From 76e58811b055a8d88e69608a2c4189b73b67b11b Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 21 Jan 2025 22:59:07 +1100 Subject: [PATCH] split rendering fixed point code on top of dlb-ivas-float-update-split-rendering --- Makefile | 25 +- Workspace_msvc/decoder.vcxproj | 1 + Workspace_msvc/encoder.vcxproj | 3 + Workspace_msvc/isar_post_rend.vcxproj | 2 + Workspace_msvc/lib_com.vcxproj | 17 +- Workspace_msvc/lib_debug.vcxproj | 1 + Workspace_msvc/lib_isar.vcxproj | 8 +- Workspace_msvc/lib_lc3plus.vcxproj | 134 +- Workspace_msvc/renderer.vcxproj | 1 + apps/decoder.c | 20 +- apps/encoder.c | 14 +- apps/isar_post_rend.c | 73 +- apps/renderer.c | 1 + lib_com/basop32.c | 709 +- lib_com/basop32.h | 68 +- lib_com/basop_mpy.c | 90 +- lib_com/basop_mpy.h | 2 + lib_com/basop_util.c | 664 +- lib_com/basop_util.h | 99 +- lib_com/cldfb.c | 1220 +- lib_com/cnst.h | 174 +- lib_com/common_api_types.h | 6 +- lib_com/complex_basop.c | 533 + lib_com/complex_basop.h | 79 + lib_com/control.c | 284 + lib_com/control.h | 365 + lib_com/count.c | 1302 ++ lib_com/count.h | 573 + lib_com/enh1632.h | 7 + lib_com/enh32.c | 231 + lib_com/enh32.h | 36 + lib_com/enh64.c | 1866 +++ lib_com/enh64.h | 85 + lib_com/enhUL32.c | 425 + lib_com/enhUL32.h | 78 + lib_com/fft_cldfb.c | 1221 ++ lib_com/float_to_fix_ops.c | 108 + lib_com/ivas_cnst.h | 3 + lib_com/ivas_limiter.c | 515 +- lib_com/ivas_prot.h | 38 +- lib_com/ivas_rotation_com.c | 125 +- lib_com/log2.c | 222 + lib_com/log2.h | 40 + lib_com/math_op.c | 24 + lib_com/math_op.h | 8 + lib_com/move.h | 7 +- lib_com/oper_32b.c | 26 + lib_com/oper_32b.h | 6 + lib_com/options.h | 10 +- lib_com/prot.h | 63 +- lib_com/prot_fx2.h | 125 + lib_com/rom_basic_math.c | 83 + lib_com/rom_basic_math.h | 26 + lib_com/rom_com.c | 457 + lib_com/rom_com.h | 58 +- lib_com/stat_com.h | 22 +- lib_com/stl.h | 22 +- lib_com/tools.c | 25 +- lib_com/tools_fx.c | 230 + lib_com/typedef.h | 10 +- lib_debug/tinywaveout_c.h | 634 + lib_debug/wmc_auto.c | 1997 ++- lib_debug/wmc_auto.h | 1279 +- lib_dec/ivas_init_dec.c | 23 + lib_dec/lib_dec.c | 206 +- lib_enc/lib_enc.c | 31 - lib_isar/isar_MSPred.c | 288 +- lib_isar/isar_NoiseGen.c | 1 + lib_isar/isar_PerceptualModel.c | 225 +- lib_isar/isar_PredDecoder.c | 296 +- lib_isar/isar_PredEncoder.c | 726 +- lib_isar/isar_RMSEnvGrouping.c | 943 +- lib_isar/isar_cnst.h | 26 +- lib_isar/isar_lc3plus_dec.c | 39 +- lib_isar/isar_lc3plus_dec.h | 7 +- lib_isar/isar_lc3plus_enc.c | 33 +- lib_isar/isar_lc3plus_enc.h | 8 +- lib_isar/isar_lcld_decoder.c | 1518 ++- lib_isar/isar_lcld_encoder.c | 1850 +-- lib_isar/isar_lcld_prot.h | 230 +- ...m_lcld_tables.c => isar_lcld_rom_tables.c} | 9520 +++++++++++++- ...m_lcld_tables.h => isar_lcld_rom_tables.h} | 86 +- lib_isar/isar_prot.h | 398 +- lib_isar/isar_rom_post_rend.c | 44 +- lib_isar/isar_rom_post_rend.h | 43 +- lib_isar/isar_splitRend_lcld_dec.c | 132 +- lib_isar/isar_splitRend_lcld_enc.c | 81 +- lib_isar/isar_splitRendererPLC.c | 1275 +- lib_isar/isar_splitRendererPost.c | 1477 ++- lib_isar/isar_splitRendererPre.c | 2717 ++-- lib_isar/isar_splitRenderer_utils.c | 1014 +- lib_isar/isar_stat.h | 80 +- lib_isar/lib_isar_post_rend.c | 774 +- lib_isar/lib_isar_post_rend.h | 62 +- lib_isar/lib_isar_pre_rend.c | 399 +- lib_isar/lib_isar_pre_rend.h | 35 +- lib_lc3plus/adjust_global_gain.c | 97 - lib_lc3plus/adjust_global_gain_fx.c | 186 + lib_lc3plus/al_fec.c | 2379 ++++ lib_lc3plus/al_fec_fl.c | 2330 ---- lib_lc3plus/apply_global_gain.c | 22 - lib_lc3plus/apply_global_gain_fx.c | 66 + lib_lc3plus/ari_codec.c | 3535 +++--- lib_lc3plus/attack_detector.c | 92 - lib_lc3plus/attack_detector_fx.c | 119 + lib_lc3plus/basop_mpy_lc3plus.c | 99 + lib_lc3plus/basop_mpy_lc3plus.h | 94 + lib_lc3plus/basop_util_lc3plus.c | 1069 ++ lib_lc3plus/basop_util_lc3plus.h | 377 + lib_lc3plus/clib.h | 29 - lib_lc3plus/constants.c | 10570 +++++++--------- lib_lc3plus/constants.h | 578 +- lib_lc3plus/cutoff_bandwidth.c | 16 +- lib_lc3plus/dct2_fx.c | 473 + lib_lc3plus/dct4.c | 95 - lib_lc3plus/dct4_fx.c | 228 + lib_lc3plus/dec_entropy.c | 497 +- lib_lc3plus/dec_lc3.c | 788 ++ lib_lc3plus/dec_lc3_fl.c | 373 - lib_lc3plus/defines.h | 884 +- lib_lc3plus/detect_cutoff_warped.c | 92 - lib_lc3plus/detect_cutoff_warped_fx.c | 124 + lib_lc3plus/dynmem.c | 288 + lib_lc3plus/dynmem.h | 80 + lib_lc3plus/enc_entropy.c | 221 +- lib_lc3plus/enc_lc3.c | 680 + lib_lc3plus/enc_lc3_fl.c | 283 - lib_lc3plus/estimate_global_gain.c | 130 - lib_lc3plus/estimate_global_gain_fx.c | 506 + lib_lc3plus/fft/cfft.c | 427 - lib_lc3plus/fft/cfft.h | 44 - lib_lc3plus/fft/fft_15_16.h | 401 - lib_lc3plus/fft/fft_240_480.h | 185 - lib_lc3plus/fft/fft_2_9.h | 278 - lib_lc3plus/fft/fft_32.h | 467 - lib_lc3plus/fft/fft_384_768.h | 103 - lib_lc3plus/fft/fft_60_128.h | 161 - lib_lc3plus/fft/fft_generic.h | 699 - lib_lc3plus/fft/iis_fft.c | 172 - lib_lc3plus/fft/iis_fft.h | 144 - lib_lc3plus/fft/iisfft.c | 175 - lib_lc3plus/fft/iisfft.h | 88 - lib_lc3plus/fft_lc3plus.c | 4537 +++++++ lib_lc3plus/functions.h | 1023 +- lib_lc3plus/imdct.c | 103 - lib_lc3plus/imdct_fx.c | 387 + lib_lc3plus/lc3.c | 358 +- lib_lc3plus/lc3.h | 257 +- lib_lc3plus/lc3plus_fft.c | 101 - lib_lc3plus/levinson_fx.c | 160 + lib_lc3plus/license.h | 9 +- lib_lc3plus/ltpf_coder.c | 268 - lib_lc3plus/ltpf_coder_fx.c | 323 + lib_lc3plus/ltpf_decoder.c | 498 - lib_lc3plus/ltpf_decoder_fx.c | 394 + lib_lc3plus/makefile | 180 + lib_lc3plus/mdct.c | 157 - lib_lc3plus/mdct_fx.c | 223 + lib_lc3plus/mdct_shaping_fx.c | 74 + lib_lc3plus/near_nyquist_detector.c | 93 - lib_lc3plus/near_nyquist_detector_fx.c | 141 + lib_lc3plus/noise_factor.c | 130 - lib_lc3plus/noise_factor_fx.c | 252 + lib_lc3plus/noise_filling.c | 107 - lib_lc3plus/noise_filling_fx.c | 149 + lib_lc3plus/olpa.c | 201 - lib_lc3plus/olpa_fx.c | 289 + lib_lc3plus/pc_apply.c | 74 - lib_lc3plus/pc_apply_fx.c | 315 + lib_lc3plus/pc_classify.c | 171 - lib_lc3plus/pc_classify_fx.c | 260 + lib_lc3plus/pc_main.c | 44 - lib_lc3plus/pc_main_fx.c | 57 + lib_lc3plus/pc_update.c | 38 - lib_lc3plus/pc_update_fx.c | 148 + lib_lc3plus/per_band_energy.c | 65 - lib_lc3plus/per_band_energy_fx.c | 275 + lib_lc3plus/plc_apply_fx.c | 419 + lib_lc3plus/plc_classify.c | 335 - lib_lc3plus/plc_classify_fx.c | 424 + lib_lc3plus/plc_compute_stab_fac.c | 65 - lib_lc3plus/plc_damping_scrambling.c | 290 - lib_lc3plus/plc_damping_scrambling_fx.c | 430 + .../{mdct_shaping.c => plc_lpc_scaling_fx.c} | 36 +- lib_lc3plus/plc_main.c | 327 - lib_lc3plus/plc_main_fx.c | 85 + lib_lc3plus/plc_noise_substitution.c | 23 - ..._com_lc3.c => plc_noise_substitution_fx.c} | 35 +- lib_lc3plus/plc_phecu_f0_refine_first.c | 76 - lib_lc3plus/plc_phecu_f0_refine_first_fx.c | 100 + lib_lc3plus/plc_phecu_fec_hq.c | 160 - lib_lc3plus/plc_phecu_fec_hq_fx.c | 3157 +++++ lib_lc3plus/plc_phecu_hq_ecu.c | 143 - lib_lc3plus/plc_phecu_lf_peak_analysis.c | 113 - lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c | 202 + lib_lc3plus/plc_phecu_peak_locator_fx.c | 385 + lib_lc3plus/plc_phecu_rec_frame.c | 153 - lib_lc3plus/plc_phecu_setf0hz_fx.c | 60 + lib_lc3plus/plc_phecu_spec_ana.c | 600 - lib_lc3plus/plc_phecu_subst_spec.c | 456 - lib_lc3plus/plc_phecu_tba_per_band_gain.c | 44 - lib_lc3plus/plc_phecu_tba_spect_Xavg.c | 46 - lib_lc3plus/plc_phecu_tba_trans_dect_gains.c | 387 - lib_lc3plus/plc_phecu_tools_fx.c | 247 + lib_lc3plus/plc_phecu_trans_burst_ana_sub.c | 60 - lib_lc3plus/plc_tdac_fx.c | 217 + lib_lc3plus/plc_tdc.c | 803 -- lib_lc3plus/plc_tdc_inverse_odft_fx.c | 130 + ...lc_phecu_setf0hz.c => plc_tdc_lagwin_fx.c} | 25 +- lib_lc3plus/plc_tdc_main_fx.c | 1257 ++ lib_lc3plus/plc_tdc_pre_emphasis_fx.c | 95 + lib_lc3plus/plc_tdc_tdac.c | 81 - lib_lc3plus/plc_update.c | 126 - lib_lc3plus/plc_update_aft_imdct_fx.c | 343 + lib_lc3plus/plc_update_fx.c | 224 + lib_lc3plus/plc_xcorr_fx.c | 250 + lib_lc3plus/pvq_dec_fx.c | 153 + lib_lc3plus/pvq_enc_fx.c | 369 + lib_lc3plus/pvq_index_fx.c | 513 + lib_lc3plus/quantize_spec.c | 283 - lib_lc3plus/quantize_spec_fx.c | 1167 ++ lib_lc3plus/reorder_bitstream.c | 42 - lib_lc3plus/reorder_bitstream_fx.c | 56 + lib_lc3plus/resamp12k8.c | 109 - lib_lc3plus/resamp12k8_fx.c | 121 + lib_lc3plus/residual_coding.c | 77 - lib_lc3plus/residual_coding_fx.c | 238 + lib_lc3plus/residual_decoding.c | 98 - lib_lc3plus/residual_decoding_fx.c | 207 + lib_lc3plus/rom_basop_util.c | 2904 +++++ lib_lc3plus/rom_basop_util.h | 172 + lib_lc3plus/scale_signal24_fx.c | 121 + lib_lc3plus/setup_dec_lc3.c | 829 +- lib_lc3plus/setup_dec_lc3.h | 258 +- lib_lc3plus/setup_enc_lc3.c | 829 +- lib_lc3plus/setup_enc_lc3.h | 211 +- lib_lc3plus/sns_compute_scf.c | 175 - lib_lc3plus/sns_compute_scf_fx.c | 166 + lib_lc3plus/sns_interpolate_scf.c | 92 - lib_lc3plus/sns_interpolate_scf_fx.c | 154 + lib_lc3plus/sns_quantize_scf.c | 523 - lib_lc3plus/sns_quantize_scf_fx.c | 834 ++ lib_lc3plus/structs.h | 208 - lib_lc3plus/tinywavein_c.h | 603 + lib_lc3plus/tinywaveout_c.h | 889 ++ lib_lc3plus/tns_coder.c | 393 - lib_lc3plus/tns_coder_fx.c | 378 + lib_lc3plus/tns_decoder.c | 55 - lib_lc3plus/tns_decoder_fx.c | 150 + lib_lc3plus/util.h | 256 - lib_rend/ivas_stat_rend.h | 11 + lib_rend/lib_rend.c | 141 +- lib_util/rotation_file_reader.c | 40 + lib_util/rotation_file_reader.h | 5 + 254 files changed, 78922 insertions(+), 31089 deletions(-) create mode 100644 lib_com/complex_basop.c create mode 100644 lib_com/complex_basop.h create mode 100644 lib_com/control.c create mode 100644 lib_com/control.h create mode 100644 lib_com/count.c create mode 100644 lib_com/count.h create mode 100644 lib_com/enh32.c create mode 100644 lib_com/enh32.h create mode 100644 lib_com/enh64.c create mode 100644 lib_com/enh64.h create mode 100644 lib_com/enhUL32.c create mode 100644 lib_com/enhUL32.h create mode 100644 lib_com/float_to_fix_ops.c create mode 100644 lib_com/log2.c create mode 100644 lib_com/log2.h create mode 100644 lib_com/math_op.c create mode 100644 lib_com/math_op.h create mode 100644 lib_com/oper_32b.c create mode 100644 lib_com/oper_32b.h create mode 100644 lib_com/prot_fx2.h create mode 100644 lib_com/rom_basic_math.c create mode 100644 lib_com/rom_basic_math.h create mode 100644 lib_com/tools_fx.c create mode 100644 lib_debug/tinywaveout_c.h rename lib_isar/{isar_rom_lcld_tables.c => isar_lcld_rom_tables.c} (80%) rename lib_isar/{isar_rom_lcld_tables.h => isar_lcld_rom_tables.h} (73%) delete mode 100644 lib_lc3plus/adjust_global_gain.c create mode 100644 lib_lc3plus/adjust_global_gain_fx.c create mode 100644 lib_lc3plus/al_fec.c delete mode 100644 lib_lc3plus/al_fec_fl.c delete mode 100644 lib_lc3plus/apply_global_gain.c create mode 100644 lib_lc3plus/apply_global_gain_fx.c delete mode 100644 lib_lc3plus/attack_detector.c create mode 100644 lib_lc3plus/attack_detector_fx.c create mode 100644 lib_lc3plus/basop_mpy_lc3plus.c create mode 100644 lib_lc3plus/basop_mpy_lc3plus.h create mode 100644 lib_lc3plus/basop_util_lc3plus.c create mode 100644 lib_lc3plus/basop_util_lc3plus.h delete mode 100644 lib_lc3plus/clib.h create mode 100644 lib_lc3plus/dct2_fx.c delete mode 100644 lib_lc3plus/dct4.c create mode 100644 lib_lc3plus/dct4_fx.c create mode 100644 lib_lc3plus/dec_lc3.c delete mode 100644 lib_lc3plus/dec_lc3_fl.c delete mode 100644 lib_lc3plus/detect_cutoff_warped.c create mode 100644 lib_lc3plus/detect_cutoff_warped_fx.c create mode 100644 lib_lc3plus/dynmem.c create mode 100644 lib_lc3plus/dynmem.h create mode 100644 lib_lc3plus/enc_lc3.c delete mode 100644 lib_lc3plus/enc_lc3_fl.c delete mode 100644 lib_lc3plus/estimate_global_gain.c create mode 100644 lib_lc3plus/estimate_global_gain_fx.c delete mode 100644 lib_lc3plus/fft/cfft.c delete mode 100644 lib_lc3plus/fft/cfft.h delete mode 100644 lib_lc3plus/fft/fft_15_16.h delete mode 100644 lib_lc3plus/fft/fft_240_480.h delete mode 100644 lib_lc3plus/fft/fft_2_9.h delete mode 100644 lib_lc3plus/fft/fft_32.h delete mode 100644 lib_lc3plus/fft/fft_384_768.h delete mode 100644 lib_lc3plus/fft/fft_60_128.h delete mode 100644 lib_lc3plus/fft/fft_generic.h delete mode 100644 lib_lc3plus/fft/iis_fft.c delete mode 100644 lib_lc3plus/fft/iis_fft.h delete mode 100644 lib_lc3plus/fft/iisfft.c delete mode 100644 lib_lc3plus/fft/iisfft.h create mode 100644 lib_lc3plus/fft_lc3plus.c delete mode 100644 lib_lc3plus/imdct.c create mode 100644 lib_lc3plus/imdct_fx.c delete mode 100644 lib_lc3plus/lc3plus_fft.c create mode 100644 lib_lc3plus/levinson_fx.c delete mode 100644 lib_lc3plus/ltpf_coder.c create mode 100644 lib_lc3plus/ltpf_coder_fx.c delete mode 100644 lib_lc3plus/ltpf_decoder.c create mode 100644 lib_lc3plus/ltpf_decoder_fx.c create mode 100644 lib_lc3plus/makefile delete mode 100644 lib_lc3plus/mdct.c create mode 100644 lib_lc3plus/mdct_fx.c create mode 100644 lib_lc3plus/mdct_shaping_fx.c delete mode 100644 lib_lc3plus/near_nyquist_detector.c create mode 100644 lib_lc3plus/near_nyquist_detector_fx.c delete mode 100644 lib_lc3plus/noise_factor.c create mode 100644 lib_lc3plus/noise_factor_fx.c delete mode 100644 lib_lc3plus/noise_filling.c create mode 100644 lib_lc3plus/noise_filling_fx.c delete mode 100644 lib_lc3plus/olpa.c create mode 100644 lib_lc3plus/olpa_fx.c delete mode 100644 lib_lc3plus/pc_apply.c create mode 100644 lib_lc3plus/pc_apply_fx.c delete mode 100644 lib_lc3plus/pc_classify.c create mode 100644 lib_lc3plus/pc_classify_fx.c delete mode 100644 lib_lc3plus/pc_main.c create mode 100644 lib_lc3plus/pc_main_fx.c delete mode 100644 lib_lc3plus/pc_update.c create mode 100644 lib_lc3plus/pc_update_fx.c delete mode 100644 lib_lc3plus/per_band_energy.c create mode 100644 lib_lc3plus/per_band_energy_fx.c create mode 100644 lib_lc3plus/plc_apply_fx.c delete mode 100644 lib_lc3plus/plc_classify.c create mode 100644 lib_lc3plus/plc_classify_fx.c delete mode 100644 lib_lc3plus/plc_compute_stab_fac.c delete mode 100644 lib_lc3plus/plc_damping_scrambling.c create mode 100644 lib_lc3plus/plc_damping_scrambling_fx.c rename lib_lc3plus/{mdct_shaping.c => plc_lpc_scaling_fx.c} (52%) delete mode 100644 lib_lc3plus/plc_main.c create mode 100644 lib_lc3plus/plc_main_fx.c delete mode 100644 lib_lc3plus/plc_noise_substitution.c rename lib_lc3plus/{setup_com_lc3.c => plc_noise_substitution_fx.c} (54%) delete mode 100644 lib_lc3plus/plc_phecu_f0_refine_first.c create mode 100644 lib_lc3plus/plc_phecu_f0_refine_first_fx.c delete mode 100644 lib_lc3plus/plc_phecu_fec_hq.c create mode 100644 lib_lc3plus/plc_phecu_fec_hq_fx.c delete mode 100644 lib_lc3plus/plc_phecu_hq_ecu.c delete mode 100644 lib_lc3plus/plc_phecu_lf_peak_analysis.c create mode 100644 lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c create mode 100644 lib_lc3plus/plc_phecu_peak_locator_fx.c delete mode 100644 lib_lc3plus/plc_phecu_rec_frame.c create mode 100644 lib_lc3plus/plc_phecu_setf0hz_fx.c delete mode 100644 lib_lc3plus/plc_phecu_spec_ana.c delete mode 100644 lib_lc3plus/plc_phecu_subst_spec.c delete mode 100644 lib_lc3plus/plc_phecu_tba_per_band_gain.c delete mode 100644 lib_lc3plus/plc_phecu_tba_spect_Xavg.c delete mode 100644 lib_lc3plus/plc_phecu_tba_trans_dect_gains.c create mode 100644 lib_lc3plus/plc_phecu_tools_fx.c delete mode 100644 lib_lc3plus/plc_phecu_trans_burst_ana_sub.c create mode 100644 lib_lc3plus/plc_tdac_fx.c delete mode 100644 lib_lc3plus/plc_tdc.c create mode 100644 lib_lc3plus/plc_tdc_inverse_odft_fx.c rename lib_lc3plus/{plc_phecu_setf0hz.c => plc_tdc_lagwin_fx.c} (60%) create mode 100644 lib_lc3plus/plc_tdc_main_fx.c create mode 100644 lib_lc3plus/plc_tdc_pre_emphasis_fx.c delete mode 100644 lib_lc3plus/plc_tdc_tdac.c delete mode 100644 lib_lc3plus/plc_update.c create mode 100644 lib_lc3plus/plc_update_aft_imdct_fx.c create mode 100644 lib_lc3plus/plc_update_fx.c create mode 100644 lib_lc3plus/plc_xcorr_fx.c create mode 100644 lib_lc3plus/pvq_dec_fx.c create mode 100644 lib_lc3plus/pvq_enc_fx.c create mode 100644 lib_lc3plus/pvq_index_fx.c delete mode 100644 lib_lc3plus/quantize_spec.c create mode 100644 lib_lc3plus/quantize_spec_fx.c delete mode 100644 lib_lc3plus/reorder_bitstream.c create mode 100644 lib_lc3plus/reorder_bitstream_fx.c delete mode 100644 lib_lc3plus/resamp12k8.c create mode 100644 lib_lc3plus/resamp12k8_fx.c delete mode 100644 lib_lc3plus/residual_coding.c create mode 100644 lib_lc3plus/residual_coding_fx.c delete mode 100644 lib_lc3plus/residual_decoding.c create mode 100644 lib_lc3plus/residual_decoding_fx.c create mode 100644 lib_lc3plus/rom_basop_util.c create mode 100644 lib_lc3plus/rom_basop_util.h create mode 100644 lib_lc3plus/scale_signal24_fx.c delete mode 100644 lib_lc3plus/sns_compute_scf.c create mode 100644 lib_lc3plus/sns_compute_scf_fx.c delete mode 100644 lib_lc3plus/sns_interpolate_scf.c create mode 100644 lib_lc3plus/sns_interpolate_scf_fx.c delete mode 100644 lib_lc3plus/sns_quantize_scf.c create mode 100644 lib_lc3plus/sns_quantize_scf_fx.c delete mode 100644 lib_lc3plus/structs.h create mode 100644 lib_lc3plus/tinywavein_c.h create mode 100644 lib_lc3plus/tinywaveout_c.h delete mode 100644 lib_lc3plus/tns_coder.c create mode 100644 lib_lc3plus/tns_coder_fx.c delete mode 100644 lib_lc3plus/tns_decoder.c create mode 100644 lib_lc3plus/tns_decoder_fx.c delete mode 100644 lib_lc3plus/util.h diff --git a/Makefile b/Makefile index 63ac29842..fc923e3a7 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,8 @@ SRC_APP = apps BUILD = build OBJDIR = obj +INCLUDE_SPLIT = 1 + SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBISAR) $(SRC_LC3PLUS) $(SRC_LIBUTIL) $(SRC_APP)) # Name of CLI binaries @@ -130,7 +132,7 @@ SRCS_SPLIT_REND = ivas_CQMFDecoder.c ivas_CQMFEncoder.c ivas_PerceptualModel.c i ivas_splitRenderer_utils.c split_rend_bfi_file_reader.c split_render_file_read_write.c \ ivas_lcld_tables.c - + ############################################################################### SRCS_LIBCOM = $(foreach DIR,$(SRC_LIBCOM),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) @@ -140,7 +142,12 @@ SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBREND = $(foreach DIR,$(SRC_LIBREND),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBISAR = $(foreach DIR,$(SRC_LIBISAR),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) +ifeq "$(INCLUDE_SPLIT)" "1" SRCS_LC3PLUS = $(foreach DIR,$(SRC_LC3PLUS),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) +else +# SRCS_LIBREND := $(filter-out $(SRCS_SPLIT_REND),$(SRCS_LIBREND)) +# SRCS_LIBUTIL := $(filter-out $(SRCS_SPLIT_REND),$(SRCS_LIBUTIL)) +endif OBJS_LIBCOM = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.o)) OBJS_LIBDEBUG = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEBUG:.c=.o)) @@ -187,7 +194,11 @@ $(LIB_LIBREND): $(OBJS_LIBREND) $(OBJS_LIBISAR) $(QUIET_AR)$(AR) rcs $@ $^ $(LIB_LC3PLUS): $(OBJS_LC3PLUS) +ifeq "$(INCLUDE_SPLIT)" "1" $(QUIET_AR)$(AR) rcs $@ $^ +else + +endif $(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(QUIET_AR)$(AR) rcs $@ $^ @@ -196,13 +207,23 @@ $(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(L $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIENC) -L. -livasenc -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIENC) $(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(LIB_LIBISAR) +ifeq "$(INCLUDE_SPLIT)" "1" $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug -llc3plus $(LDLIBS) -o $(CLI_APIDEC) +else + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC) +endif $(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) $(LIB_LC3PLUS) $(LIB_LIBISAR) +ifeq "$(INCLUDE_SPLIT)" "1" $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -lisar -livasdec -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIREND) +else + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasdec -livasutil -livasdebug -livascom $(LDLIBS) -o $(CLI_APIREND) +endif $(CLI_APIPOSTREND): $(OBJS_CLI_APPPOSTREND) $(LIB_LIBISAR) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPPOSTREND) -L. -lisar -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIPOSTREND) +ifeq "$(INCLUDE_SPLIT)" "1" + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPPOSTREND) -L. -lisar -livasutil -livasdebug -llc3plus -livascom $(LDLIBS) -o $(CLI_APIPOSTREND) +endif libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBISAR) $(LIB_LC3PLUS) $(LIB_LIBUTIL) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index 648f01e82..c1662f613 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -149,6 +149,7 @@ + diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 9578e488d..149c3abb4 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -167,6 +167,9 @@ false + + + diff --git a/Workspace_msvc/isar_post_rend.vcxproj b/Workspace_msvc/isar_post_rend.vcxproj index 170ff2054..19cb1aff7 100644 --- a/Workspace_msvc/isar_post_rend.vcxproj +++ b/Workspace_msvc/isar_post_rend.vcxproj @@ -148,6 +148,8 @@ + + diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 9eb1af512..42c519221 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -60,7 +60,7 @@ Disabled ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions); EnableFastChecks MultiThreadedDebug @@ -140,14 +140,20 @@ + + + + + + @@ -161,6 +167,7 @@ + @@ -266,6 +273,7 @@ + @@ -284,8 +292,14 @@ + + + + + + @@ -295,6 +309,7 @@ + diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index 396078790..3866c19a9 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -108,6 +108,7 @@ + diff --git a/Workspace_msvc/lib_isar.vcxproj b/Workspace_msvc/lib_isar.vcxproj index fceeb731c..c663ef5e7 100644 --- a/Workspace_msvc/lib_isar.vcxproj +++ b/Workspace_msvc/lib_isar.vcxproj @@ -138,9 +138,10 @@ + - + @@ -162,11 +163,12 @@ + - + @@ -197,4 +199,4 @@ - + \ No newline at end of file diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj index eb2a91d36..294677fff 100644 --- a/Workspace_msvc/lib_lc3plus.vcxproj +++ b/Workspace_msvc/lib_lc3plus.vcxproj @@ -65,13 +65,14 @@ Level3 - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_com;%(AdditionalIncludeDirectories) Disabled MultiThreadedDebug WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 4305;4244;4996 OldStyle false + false Console @@ -83,13 +84,14 @@ Level3 - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_com;%(AdditionalIncludeDirectories) MaxSpeed MultiThreaded true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 4244;4305;4996 + false Console @@ -99,83 +101,93 @@ - - - + + + - - + + + - + + - - + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + - + + - + + + - - diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 324c71373..e6a711491 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -146,6 +146,7 @@ + diff --git a/apps/decoder.c b/apps/decoder.c index 00a928685..ee8c568f4 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -55,6 +55,7 @@ #include "debug.h" #endif #include "wmc_auto.h" +#include "stl.h" #define WMC_TOOL_SKIP @@ -63,7 +64,7 @@ * Local constants *------------------------------------------------------------------------------------------*/ -#if !defined( DEBUGGING ) && !defined( WMOPS ) +#if !defined( WMOPS ) static #endif int32_t frame = 0; /* Counter of frames */ @@ -212,9 +213,14 @@ int main( reset_wmops(); reset_mem( USE_BYTES ); #endif +#if ( WMOPS ) +#ifndef DONT_COUNT + BASOP_init +#endif +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT - splitRendBits.bits_buf = splitRendBitsBuf; + splitRendBits.bits_buf = splitRendBitsBuf; #endif /*------------------------------------------------------------------------------------------* @@ -2097,7 +2103,7 @@ static ivas_error decodeG192( #endif #endif IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; - IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }; int16_t vec_pos_update, vec_pos_len; #ifdef SPLIT_REND_WITH_HEAD_ROT SplitFileReadWrite *splitRendWriter = NULL; @@ -2924,7 +2930,7 @@ static ivas_error decodeVoIP( IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; - IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }; int16_t vec_pos_update, vec_pos_len; int16_t nOutSamples = 0; @@ -3355,6 +3361,12 @@ static ivas_error decodeVoIP( frame++; systemTime_ms += systemTimeInc_ms; +#ifdef WMOPS +#ifndef DONT_COUNT + /* update WMPOS counting (end of frame) */ + BASOP_frame_update(); +#endif +#endif #ifdef WMOPS update_mem(); update_wmops(); diff --git a/apps/encoder.c b/apps/encoder.c index 21aa5d0b1..38f9f36af 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -42,7 +42,7 @@ #include "debug.h" #endif #include "wmc_auto.h" - +#include "stl.h" #define WMC_TOOL_SKIP @@ -203,9 +203,14 @@ int main( #ifdef WMOPS reset_wmops(); reset_mem( USE_BYTES ); +#endif +#if ( WMOPS ) +#ifndef DONT_COUNT + BASOP_init +#endif #endif - initArgStruct( &arg ); + initArgStruct( &arg ); /*------------------------------------------------------------------------------------------* * Parse command-line arguments @@ -777,8 +782,11 @@ int main( } #ifdef WMOPS - update_mem(); update_wmops(); + update_mem(); +#ifdef MEM_COUNT_DETAILS + export_mem( "mem_analysis.csv" ); +#endif #endif } diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c index 7f5af86ff..9a8d7c3ba 100644 --- a/apps/isar_post_rend.c +++ b/apps/isar_post_rend.c @@ -31,6 +31,7 @@ *******************************************************************************************************/ #include "lib_isar_post_rend.h" +//#undef IVAS_FLOAT_FIXED #ifndef SPLIT_REND_WITH_HEAD_ROT @@ -58,6 +59,7 @@ int main( int argc, char **argv ) #ifdef DEBUGGING #include "debug.h" #endif +#include "stl.h" #include "wmc_auto.h" @@ -71,6 +73,8 @@ int main( int argc, char **argv ) #define ISAR_MAX16B_FLT 32767.0f #define ISAR_MIN16B_FLT ( -32768.0f ) +#define ISAR_MAX16B_FX 32767 +#define ISAR_MIN16B_FX ( -32768 ) #if !defined( DEBUGGING ) && !defined( WMOPS ) static @@ -227,7 +231,7 @@ static void printSupportedAudioConfigs( void ); static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); -static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); +static void convertOutputBuffer( const Word32 *fixedBuffer, Word16 q, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); /*------------------------------------------------------------------------------------------* * Local functions @@ -242,7 +246,7 @@ static ISAR_POST_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( subBuffer.config = buffer.config; subBuffer.config.numChannels = numChannels; - subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx; + subBuffer.data_fx = buffer.data_fx + subBuffer.config.numSamplesPerChannel * chBeginIdx; return subBuffer; } @@ -612,23 +616,23 @@ static void convertInputBuffer( const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, - float *floatBuffer ) + Word32 *fixedBuffer ) { int16_t chnl, smpl, i; i = 0; - for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + FOR( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) { - for ( chnl = 0; chnl < numChannels; ++chnl ) + FOR( chnl = 0; chnl < numChannels; ++chnl ) { - if ( i < numIntSamplesPerChannel ) + IF( i < numIntSamplesPerChannel ) { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; + fixedBuffer[chnl * numFloatSamplesPerChannel + smpl] = (Word32) intBuffer[i]; } - else + ELSE { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + fixedBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0; } ++i; @@ -646,13 +650,14 @@ static void convertInputBuffer( *--------------------------------------------------------------------------*/ static void convertOutputBuffer( - const float *floatBuffer, + const Word32 *fixedBuffer, + Word16 q, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ) { int16_t chnl, smpl, i; - float temp; + Word32 temp; i = 0; @@ -660,15 +665,14 @@ static void convertOutputBuffer( { for ( chnl = 0; chnl < numChannels; ++chnl ) { - temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; - temp = (float) floor( temp + 0.5f ); - if ( temp > ISAR_MAX16B_FLT ) + temp = L_shr_r( fixedBuffer[chnl * numSamplesPerChannel + smpl], q ); + IF( GT_32( temp, ISAR_MAX16B_FX ) ) { - temp = ISAR_MAX16B_FLT; + temp = ISAR_MAX16B_FX; } - else if ( temp < ISAR_MIN16B_FLT ) + ELSE IF( LT_32( temp, ISAR_MIN16B_FX ) ) { - temp = ISAR_MIN16B_FLT; + temp = ISAR_MIN16B_FX; } intBuffer[i] = (int16_t) temp; @@ -699,9 +703,9 @@ int main( int32_t outBufferSize; int32_t bitsBufferSize; int16_t *inpInt16Buffer; - float *inFloatBuffer; + Word32 *inFloatBuffer_fx; int16_t *outInt16Buffer; - float *outFloatBuffer; + Word32 *outFloatBuffer_fx; uint8_t *bitsBufferData = NULL; IVAS_REND_AudioBuffer inBuffer; IVAS_REND_AudioBuffer outBuffer; @@ -869,7 +873,7 @@ int main( } const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_BINAURAL; - if ( ( error = ISAR_POST_REND_open( &hIsarPostRend, args.sampleRate, args.outConfig.audioConfig, true, 0, 0.0, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) + if ( ( error = ISAR_POST_REND_open( &hIsarPostRend, args.sampleRate, args.outConfig.audioConfig, true, 0, 0, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -936,23 +940,26 @@ int main( inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); + memset( inpInt16Buffer, 0, inBufferSize * sizeof( int16_t ) ); - inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + inFloatBuffer_fx = malloc( inBufferSize * sizeof( Word32 ) ); inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; - outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + outFloatBuffer_fx = malloc( outBufferSize * sizeof( Word32 ) ); outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); inBuffer.config.is_cldfb = 0; inBuffer.config.numChannels = (int16_t) totalNumInChannels; - inBuffer.data = inFloatBuffer; + inBuffer.data_fx = inFloatBuffer_fx; + inBuffer.q_data_fx = malloc( sizeof( Word16 ) ); outBuffer.config.is_cldfb = 0; outBuffer.config.numChannels = (int16_t) numOutChannels; - outBuffer.data = outFloatBuffer; + outBuffer.data_fx = outFloatBuffer_fx; + outBuffer.q_data_fx = malloc( sizeof( Word16 ) ); - memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) ); + memset( outBuffer.data_fx, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( Word32 ) ); bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; @@ -1027,8 +1034,8 @@ int main( } /* Convert from int to float and from interleaved to packed */ - convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer ); - + convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer_fx ); + *inBuffer.q_data_fx = 0; int16_t num_subframes, sf_idx; num_subframes = (int16_t) args.render_framesize; @@ -1040,7 +1047,7 @@ int main( IVAS_QUATERNION headRot; IVAS_VECTOR3 Pos; - if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) + IF( ( error = HeadRotationFileReading_fx( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1114,7 +1121,7 @@ int main( /* Convert from float to int and from packed to interleaved. * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ - convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer ); + convertOutputBuffer( outFloatBuffer_fx, *outBuffer.q_data_fx, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer ); if ( delayNumSamples == -1 ) { @@ -1130,7 +1137,7 @@ int main( { uint32_t pre_rend_delay_ns; split_rend_read_pre_rend_delay_ns( hSplitRendFileReadWrite, &pre_rend_delay_ns ); - delayNumSamples += (int16_t) roundf( (float) pre_rend_delay_ns * delayTimeScale / 1000000000.f ); + delayNumSamples += (Word16) ( ( ( (Word64) pre_rend_delay_ns * delayTimeScale ) + 500000000 ) / 1000000000 ); } delayNumSamples_orig = delayNumSamples; @@ -1217,9 +1224,11 @@ int main( /* === Close === */ free( inpInt16Buffer ); - free( inFloatBuffer ); + free( inFloatBuffer_fx ); + free( inBuffer.q_data_fx ); free( outInt16Buffer ); - free( outFloatBuffer ); + free( outFloatBuffer_fx ); + free( outBuffer.q_data_fx ); if ( bitsBufferData != NULL ) { diff --git a/apps/renderer.c b/apps/renderer.c index 362a5b423..1e97b77b9 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -54,6 +54,7 @@ #include "debug.h" #endif #include "wmc_auto.h" +#include "stl.h" #define WMC_TOOL_SKIP diff --git a/lib_com/basop32.c b/lib_com/basop32.c index a407ff72d..2f1d67d0e 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -170,6 +170,11 @@ HISTORY: #pragma warning( disable : 4310 ) #endif +#if ( WMOPS ) +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif + /*___________________________________________________________________________ | | | Local Functions | @@ -186,15 +191,236 @@ static Word16 saturate( Word32 L_var1 ); | Constants and Globals | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB +#ifdef BASOP_NOGLOB + +#ifdef BASOP_PRINT_ON_WARNING +#include +#if defined( __unix__ ) || defined( __unix ) || defined( __APPLE__ ) +#include +/* Using macro instead of function here to avoid pushing new frames onto the stack */ +#define PRINT_STACK() \ + do \ + { \ + void *call_stack[200]; \ + int i; \ + int num_frames; \ + char **strings; \ + \ + num_frames = backtrace( call_stack, 200 ); \ + strings = backtrace_symbols( call_stack, num_frames ); \ + for ( i = 0; i < num_frames; ++i ) \ + { \ + printf( "[BASOP] %s\n", strings[i] ); \ + } \ + free( strings ); \ + } while ( 0 ) +#elif defined _WIN32 || defined _WIN64 +#include +#include +#pragma comment( lib, "Dbghelp.lib" ) + +/* Using macro instead of function here to avoid pushing new frames onto the stack */ +#define PRINT_STACK() \ + do \ + { \ + void *call_stack[200]; \ + int i; \ + int num_frames; \ + DWORD64 offset; \ + SYMBOL_INFO *symbol; \ + IMAGEHLP_MODULE module; \ + HANDLE process; \ + \ + process = GetCurrentProcess(); \ + SymInitialize( process, NULL, TRUE ); \ + symbol = \ + (SYMBOL_INFO *) calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 ); \ + symbol->MaxNameLen = 255; \ + symbol->SizeOfStruct = sizeof( SYMBOL_INFO ); \ + module.SizeOfStruct = sizeof( IMAGEHLP_MODULE64 ); \ + \ + IMAGEHLP_LINE *line_info = \ + (IMAGEHLP_LINE *) calloc( sizeof( IMAGEHLP_LINE ), 1 ); \ + line_info->SizeOfStruct = sizeof( IMAGEHLP_LINE ); \ + \ + num_frames = CaptureStackBackTrace( 0, 200, call_stack, NULL ); \ + for ( i = 0; i < num_frames; ++i ) \ + { \ + DWORD dwLineDisplacement; \ + SymFromAddr( process, (DWORD64) ( call_stack[i] ), &offset, symbol ); \ + SymGetModuleInfo( process, (DWORD) symbol->ModBase, &module ); \ + if ( SymGetLineFromAddr( process, (DWORD64) ( call_stack[i] ), \ + &dwLineDisplacement, line_info ) ) \ + { \ + printf( "[BASOP] %i\t%s(%s+0x%llX) [0x%llX] %s:%d\n", i, \ + module.ModuleName, symbol->Name, offset, symbol->Address, \ + line_info->FileName, line_info->LineNumber ); \ + } \ + else \ + { \ + printf( "[BASOP] %i\t%s(%s+0x%llX) [0x%llX]\n", i, module.ModuleName, \ + symbol->Name, offset, symbol->Address ); \ + } \ + } \ + free( line_info ); \ + free( symbol ); \ + } while ( 0 ) +#else +#define PRINT_STACK() \ + do \ + { \ + printf( "[BASOP] - printing call stack is not " \ + "supported on this platform\n" ); \ + } while ( 0 ) +#endif + +/* Using macro instead of function here to avoid pushing new frames onto the stack */ +#define PRINT_BASOP_NOGLOB_WARNING() \ + do \ + { \ + printf( "[BASOP] Overflow occured. Call stack:\n" ); \ + PRINT_STACK(); \ + } while ( 0 ) + +/* Using macro instead of function here to avoid pushing new frames onto the stack */ +#define PRINT_BASOP_NOGLOB_ERROR() \ + do \ + { \ + printf( "[BASOP] Overflow error occured. Call stack:\n" ); \ + PRINT_STACK(); \ + } while ( 0 ) +#endif /* BASOP_PRINT_ON_WARNING */ + +#if defined BASOP_PRINT_ON_WARNING || defined BASOP_ABORT_ON_WARNING +int BASOP_saturation_warning_enable = 1, BASOP_saturation_warning_disable_counter = 0; +int BASOP_warnings_as_errors = 0; +#endif + +#ifdef BASOP_PRINT_ON_WARNING +#define B_HELPER_PRINT_WARNING() \ + do \ + { \ + if ( BASOP_saturation_warning_enable ) \ + { \ + if ( BASOP_warnings_as_errors ) \ + { \ + PRINT_BASOP_NOGLOB_ERROR(); \ + } \ + else \ + { \ + PRINT_BASOP_NOGLOB_WARNING(); \ + } \ + } \ + } while ( 0 ) +#else +#define B_HELPER_PRINT_WARNING() \ + do \ + { \ + (void) 0; \ + } while ( 0 ) /* no-op */ +#endif + +#ifdef BASOP_ABORT_ON_WARNING +#define B_HELPER_ABORT() \ + do \ + { \ + if ( BASOP_saturation_warning_enable ) \ + { \ + assert( 0 ); \ + } \ + } while ( 0 ) +#else +#define B_HELPER_ABORT() \ + do \ + { \ + (void) 0; \ + } while ( 0 ) /* no-op */ +#endif + +#ifdef BASOP_NOGLOB_DEV_USE_GLOBALS Flag Overflow = 0; Flag Carry = 0; +#define B_HELPER_SET_GLOBAL( global_flag, value ) \ + do \ + { \ + ( global_flag ) = ( value ); \ + } while ( 0 ) +#define B_HELPER_GET_GLOBAL( global_flag ) ( global_flag ) +#else +#define B_HELPER_SET_GLOBAL( global_flag, value ) \ + do \ + { \ + (void) 0; \ + } while ( 0 ) /* no-op */ +#define B_HELPER_GET_GLOBAL( global_flag ) 0 /* Default to 0 */ +#endif + +void set_overflow( Flag *overflow ) +{ + if ( overflow ) + *overflow = 1; + else + { + B_HELPER_PRINT_WARNING(); + B_HELPER_ABORT(); + B_HELPER_SET_GLOBAL( Overflow, 1 ); + } +} +void unset_overflow( Flag *overflow ) +{ + if ( overflow ) + *overflow = 0; + else + { + B_HELPER_PRINT_WARNING(); + B_HELPER_ABORT(); + B_HELPER_SET_GLOBAL( Overflow, 0 ); + } +} +void set_carry( Flag *carry ) +{ + if ( carry ) + *carry = 1; + else + { + B_HELPER_PRINT_WARNING(); + B_HELPER_ABORT(); + B_HELPER_SET_GLOBAL( Carry, 1 ); + } +} +void unset_carry( Flag *carry ) +{ + if ( carry ) + *carry = 0; + else + { + B_HELPER_PRINT_WARNING(); + B_HELPER_ABORT(); + B_HELPER_SET_GLOBAL( Carry, 0 ); + } +} +Flag get_carry( const Flag *carry ) +{ + if ( carry ) + return *carry; + else + { + B_HELPER_PRINT_WARNING(); + B_HELPER_ABORT(); + } + return B_HELPER_GET_GLOBAL( Carry ); +} + +/* Undef helper macros - these should only be used in functions above */ +#undef B_HELPER_PRINT_WARNING +#undef B_HELPER_ABORT +#undef B_HELPER_SET_GLOBAL +#undef B_HELPER_GET_GLOBAL + #else /* BASOP_NOGLOB */ -/* -Flag BASOP_Overflow = 0; -Flag BASOP_Carry = 0; -*/ +Flag Overflow = 0; +Flag Carry = 0; #endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -362,8 +588,13 @@ Word16 add( Word16 var1, Word16 var2 ) #endif return ( var_out ); } - - +#ifdef BASOP_NOGLOB +Word16 add_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return add_o( var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : sub | @@ -426,8 +657,13 @@ Word16 sub( Word16 var1, Word16 var2 ) #endif return ( var_out ); } - - +#ifdef BASOP_NOGLOB +Word16 sub_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return sub_o( var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : abs_s | @@ -616,6 +852,12 @@ Word16 shl( Word16 var1, Word16 var2 ) return ( var_out ); } + +Word16 shl_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return shl_o( var1, var2, &Overflow ); +} #endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -652,21 +894,27 @@ Word16 shl( Word16 var1, Word16 var2 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB +Word16 shr_o( Word16 var1, Word16 var2, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ Word16 shr( Word16 var1, Word16 var2 ) { +#endif /* BASOP_NOGLOB */ Word16 var_out; if ( var2 < 0 ) { -#ifdef BASOP_NOGLOB - assert( 0 ); -#endif /* BASOP_NOGLOB */ if ( var2 < -16 ) var2 = -16; var2 = -var2; +#ifdef BASOP_NOGLOB + var_out = shl_o( var1, var2, Overflow ); +#else /* BASOP_NOGLOB */ var_out = shl( var1, var2 ); +#endif /* BASOP_NOGLOB */ -#ifdef WMOPS +#if ( WMOPS ) multiCounter[currCounter].shl--; #endif } @@ -695,10 +943,21 @@ Word16 shr( Word16 var1, Word16 var2 ) BASOP_CHECK(); - return ( var_out ); } +#ifdef BASOP_NOGLOB +Word16 shr( Word16 var1, Word16 var2 ) +{ + return shr_o( var1, var2, NULL ); +} +Word16 shr_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return shr_o( var1, var2, &Overflow ); +} +#endif /* BASOP_NOGLOB */ + /*___________________________________________________________________________ | | @@ -737,6 +996,10 @@ Word16 shr( Word16 var1, Word16 var2 ) #ifdef BASOP_NOGLOB Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow ) { +#else /* BASOP_NOGLOB */ +Word16 mult( Word16 var1, Word16 var2 ) +{ +#endif /* BASOP_NOGLOB */ Word16 var_out; Word32 L_product; @@ -747,16 +1010,20 @@ Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow ) if ( L_product & (Word32) 0x00010000L ) L_product = L_product | (Word32) 0xffff0000L; +#ifdef BASOP_NOGLOB var_out = saturate_o( L_product, Overflow ); +#else /* BASOP_NOGLOB */ + var_out = saturate( L_product ); +#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].mult++; #endif + BASOP_CHECK(); return ( var_out ); } - -#endif /* BASOP_NOGLOB */ +#ifdef BASOP_NOGLOB Word16 mult( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -777,6 +1044,13 @@ Word16 mult( Word16 var1, Word16 var2 ) return ( var_out ); } +Word16 mult_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return mult_o( var1, var2, &Overflow ); +} + +#endif /*___________________________________________________________________________ | | @@ -870,6 +1144,12 @@ Word32 L_mult( Word16 var1, Word16 var2 ) return ( L_var_out ); } + +Word32 L_mult_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return L_mult_o( var1, var2, &Overflow ); +} #endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -1078,8 +1358,13 @@ Word16 round_fx( Word32 L_var1 ) return ( var_out ); } - - +#ifdef BASOP_NOGLOB +Word16 round_fx_sat( Word32 L_var1 ) +{ + Flag Overflow; + return round_fx_o( L_var1, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_mac | @@ -1152,8 +1437,13 @@ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ) return ( L_var_out ); } - - +#ifdef BASOP_NOGLOB +Word32 L_mac_sat( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return L_mac_o( L_var3, var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_msu | @@ -1226,8 +1516,13 @@ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ) return ( L_var_out ); } - - +#ifdef BASOP_NOGLOB +Word32 L_msu_sat( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return L_msu_o( L_var3, var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_macNs | @@ -1274,20 +1569,13 @@ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ) | operators which take into account its value. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ) -#else /* BASOP_NOGLOB */ +#ifdef BASOP_NOGLOB Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; L_var_out = L_mult( var1, var2 ); -#ifndef BASOP_NOGLOB - L_var_out = L_add_c( L_var3, L_var_out ); -#else /* BASOP_NOGLOB */ L_var_out = DEPR_L_add_c( L_var3, L_var_out, Carry ); -#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].L_mult--; @@ -1296,12 +1584,38 @@ Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) #endif /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */ - - return ( L_var_out ); } +#endif +#ifdef BASOP_NOGLOB +Word32 L_macNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ) +{ +#endif /* BASOP_NOGLOB */ + Word32 L_var_out; - +#ifdef BASOP_NOGLOB + L_var_out = L_mult_o( var1, var2, Overflow ); + L_var_out = L_add_co( L_var3, L_var_out, Carry, Overflow ); +#else /* BASOP_NOGLOB */ + L_var_out = L_mult( var1, var2 ); + L_var_out = L_add_c( L_var3, L_var_out ); +#endif /* BASOP_NOGLOB */ + return ( L_var_out ); +} +#ifdef BASOP_NOGLOB +Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + return L_macNs_co( L_var3, var1, var2, NULL, NULL ); +} +Word32 L_macNs_sat( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + Flag Carry, Overflow; + return L_macNs_co( L_var3, var1, var2, &Carry, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_msuNs | @@ -1374,7 +1688,28 @@ Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB +Word32 L_msuNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow ) +{ + Word32 L_var_out; + L_var_out = L_mult( var1, var2 ); + L_var_out = L_sub_co( L_var3, L_var_out, Carry, Overflow ); + + return ( L_var_out ); +} + + +Word32 L_msuNs( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + return L_msuNs_co( L_var3, var1, var2, NULL, NULL ); +} +Word32 L_msuNs_sat( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + Flag Carry, Overflow; + return L_msuNs_co( L_var3, var1, var2, &Carry, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_add | @@ -1460,6 +1795,11 @@ Word32 L_add( Word32 L_var1, Word32 L_var2 ) #endif return ( L_var_out ); } +Word32 L_add_sat( Word32 L_var1, Word32 L_var2 ) +{ + Flag Overflow; + return L_add_o( L_var1, L_var2, &Overflow ); +} #endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -1548,6 +1888,11 @@ Word32 L_sub( Word32 L_var1, Word32 L_var2 ) return ( L_var_out ); } +Word32 L_sub_sat( Word32 L_var1, Word32 L_var2 ) +{ + Flag Overflow; + return L_sub_o( L_var1, L_var2, &Overflow ); +} #endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -1711,8 +2056,83 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB +Word32 L_add_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) +{ + Word32 L_var_out; + Word32 L_test; + Flag carry_int = 0; + + L_var_out = L_var1 + L_var2 + get_carry( Carry ); + + L_test = L_var1 + L_var2; + + if ( ( L_var1 > 0 ) && ( L_var2 > 0 ) && ( L_test < 0 ) ) + { + set_overflow( Overflow ); + carry_int = 0; + } + else + { + if ( ( L_var1 < 0 ) && ( L_var2 < 0 ) ) + { + if ( L_test >= 0 ) + { + set_overflow( Overflow ); + carry_int = 1; + } + else + { + unset_overflow( Overflow ); + carry_int = 1; + } + } + else + { + if ( ( ( L_var1 ^ L_var2 ) < 0 ) && ( L_test >= 0 ) ) + { + unset_overflow( Overflow ); + carry_int = 1; + } + else + { + unset_overflow( Overflow ); + carry_int = 0; + } + } + } + if ( get_carry( Carry ) ) + { + if ( L_test == MAX_32 ) + { + set_overflow( Overflow ); + carry_int ? set_carry( Carry ) : unset_carry( Carry ); + } + else + { + if ( L_test == (Word32) 0xFFFFFFFFL ) + { + set_carry( Carry ); + } + else + { + carry_int ? set_carry( Carry ) : unset_carry( Carry ); + } + } + } + else + { + carry_int ? set_carry( Carry ) : unset_carry( Carry ); + } + return ( L_var_out ); +} +Word32 L_add_c( Word32 L_var1, Word32 L_var2 ) +{ + return L_add_co( L_var1, L_var2, NULL, NULL ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_sub_c | @@ -1858,8 +2278,63 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB +Word32 L_sub_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) +{ + Word32 L_var_out; + Word32 L_test; + Flag carry_int = 0; + if ( get_carry( Carry ) ) + { + unset_carry( Carry ); + if ( L_var2 != MIN_32 ) + { + L_var_out = L_add_co( L_var1, -L_var2, Carry, Overflow ); + } + else + { + L_var_out = L_var1 - L_var2; + if ( L_var1 > 0L ) + { + unset_carry( Carry ); + } + } + } + else + { + L_var_out = L_var1 - L_var2 - (Word32) 0X00000001L; + L_test = L_var1 - L_var2; + if ( ( L_test < 0 ) && ( L_var1 > 0 ) && ( L_var2 < 0 ) ) + { + carry_int = 0; + } + else if ( ( L_test > 0 ) && ( L_var1 < 0 ) && ( L_var2 > 0 ) ) + { + carry_int = 1; + } + else if ( ( L_test > 0 ) && ( ( L_var1 ^ L_var2 ) > 0 ) ) + { + carry_int = 1; + } + if ( L_test == MIN_32 ) + { + carry_int ? set_carry( Carry ) : unset_carry( Carry ); + } + else + { + carry_int ? set_carry( Carry ) : unset_carry( Carry ); + } + } + + return ( L_var_out ); +} +Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ) +{ + return L_sub_co( L_var1, L_var2, NULL, NULL ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_negate | @@ -1984,7 +2459,13 @@ Word16 mult_r( Word16 var1, Word16 var2 ) return ( var_out ); } - +#ifdef BASOP_NOGLOB +Word16 mult_r_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return mult_ro( var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_shl | @@ -2127,8 +2608,14 @@ Word32 L_shl( Word32 L_var1, Word16 var2 ) return ( L_var_out ); } -#endif /* BASOP_NOGLOB */ +Word32 L_shl_sat( Word32 L_var1, Word16 var2 ) +{ + Flag Overflow; + return L_shl_o( L_var1, var2, &Overflow ); +} + +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | | Function Name : L_shr | @@ -2248,8 +2735,13 @@ Word32 L_shr( Word32 L_var1, Word16 var2 ) return ( L_var_out ); } - - +#ifdef BASOP_NOGLOB +Word32 L_shr_sat( Word32 L_var1, Word16 var2 ) +{ + Flag Overflow; + return L_shr_o( L_var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : shr_r | @@ -2323,8 +2815,35 @@ Word16 shr_r( Word16 var1, Word16 var2 ) return ( var_out ); } +#ifdef BASOP_NOGLOB +Word16 shr_ro( Word16 var1, Word16 var2, Flag *Overflow ) +{ + Word16 var_out; + if ( var2 > 15 ) + { + var_out = 0; + } + else + { + var_out = shr_o( var1, var2, Overflow ); + if ( var2 > 0 ) + { + if ( ( var1 & ( (Word16) 1 << ( var2 - 1 ) ) ) != 0 ) + { + var_out++; + } + } + } + return ( var_out ); +} +Word16 shr_r_sat( Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return shr_ro( var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : mac_r | @@ -2406,8 +2925,13 @@ Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ) return ( var_out ); } - - +#ifdef BASOP_NOGLOB +Word16 mac_r_sat( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return mac_ro( L_var3, var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : msu_r | @@ -2485,8 +3009,13 @@ Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ) return ( var_out ); } - - +#ifdef BASOP_NOGLOB +Word16 msu_r_sat( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return msu_ro( L_var3, var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_deposit_h | @@ -2651,8 +3180,35 @@ Word32 L_shr_r( Word32 L_var1, Word16 var2 ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB +Word32 L_shr_ro( Word32 L_var1, Word16 var2, Flag *Overflow ) +{ + Word32 L_var_out; + if ( var2 > 31 ) + { + L_var_out = 0; + } + else + { + L_var_out = L_shr_o( L_var1, var2, Overflow ); + if ( var2 > 0 ) + { + if ( ( L_var1 & ( (Word32) 1 << ( var2 - 1 ) ) ) != 0 ) + { + L_var_out++; + } + } + } + return ( L_var_out ); +} +Word32 L_shr_r_sat( Word32 L_var1, Word16 var2 ) +{ + Flag Overflow = 0; + return L_shr_ro( L_var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | | Function Name : L_abs | @@ -2779,8 +3335,34 @@ Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB +Word32 L_sat_co( Word32 L_var1, Flag Carry, Flag Overflow ) +{ + Word32 L_var_out; + L_var_out = L_var1; + if ( Overflow ) + { + + if ( Carry ) + { + L_var_out = MIN_32; + } + else + { + L_var_out = MAX_32; + } + } + return ( L_var_out ); +} + +Word32 L_sat( Word32 L_var1 ) +{ + assert( 0 ); /* Overflow and Carry are no longer global, must be passed as parameters */ + return L_sat_co( L_var1, 0, 0 ); +} +#endif /*___________________________________________________________________________ | | | Function Name : norm_s | @@ -3113,7 +3695,13 @@ Word32 L_mls( Word32 Lv, Word16 v ) return Temp; } - +#ifdef BASOP_NOGLOB +Word32 L_mls_sat( Word32 Lv, Word16 v ) +{ + Flag Overflow; + return L_mls_o( Lv, v, &Overflow ); +} +#endif /*__________________________________________________________________________ | | @@ -3268,7 +3856,26 @@ Word16 DEPR_i_mult( Word16 a, Word16 b ) #endif } - +#ifdef BASOP_NOGLOB +Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) +{ +#ifdef ORIGINAL_G7231 + return a * b; +#else + Word32 register c = a * b; + return saturate_o( c, Overflow ); +#endif +} +Word16 i_mult( Word16 a, Word16 b ) +{ + return i_mult_o( a, b, NULL ); +} +Word16 i_mult_sat( Word16 a, Word16 b ) +{ + Flag Overflow; + return i_mult_o( a, b, &Overflow ); +} +#endif /* ****************************************************************************** * The following three operators are not part of the original @@ -3388,8 +3995,13 @@ Word32 L_mac0( Word32 L_var3, Word16 var1, Word16 var2 ) return ( L_var_out ); } - - +#ifdef BASOP_NOGLOB +Word32 L_mac0_sat( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return L_mac0_o( L_var3, var1, var2, &Overflow ); +} +#endif /*___________________________________________________________________________ | | Function Name : L_msu0 @@ -3460,5 +4072,12 @@ Word32 L_msu0( Word32 L_var3, Word16 var1, Word16 var2 ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB +Word32 L_msu0_sat( Word32 L_var3, Word16 var1, Word16 var2 ) +{ + Flag Overflow; + return L_msu0_o( L_var3, var1, var2, &Overflow ); +} +#endif #undef WMC_TOOL_SKIP diff --git a/lib_com/basop32.h b/lib_com/basop32.h index f1a7e1b86..3c45f8000 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -97,6 +97,11 @@ extern Flag BASOP_Overflow, BASOP_Overflow2; extern Flag BASOP_Carry; */ #endif /* BASOP_NOGLOB */ +#define BASOP_SATURATE_WARNING_ON_EVS +#define BASOP_SATURATE_WARNING_OFF_EVS +#define BASOP_SATURATE_ERROR_ON_EVS +#define BASOP_SATURATE_ERROR_OFF_EVS + #define BASOP_SATURATE_WARNING_ON #define BASOP_SATURATE_WARNING_OFF #define BASOP_SATURATE_ERROR_ON @@ -109,7 +114,13 @@ extern Flag BASOP_Carry; #define MAX_16 (Word16) 0x7fff #define MIN_16 (Word16) 0x8000 - +#ifdef BASOP_NOGLOB +void set_overflow( Flag *overflow ); +void unset_overflow( Flag *overflow ); +void set_carry( Flag *carry ); +void unset_carry( Flag *carry ); +Flag get_carry( const Flag *carry ); +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | | Prototypes for basic arithmetic operators | @@ -148,7 +159,14 @@ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ); /* Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu, 1 */ Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ); /* Mac without sat, 1 */ -#endif /* BASOP_NOGLOB */ +Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac without sat, 1 */ +Word32 L_msuNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu without sat, 1 */ +Word32 L_add_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ); +Word32 L_sub_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ); +Word32 L_add_c( Word32 L_var1, Word32 L_var2 ); /* Long add with c, 2 */ +Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ); /* Long sub with c, 2 */ + +#endif /* BASOP_NOGLOB */ #ifndef BASOP_NOGLOB Word32 L_msuNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu without @@ -221,7 +239,8 @@ Word32 L_abs( Word32 L_var1 ); /* Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ); /* Long saturation, 4 */ Word16 norm_s( Word16 var1 ); /* Short norm, 1 */ Word16 div_s( Word16 var1, Word16 var2 ); /* Short division, 18 */ -Word16 norm_l( Word32 L_var1 ); /* Long norm, 1 */ +Word32 div_w( Word32 L_num, Word32 L_den ); +Word16 norm_l( Word32 L_var1 ); /* Long norm, 1 */ #endif /* BASOP_NOGLOB */ @@ -233,9 +252,10 @@ Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ #else /* BASOP_NOGLOB */ -Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ -Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ -Word16 DEPR_i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ +Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ +Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ +Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ +Word16 DEPR_i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ #endif /* BASOP_NOGLOB */ /* @@ -249,9 +269,12 @@ Word32 L_msu0( Word32 L_v3, Word16 v1, Word16 v2 ); /* 32-bit Msu w/o shift 1 * /* * Overflowing operators */ +Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ); Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow ); Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow ); Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ); +Word16 shr_o( Word16 var1, Word16 var2, Flag *Overflow ); +Word16 shr_ro( Word16 var1, Word16 var2, Flag *Overflow ); Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow ); Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ); Word16 round_fx_o( Word32 L_var1, Flag *Overflow ); @@ -267,9 +290,40 @@ Word32 L_msu0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ); Word16 mult_ro( Word16 var1, Word16 var2, Flag *Overflow ); Word16 mac_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ); Word16 msu_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ); -#endif /* BASOP_NOGLOB */ +Word32 L_sat_co( Word32 L_var1, Flag Carry, Flag Overflow ); +Word32 L_shr_ro( Word32 L_var1, Word16 var2, Flag *Overflow ); +Word32 L_macNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow ); +Word32 L_msuNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow ); +#endif /* BASOP_NOGLOB */ +/* + * Saturating operators + */ +Word16 i_mult_sat( Word16 a, Word16 b ); +Word16 add_sat( Word16 var1, Word16 var2 ); +Word16 sub_sat( Word16 var1, Word16 var2 ); +Word16 shl_sat( Word16 var1, Word16 var2 ); +Word16 shr_sat( Word16 var1, Word16 var2 ); +Word16 shr_r_sat( Word16 var1, Word16 var2 ); +Word16 mult_sat( Word16 var1, Word16 var2 ); +Word32 L_mult_sat( Word16 var1, Word16 var2 ); +Word16 round_fx_sat( Word32 L_var1 ); +Word32 L_mac_sat( Word32 L_var3, Word16 var1, Word16 var2 ); +Word32 L_msu_sat( Word32 L_var3, Word16 var1, Word16 var2 ); +Word32 L_macNs_sat( Word32 L_var3, Word16 var1, Word16 var2 ); +Word32 L_msuNs_sat( Word32 L_var3, Word16 var1, Word16 var2 ); +Word32 L_add_sat( Word32 L_var1, Word32 L_var2 ); +Word32 L_sub_sat( Word32 L_var1, Word32 L_var2 ); +Word32 L_shr_sat( Word32 L_var1, Word16 var2 ); +Word32 L_shl_sat( Word32 L_var1, Word16 var2 ); +Word32 L_mls_sat( Word32 Lv, Word16 v ); +Word32 L_mac0_sat( Word32 L_var3, Word16 var1, Word16 var2 ); +Word32 L_msu0_sat( Word32 L_var3, Word16 var1, Word16 var2 ); +Word16 mult_r_sat( Word16 var1, Word16 var2 ); +Word16 mac_r_sat( Word32 L_var3, Word16 var1, Word16 var2 ); +Word16 msu_r_sat( Word32 L_var3, Word16 var1, Word16 var2 ); +Word32 L_shr_r_sat( Word32 L_var1, Word16 var2 ); #endif /* ifndef _BASIC_OP_H */ diff --git a/lib_com/basop_mpy.c b/lib_com/basop_mpy.c index db2a14c0b..1e5b077b7 100644 --- a/lib_com/basop_mpy.c +++ b/lib_com/basop_mpy.c @@ -37,56 +37,86 @@ #include "basop_mpy.h" #include #include "options.h" +#include "enh64.h" #ifdef DEBUGGING #include "debug.h" #endif #define WMC_TOOL_SKIP -Word32 Mpy_32_16_1( Word32 x, Word16 y ) -{ - Word32 mh; - UWord16 ml; +/***************************************************************************** + * + * Functions + * + *****************************************************************************/ - Mpy_32_16_ss( x, y, &mh, &ml ); - - return ( mh ); +Word32 Mpy_32_16_1( Word32 L_var1, Word16 var2 ) +{ + Word32 L_var_out = W_sat_m( W_mult_32_16( L_var1, var2 ) ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_1++; + multiCounter[currCounter].W_mult_32_16--; + multiCounter[currCounter].W_sat_m--; +#endif /* if WMOPS */ + return L_var_out; } -Word32 Mpy_32_16( Word32 x, Word16 y ) +Word32 Mpy_32_16_r( Word32 L_var1, Word16 var2 ) { - Word32 mh; - UWord16 ml; - - Mpy_32_16_ss( x, y, &mh, &ml ); - - return ( mh ); + Word32 L_var_out = W_round48_L( W_mult_32_16( L_var1, var2 ) ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_r++; + multiCounter[currCounter].W_mult_32_16--; + multiCounter[currCounter].W_round48_L--; +#endif /* if WMOPS */ + return L_var_out; } -Word32 Mpy_32_16_r( Word32 x, Word16 y ) +Word32 Mpy_32_32( Word32 L_var1, Word32 L_var2 ) { - Word32 mh; - UWord16 ml; - - Mpy_32_16_ss( x, y, &mh, &ml ); - - if ( s_and( ml, -32768 /* 0x8000 */ ) ) - { - mh = L_add( mh, 1 ); - } + Word32 L_var_out; + Word64 L64_var1; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif - return ( mh ); + L64_var1 = ( (Word64) L_var1 * L_var2 ); +#ifdef BASOP_NOGLOB + L64_var1 = W_shl_o( L64_var1, 1, &Overflow ); +#else /* BASOP_NOGLOB */ + L64_var1 = W_shl( L64_var1, 1 ); +#endif /* BASOP_NOGLOB */ + L_var_out = W_extract_h( L64_var1 ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32++; + multiCounter[currCounter].W_shl--; + multiCounter[currCounter].W_extract_h--; +#endif /* if WMOPS */ + return L_var_out; } - -Word32 Mpy_32_32( Word32 x, Word32 y ) +Word32 Mpy_32_32_r( Word32 L_var1, Word32 L_var2 ) +{ + Word32 L_var_out; + Word64 L64_var1; + + L64_var1 = ( (Word64) L_var1 * L_var2 ); + L64_var1 = W_shr( L64_var1, 15 ); + L_var_out = W_round48_L( L64_var1 ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32_r++; + multiCounter[currCounter].W_shr--; + multiCounter[currCounter].W_round48_L--; +#endif /* if WMOPS */ + return L_var_out; +} +Word32 Mpy_32_16( Word32 x, Word16 y ) { Word32 mh; - UWord32 ml; + UWord16 ml; - Mpy_32_32_ss( x, y, &mh, &ml ); + Mpy_32_16_ss( x, y, &mh, &ml ); return ( mh ); } - #undef WMC_TOOL_SKIP diff --git a/lib_com/basop_mpy.h b/lib_com/basop_mpy.h index 4a8d4473c..1e2f7914c 100644 --- a/lib_com/basop_mpy.h +++ b/lib_com/basop_mpy.h @@ -97,4 +97,6 @@ Word32 Mpy_32_16_r( Word32 x, Word16 y ); Word32 Mpy_32_32( Word32 x, Word32 y ); +Word32 Mpy_32_32_r( Word32 L_var1, Word32 L_var2 ); + #endif /* __BASOP_SETTINGS_H */ diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 0a168852b..d70ad5633 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -46,7 +46,11 @@ #include "basop_mpy.h" #include "stl.h" #include "cnst.h" - +#include "prot_fx2.h" +#include "enh64.h" +#define BASOP_SATURATE_WARNING_ON_EVS +#define BASOP_SATURATE_WARNING_OFF_EVS +#define BASOP_NOGLOB_DECLARE_LOCAL #define WMC_TOOL_SKIP extern const Word32 SqrtTable[32]; @@ -636,23 +640,23 @@ static Word16 fixp_sin_cos_residual_16( return residual; } - -Word16 getCosWord16R2( - Word16 theta ) -{ - Word16 result, residual, sine, cosine; - - residual = fixp_sin_cos_residual_16( theta, 1, &sine, &cosine, 1 ); - /* This negation prevents the subsequent addition from overflow */ - /* The negation cannot overflow, sine is in range [0x0..0x7FFF] */ - BASOP_SATURATE_WARNING_OFF - sine = negate( sine ); - result = msu_r( L_mult( sine, residual ), cosine, -32768 ); - BASOP_SATURATE_WARNING_ON - - return result; -} - +// +// Word16 getCosWord16R2( +// Word16 theta ) +//{ +// Word16 result, residual, sine, cosine; +// +// residual = fixp_sin_cos_residual_16( theta, 1, &sine, &cosine, 1 ); +// /* This negation prevents the subsequent addition from overflow */ +// /* The negation cannot overflow, sine is in range [0x0..0x7FFF] */ +// BASOP_SATURATE_WARNING_OFF +// sine = negate( sine ); +// result = msu_r( L_mult( sine, residual ), cosine, -32768 ); +// BASOP_SATURATE_WARNING_ON +// +// return result; +//} +// Word16 idiv1616U( Word16 x, @@ -676,6 +680,99 @@ Word16 idiv1616U( return y; } +Word16 BASOP_Util_Cmp_Mant32Exp /*!< o: flag: result of comparison */ + /* 0, if a == b */ + /* 1, if a > b */ + /* -1, if a < b */ + ( Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e ) /*!< i: Exponent of 2nd operand b */ + +{ + Word32 diff_m; + Word16 diff_e, shift, result; + + + /* + This function compares two input parameters, both represented by a 32-bit mantissa and a 16-bit exponent. + If both values are identical, 0 is returned. + If a is greater b, 1 is returned. + If a is less than b, -1 is returned. + */ + + /* Check, if both mantissa and exponents are identical, when normalized: return 0 */ + shift = norm_l( a_m ); + if ( shift ) + a_m = L_shl( a_m, shift ); + if ( shift ) + a_e = sub( a_e, shift ); + + shift = norm_l( b_m ); + if ( shift ) + b_m = L_shl( b_m, shift ); + if ( shift ) + b_e = sub( b_e, shift ); + + /* align exponent, if any mantissa is zero */ + if ( !a_m ) + { + a_e = b_e; + move16(); + } + if ( !b_m ) + { + b_e = a_e; + move16(); + } + + BASOP_SATURATE_WARNING_OFF_EVS + Flag overflow; + diff_m = L_sub_o( a_m, b_m, &overflow ); + BASOP_SATURATE_WARNING_ON_EVS + diff_e = sub( a_e, b_e ); + + test(); + IF( diff_m == 0 && diff_e == 0 ) + { + return 0; + } + + /* Check sign, exponent and mantissa to identify, whether a is greater b or not */ + result = sub( 0, 1 ); + + IF( a_m >= 0 ) + { + /* a is positive */ + if ( b_m < 0 ) + { + result = 1; + move16(); + } + + test(); + test(); + test(); + if ( ( b_m >= 0 ) && ( ( diff_e > 0 ) || ( diff_e == 0 && diff_m > 0 ) ) ) + { + result = 1; + move16(); + } + } + ELSE + { + /* a is negative */ + test(); + test(); + test(); + if ( ( b_m < 0 ) && ( ( diff_e < 0 ) || ( diff_e == 0 && diff_m > 0 ) ) ) + { + result = 1; + move16(); + } + } + return result; +} Word32 BASOP_util_Pow2( const Word32 exp_m, const Word16 exp_e, @@ -885,6 +982,78 @@ Word16 Log2_norm_lc( /* o : Fractional part of Log2. (range: 0<=val< return y; } +Word16 getCosWord16( Word16 theta ) +{ + Word16 result, residual, sine, cosine; + + residual = fixp_sin_cos_residual_16( theta, 2, &sine, &cosine, 0 ); + /* This negation prevents the subsequent addition from overflow */ + /* The negation cannot overflow, sine is in range [0x0..0x7FFF] */ + sine = negate( sine ); + result = mac_r( L_mult0( sine, residual ), cosine, 16384 ); + + + return result; +} + +Word16 getSinWord16( Word16 theta ) +{ + Word16 sine; + Word32 theta_new = L_sub( EVS_PI_BY_2_FX, theta ); + Word16 l_theta; + IF( GT_32( theta_new, EVS_PI_FX16 ) ) + { + l_theta = extract_l( L_sub( L_sub( theta_new, EVS_PI_FX16 ), EVS_PI_FX16 ) ); + } + ELSE IF( LT_32( theta_new, -EVS_PI_FX16 ) ) + { + l_theta = extract_l( L_add( L_add( theta_new, EVS_PI_FX16 ), EVS_PI_FX16 ) ); + } + ELSE + { + l_theta = extract_l( theta_new ); + } + sine = getCosWord16( l_theta ); + /*IF( EQ_16( sine, ONE_IN_Q14 ) ) + { + sine = MAX_16; + } + ELSE + { + sine = shl( sine, 1 ); + }*/ + return sine; +} + +Word16 getCosWord16R2( + Word16 theta ) +{ + Word16 result, residual, sine, cosine; + + residual = fixp_sin_cos_residual_16( theta, 1, &sine, &cosine, 1 ); + /* This negation prevents the subsequent addition from overflow */ + /* The negation cannot overflow, sine is in range [0x0..0x7FFF] */ + BASOP_SATURATE_WARNING_OFF + sine = negate( sine ); + result = msu_r( L_mult( sine, residual ), cosine, -32768 ); + BASOP_SATURATE_WARNING_ON + + return result; +} + + +Word16 getSineWord16R2( Word16 theta ) +{ + IF( EQ_16( theta, (Word16) 0 ) ) + { + return 0; + } + ELSE IF( LT_16( theta, (Word16) -24576 ) ) + { + theta = add( add( theta, (Word16) 32767 ), (Word16) 1 ); + } + return getCosWord16R2( sub( 8192, theta ) ); +} Word32 BASOP_Util_fPow( Word32 base_m, @@ -1085,12 +1254,8 @@ Word32 Sqrt_l( return L_deposit_l( 0 ); } -#if 0 /* original version creates an overflow warning */ - e = s_and(norm_l(L_x), 0xFFFE); /* get next lower EVEN norm. exp */ -#else e = s_and( norm_l( L_x ), 0x7FFE ); /* get next lower EVEN norm. exp */ -#endif - L_x = L_shl( L_x, e ); /* L_x is normalized to [0.25..1) */ + L_x = L_shl( L_x, e ); /* L_x is normalized to [0.25..1) */ *exp = e; move16(); /* return 2*exponent (or Q1) */ @@ -1109,4 +1274,457 @@ Word32 Sqrt_l( return ( L_y ); } +/* local function for Sqrt32 and Sqrt32norm */ +static Word32 Sqrt32_common( Word32 m, + Word16 e ) +{ + Word16 m16, index, frac; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + assert( ( m >= 0x40000000 ) || ( m == 0 ) ); + +#ifdef BASOP_NOGLOB + m16 = round_fx_o( m, &Overflow ); +#else /* BASOP_NOGLOB */ + m16 = round_fx( m ); +#endif /* BASOP_NOGLOB */ + + /* get table index (upper 6 bits minus 32) */ + /* index = (m16 >> 9) - 32; */ + index = mac_r( -32768 - ( 32 << 16 ), m16, 1 << 6 ); + + /* get fractional part for interpolation (lower 9 bits) */ + frac = s_and( m16, 0x1FF ); /* Q9 */ + + /* interpolate */ + if ( m != 0 ) + { + BASOP_SATURATE_WARNING_OFF_EVS; + m = L_mac( SqrtTable[index], SqrtDiffTable[index], frac ); + BASOP_SATURATE_WARNING_ON_EVS; + } + + /* handle odd exponents */ + if ( s_and( e, 1 ) != 0 ) + m = Mpy_32_16_1( m, 0x5a82 ); + + return m; +} +Word32 Sqrt32( /*!< output mantissa */ + Word32 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +) +{ + Word16 preShift, e; + + assert( mantissa >= 0 ); + + /* normalize */ + preShift = norm_l( mantissa ); + + e = sub( *exponent, preShift ); + mantissa = L_shl( mantissa, preShift ); + + /* calc mantissa */ + mantissa = Sqrt32_common( mantissa, e ); + + /* e = (e + 1) >> 1 */ + *exponent = mult_r( e, 1 << 14 ); + move16(); + + return mantissa; +} +/* --- fixp_atan() ---- */ +#define Q_ATANINP ( 25 ) /* Input in q25, Output in q14 */ +#define Q_ATANOUT ( 14 ) +#define ATI_SF ( ( 32 - 1 ) - Q_ATANINP ) /* 6 */ +#define ATO_SF ( ( 16 - 1 ) - Q_ATANOUT ) /* 1 ] -pi/2 .. pi/2 [ */ +/* --- fixp_atan2() --- */ +#define Q_ATAN2OUT ( 13 ) +#define AT2O_SF ( ( 16 - 1 ) - Q_ATAN2OUT ) /* 2 ] -pi .. pi ] */ +/* SNR of fixp_atan() = 56 dB*/ +#define ONEBY3P56 0x26800000 /* 1.0/3.56 in q31*/ +#define P281 0x00026000 /* 0.281 in q19*/ +#define ONEP571 0x6487 /* 1.571 in q14*/ +Word16 BASOP_util_atan( /* o: atan(x) [-pi/2;pi/2] 1Q14 */ + Word32 x /* i: input data (-64;64) 6Q25 */ +) +{ + Word16 sign, result, exp; + Word16 res_e; + Word16 tmp, xx; + + + sign = 0; + move16(); + if ( x < 0 ) + { + sign = 1; + move16(); + } + x = L_abs( x ); + + /* calc of arctan */ + IF( LT_32( x, 1509950l /*0.045f/64.0f Q31*/ ) ) + { + result = round_fx( L_shl( x, 5 ) ); /*Q14*/ + /*BASOP_util_atan_16(0.0444059968): max error 0.0000567511, mean 0.000017, abs mean 0.000017*/ + } + ELSE + IF( LT_32( x, ( L_shl( 1, Q_ATANINP ) - 8482560l /*0.00395 Q31*/ ) ) ) + { + xx = round_fx( L_shl( x, 6 ) ); + tmp = mult_r( xx, xx ); /* q15 * q15 - (16-1) = q15*/ + tmp = mult_r( tmp, 0x1340 ); /* 15 * (ONEBY3P56) q14 - (16-1) = q14*/ + tmp = add( tmp, 0x4000 ); /*L_shl(1,14) = 524288*/ /* q14 + q14 = q14 */ + res_e = Q_ATANOUT - 15 + 14 - 16 + 1; + move16(); + if ( GT_16( xx, tmp ) ) + { + res_e = add( res_e, 1 ); + } + if ( GT_16( xx, tmp ) ) + { + xx = shr( xx, 1 ); + } + result = div_s( xx, tmp ); + result = msu_r( 0, result, shl( -32768, res_e ) ); + /*BASOP_util_atan_16(0.7471138239): max error 0.0020029545, mean 0.000715, abs mean 0.000715*/ + } + ELSE IF( LT_32( x, 42949673l /*1.28/64.0 Q31*/ ) ) + { + Word16 delta_fix; + Word32 PI_BY_4 = 1686629684l /*3.1415926/4.0 Q31*/ / 2; /* pi/4 in q30 */ + + delta_fix = round_fx( L_shl( L_sub( x, 33554432l /*1.0/64.0 Q31*/ ), 5 ) ); /* q30 */ + result = round_fx( L_sub( L_add( PI_BY_4, L_msu( 0, delta_fix, -16384 ) ), ( L_mult0( delta_fix, delta_fix ) ) ) ); + /* BASOP_Util_fPow(0.7472000122): max error 0.0020237688, mean 0.000026, abs mean 0.000520 */ + } + ELSE + { + exp = sub( norm_l( x ), 1 ); + xx = round_fx( L_shl( x, exp ) ); + /* q25+exp * q25+exp - (16-1) = q19+2*exp*/ + tmp = mac_r( L_shl( P281, shl( exp, 1 ) ), xx, xx ); /* q19+2*exp + q19+2*exp = q19+2*exp*/ + res_e = norm_s( tmp ); + result = div_s( xx, shl( tmp, res_e ) ); + result = shl( result, add( add( Q_ATANOUT - Q_ATANINP /*-exp*/ + 19 /*+2*exp*/ - 16 + 1, res_e ), exp ) ); + result = sub( ONEP571, result ); /* q14 + q14 = q14*/ + /*BASOP_Util_fPow(1.2799999714): max error 0.0020168927, mean 0.000066, abs mean 0.000072*/ + } + + if ( sign ) + { + result = negate( result ); + } + + return ( result ); +} +Word32 imult3216( Word32 x, Word16 y ) +{ + Word32 mh; + UWord16 ml; + + Mpy_32_16_ss( x, y, &mh, &ml ); + + mh = L_shl( mh, 15 ); + ml = lshr( ml, 1 ); + + return L_or( mh, L_deposit_l( ml ) ); +} +Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s ) +{ + Word16 z; + Word16 sy; + + + sy = norm_l( y ); + if ( sy > 0 ) + { + sy = sub( sy, 1 ); + } + y = L_shl( y, sy ); + + z = BASOP_Util_Divide3216_Scale( x, extract_h( y ), s ); + move16(); + *s = add( *s, sy ); + + + return ( z ); +} +Word32 div_w( Word32 L_num, Word32 L_den ) +{ + Word32 L_var_out = (Word32) 0; + Word16 iteration; + + + if ( L_den == (Word32) 0 ) + { + /* printf("Division by 0 in div_l, Fatal error in "); printStack(); */ + return ( 0 ); + } + + if ( ( L_num < (Word32) 0 ) || ( L_den < (Word32) 0 ) ) + { + /* printf("Division Error in div_l, Fatal error in "); printStack(); */ + return ( 0 ); + } + Word64 W_num, W_den; + W_num = W_deposit32_h( L_num ); + W_den = W_deposit32_h( L_den ); + + if ( W_num >= W_den ) + { + return MAX_32; + } + else + { + W_num = W_shr( W_num, (Word16) 1 ); + W_den = W_shr( W_den, (Word16) 1 ); + + for ( iteration = (Word16) 0; iteration < (Word16) 31; iteration++ ) + { + L_var_out = L_shl( L_var_out, (Word16) 1 ); + W_num = W_shl( W_num, (Word16) 1 ); + + if ( W_num >= W_den ) + { + W_num = W_sub( W_num, W_den ); + L_var_out = L_add( L_var_out, (Word32) 1 ); + } + } + + return L_var_out; + } +} +Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) +{ + Word32 z; + Word16 sx; + Word16 sy; + Word32 sign; + + /* assert (x >= (Word32)0); */ + assert( y != (Word32) 0 ); + + sign = 0; + move16(); + + IF( x < 0 ) + { + x = L_negate( x ); + sign = L_xor( sign, 1 ); + } + + IF( y < 0 ) + { + y = L_negate( y ); + sign = L_xor( sign, 1 ); + } + + IF( x == (Word32) 0 ) + { + *s = 0; + return ( (Word32) 0 ); + } + + sx = norm_l( x ); + x = L_shl( x, sx ); + x = L_shr( x, 1 ); + move16(); + *s = sub( 1, sx ); + + sy = norm_l( y ); + y = L_shl( y, sy ); + move16(); + *s = add( *s, sy ); + + z = div_w( x, y ); + + if ( sign != 0 ) + { + z = L_negate( z ); + } + + return z; +} +Word16 BASOP_Util_Divide3232_uu_1616_Scale( Word32 x, Word32 y, Word16 *s ) +{ + Word16 z; + Word16 sx; + Word16 sy; + Word16 x16; + Word16 y16; + + + assert( x >= 0 ); + assert( y > 0 ); + + if ( x == 0 ) + { + *s = 0; + move16(); + + + return ( 0 ); + } + + sx = norm_l( x ); + sy = norm_l( y ); + + x16 = extract_h( L_shl( x, sx ) ); + y16 = extract_h( L_shl( y, sy ) ); + + if ( GT_16( x16, y16 ) ) + { + sx = sub( sx, 1 ); + } + + if ( LT_16( y16, x16 ) ) + { + x16 = mult_r( x16, 0x4000 ); + } + + + z = div_s( x16, y16 ); + move16(); + *s = sub( sy, sx ); + + + return ( z ); +} +/* --- fixp_atan() ---- */ +#define Q_ATANINP ( 25 ) /* Input in q25, Output in q14 */ +#define Q_ATANOUT ( 14 ) +#define ATI_SF ( ( 32 - 1 ) - Q_ATANINP ) /* 6 */ +#define ATO_SF ( ( 16 - 1 ) - Q_ATANOUT ) /* 1 ] -pi/2 .. pi/2 [ */ +/* --- fixp_atan2() --- */ +#define Q_ATAN2OUT ( 13 ) +#define AT2O_SF ( ( 16 - 1 ) - Q_ATAN2OUT ) /* 2 ] -pi .. pi ] */ + +Word16 BASOP_util_atan2( /* o: atan2(y,x) [-pi,pi] Q13 */ + Word32 y, /* i: */ + Word32 x, /* i: */ + Word16 e /* i: exponent difference (exp_y - exp_x) */ +) +{ + Word16 q; + Word32 at; + Word16 ret = -32768 /*-1.0f Q15*/; + Word16 sf, sfo, stf; + Word32 L_sign; + + if ( L_or( y, x ) == 0 ) + { + return 0; + } + + IF( x == 0 ) + { + ret = 12868 /*+EVS_PI/2 Q13*/; + move16(); + if ( y < 0 ) + { + ret = negate( ret ); + } + + return ret; + } + + /* --- division */ + L_sign = L_and( L_xor( x, y ), 0x80000000 ); + + q = 32767 /*1.0f Q15*/; /* y/x = neg/zero = -Inf */ + sf = 0; + BASOP_SATURATE_WARNING_OFF_EVS + q = BASOP_Util_Divide3232_uu_1616_Scale( L_abs( y ), L_abs( x ), &sf ); + BASOP_SATURATE_WARNING_ON_EVS + + BASOP_SATURATE_WARNING_OFF_EVS + if ( L_sign < 0 ) + q = negate( q ); + BASOP_SATURATE_WARNING_ON_EVS + + sfo = add( sf, e ); + + /* --- atan() */ + IF( GT_16( sfo, ATI_SF ) ) + { + /* --- could not calc fixp_atan() here bec of input data out of range + ==> therefore give back boundary values */ + + sfo = s_min( sfo, MAXSFTAB ); + + /*q = FL2WORD16( 0.0f ); move16();*/ + + if ( q > 0 ) + { + move16(); + q = +f_atan_expand_range[sfo - ATI_SF - 1]; + } + if ( q < 0 ) + { + move16(); + q = -f_atan_expand_range[sfo - ATI_SF - 1]; + } + } + ELSE + { + /* --- calc of fixp_atan() is possible; input data within range + ==> set q on fixed scale level as desired from fixp_atan() */ + stf = sub( sfo, ATI_SF ); + + at = L_deposit_h( q ); + if ( stf < 0 ) + at = L_shl( at, stf ); + + q = BASOP_util_atan( at ); /* ATO_SF*/ + } + + + /* --- atan2() */ + + ret = shr( q, ( AT2O_SF - ATO_SF ) ); /* now AT2O_SF for atan2 */ + IF( x < 0 ) + { + if ( y >= 0 ) + { + ret = add( ret, 25736 /*EVS_PI Q13*/ ); + } + if ( y < 0 ) + { + ret = sub( ret, 25736 /* EVS_PI Q13*/ ); + } + } + + return ret; +} + +void Copy32( + const Word32 x[], /* i : input vector */ + Word32 y[], /* o : output vector */ + const Word16 L /* i : vector length */ +) +{ + Word16 i; + IF( y < x ) + { + FOR( i = 0; i < L; i++ ) + { + y[i] = x[i]; + move32(); + } + } + ELSE + { + FOR( i = L - 1; i >= 0; i-- ) + { + y[i] = x[i]; + move32(); + } + } +} + #undef WMC_TOOL_SKIP diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index c09b8ea62..b4eaede53 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -163,7 +163,19 @@ Word16 getScaleFactor32( /************************************************************************/ Word32 BASOP_Util_Log2( Word32 x ); +/*!********************************************************************** + \brief Returns the comparison result of two normalized values given by mantissa and exponent. + return value: -1: a < b, 0: a == b, 1; a > b + Mantissas are in 32-bit-fractional format with values between 0 and 1.
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ +************************************************************************/ +Word16 BASOP_Util_Cmp_Mant32Exp /*!< o: flag: result of comparison */ + ( Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e ); /*!< i: Exponent of 2nd operand b */ /****************************************************************************/ /*! \brief Does fractional division of Word16 arg1 by Word16 arg2 @@ -272,6 +284,7 @@ Word16 mult0( Word16 x, /* i : Multiplier */ * \return result with exponent 0. */ Word16 getCosWord16R2( Word16 theta ); +Word16 getSineWord16R2( Word16 theta ); /****************************************************************************/ /*! @@ -354,6 +367,35 @@ Word16 Log2_norm_lc( /* o : Fractional part of Log2. (range: 0<=val< Word32 L_x /* i : input value (normalized) */ ); +/****************************************************************************/ +/*! + \brief 32x16->32 integer multiplication with overflow control + + \return 32x16->32 integer + */ +Word32 imult3216( Word32 x, Word16 y ); + +/****************************************************************************/ +/*! + \brief Does fractional integer division of Word32 arg1 by Word32 arg2 + + This function scales up both values to avoid losing the accuracy of the outcome + too much.
+ + CAUTION: Arg 3 is a Word16 pointer which will point to the scalefactor difference + s_diff = sub(s2,s1), where s1 and s2 are the scalefactors of the arguments, which + were shifted in order to e.g. preserve accuracy. + I.e. the result has to be scaled due to shifting it + s_diff to the right to obtain the real result of the division. + + \return fractional Word16 integer z = arg1(32bits)/arg2(32bits) +*/ +Word16 BASOP_Util_Divide3232_Scale( Word32 x, /*!< i : Numerator*/ + Word32 y, /*!< i : Denominator*/ + Word16 *s ); /*!< o : Additional scalefactor difference*/ +Word32 div_w( Word32 L_num, Word32 L_den ); +Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ); + /************************************************************************* * * FUNCTION: BASOP_Util_fPow() @@ -414,5 +456,60 @@ Word32 BASOP_Util_Add_Mant32Exp /* o : normalized result mantissa */ Word32 dotWord32_16_guards( const Word32 *X, const Word16 *Y, Word16 n, Word16 hr, Word16 *shift ); Word32 Sqrt_l( Word32 L_x, Word16 *exp ); +Word32 Sqrt32( /*!< output mantissa */ + Word32 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +); -#endif /* __BASOP_UTIL_H__ */ +/****************************************************************************/ +/*! + \brief Does fractional integer division of UWord32 arg1 by UWord32 arg2 + + This function ensures both the numerator and the denominator are positive integers, + and scales up both values to avoid losing the accuracy of the outcome + too much.
+ + CAUTION: Arg 3 is a Word16 pointer which will point to the scalefactor difference + s_diff = sub(s2,s1), where s1 and s2 are the scalefactors of the arguments, which + were shifted in order to e.g. preserve accuracy. + I.e. the result has to be scaled due to shifting it + s_diff to the right to obtain the real result of the division. + + \return fractional Word16 integer z = arg1(32bits)/arg2(32bits) +*/ +Word16 BASOP_Util_Divide3232_uu_1616_Scale( Word32 x, /*!< i : Numerator*/ + Word32 y, /*!< i : Denominator*/ + Word16 *s ); /*!< o : Additional scalefactor difference*/ +/*!********************************************************************** + \brief Calculates atan(x). +************************************************************************/ +Word16 BASOP_util_atan( /*!< o: atan(x) [-pi/2;pi/2] 1Q14 */ + Word32 x /*!< i: input data (-64;64) 6Q25 */ +); +/*!********************************************************************** + \brief Calculates atan2(y,x). +************************************************************************/ +Word16 BASOP_util_atan2( /*!< o: atan2(y,x) [-pi,pi] Q13 */ + Word32 y, /*!< i: */ + Word32 x, /*!< i: */ + Word16 e /*!< i: exponent difference (exp_y - exp_x) */ +); + +/* Calculate sin/cos. Angle in 2Q13 format, result has exponent = 1 */ +Word16 getCosWord16( Word16 theta ); +Word16 getSinWord16( Word16 theta ); +Word32 getCosWord32( Word32 theta ); +/** + * \brief calculate cosine of angle. Tuned for ISF domain. + * \param theta Angle normalized to radix 2, theta = (angle in radians)*2.0/pi + * \return result with exponent 0. + */ +Word16 getCosWord16R2( Word16 theta ); +Word16 getSineWord16R2( Word16 theta ); + +Word16 BASOP_Util_Cmp_Mant32Exp /*!< o: flag: result of comparison */ + ( Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e ); /*!< i: Exponent of 2nd operand b */ +#endif /* __BASOP_UTIL_H__ */ diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 1490703ae..1c191c2ed 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -45,6 +45,7 @@ #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" +#include "prot_fx2.h" #if __STDC_VERSION__ >= 199901L #if defined __ICL @@ -54,15 +55,51 @@ #define restrict #endif +// static Word16 sampling_rate_table[4] = {10, 20, 40, 60}; +static Word16 find_guarded_bits_fx( Word32 n ) +{ + return n <= 1 ? 0 : n <= 2 ? 1 + : n <= 4 ? 2 + : n <= 8 ? 3 + : n <= 16 ? 4 + : n <= 32 ? 5 + : n <= 64 ? 6 + : n <= 128 ? 7 + : n <= 256 ? 8 + : n <= 512 ? 9 + : n <= 1024 ? 10 + : n <= 2048 ? 11 + : n <= 4096 ? 12 + : n <= 8192 ? 13 + : n <= 16384 ? 14 + : 15; +} /*-------------------------------------------------------------------* * Local prototypes *--------------------------------------------------------------------*/ static void cldfb_init_proto_and_twiddles( HANDLE_CLDFB_FILTER_BANK hs ); +static void cldfb_init_proto_and_twiddles_splitRenderer( HANDLE_CLDFB_FILTER_BANK hs ); static float GetEnergyCldfb( float *energyValuesSum, float *energyLookahead, float **realValues, float **imagValues, const int16_t numberBands, int16_t numberCols, TEC_ENC_HANDLE hTecEnc ); +static void set32_fx( + Word32 y[], /* i/o: Vector to set */ + const Word32 a, /* i : Value to set the vector to */ + const Word16 N /* i : Length of the vector */ +) +{ + Word16 i; + + FOR( i = 0; i < N; i++ ) + { + y[i] = a; + move32(); + } + + return; +} /*-------------------------------------------------------------------* * cplxMult() * @@ -479,6 +516,492 @@ void cldfbAnalysis_ts( return; } + +void cldfbAnalysis_ts_fx( + const Word32 *timeIn_fx, + /* i : time buffer */ // q + Word32 realBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : real value buffer */ // q - 5 + Word32 imagBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : imag value buffer */ // q - 5 + const Word16 samplesToProcess, /* i : samples to process */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word16 *q_cldfb ) +{ + Word16 i, k; + Word16 L2, M1, M2, M4; + Word16 no_col = h_cldfb->no_col; + + Word32 r1_fx, r2_fx, rr12_fx, ir12_fx; + Word32 i1_fx, i2_fx, ri12_fx, ii12_fx; + Word32 rBuffer_fx[2 * CLDFB_NO_CHANNELS_MAX]; + Word32 iBuffer_fx[2 * CLDFB_NO_CHANNELS_MAX]; + const Word32 *rot_vctr_re_fx; + const Word32 *rot_vctr_im_fx; + const Word32 *rot_vctr_delay_re_fx; + const Word32 *rot_vctr_delay_im_fx; + const Word16 *ptr_pf_fx; + Word16 ptr_pf_sf; + Word32 *timeBuffer_fx, buffer_fx[( CLDFB_NO_CHANNELS_MAX * CLDFB_NO_COL_MAX ) + ( 9 * CLDFB_NO_CHANNELS_MAX )]; + Word16 offset, frameSize; + + offset = h_cldfb->p_filter_length - h_cldfb->no_channels; + frameSize = h_cldfb->no_channels * h_cldfb->no_col; + + /* prepare input buffer */ + timeBuffer_fx = buffer_fx; + Copy32( h_cldfb->cldfb_state_fx, timeBuffer_fx, offset ); + + if ( samplesToProcess > -1 ) + { + Copy32( timeIn_fx, timeBuffer_fx + offset, samplesToProcess ); + set32_fx( timeBuffer_fx + offset + samplesToProcess, 0, ( frameSize - samplesToProcess ) ); + } + else + { + Copy32( timeIn_fx, timeBuffer_fx + offset, frameSize ); + } + + /* only process needed cols */ + if ( samplesToProcess > -1 ) + { + no_col = min( no_col, ( samplesToProcess + h_cldfb->no_channels - 1 ) / h_cldfb->no_channels ); + assert( no_col == 1 ); + } + + M1 = h_cldfb->no_channels; + M2 = M1 >> 1; + M4 = M1 >> 2; + L2 = M1 << 1; + + if ( M2 & 1 ) + { + M4 += 1; + } + + rot_vctr_re_fx = h_cldfb->rot_vec_ana_re_fx; // q = 29 + rot_vctr_im_fx = h_cldfb->rot_vec_ana_im_fx; // q = 29 + rot_vctr_delay_re_fx = h_cldfb->rot_vec_ana_delay_re_fx; // q = 31 + rot_vctr_delay_im_fx = h_cldfb->rot_vec_ana_delay_im_fx; // q = 31 + + ptr_pf_fx = h_cldfb->p_filter_fx; + ptr_pf_sf = h_cldfb->p_filter_sf; + + for ( i = 0; i < no_col; i++ ) + { + for ( k = 0; k < M4; k++ ) + { + /* prototype filter */ + r1_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 0 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 1 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 2 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 3 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 4 * L2 )] ) ); // q + + r2_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 0 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 1 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 2 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 3 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 4 * L2 )] ) ); // q + + i1_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )] ) ); // q + + i2_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 0 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 1 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 2 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 3 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 4 * L2 )] ) ); // q + + r1_fx = Mpy_32_16_1( r1_fx, ptr_pf_sf ); // q - 1 + r2_fx = Mpy_32_16_1( r2_fx, ptr_pf_sf ); // q - 1 + i1_fx = Mpy_32_16_1( i1_fx, ptr_pf_sf ); // q - 1 + i2_fx = Mpy_32_16_1( i2_fx, ptr_pf_sf ); // q - 1 + + /* folding + pre modulation of DST IV */ + rr12_fx = L_sub( r1_fx, r2_fx ); // q -1 + ri12_fx = L_negate( L_add( i1_fx, i2_fx ) ); // q - 1 + /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ + rBuffer_fx[2 * k] = L_sub( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + rBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + + ///* folding + pre modulation of DCT IV */ + ir12_fx = L_add( r1_fx, r2_fx ); // q - 1 + ii12_fx = L_sub( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ + iBuffer_fx[2 * k] = L_sub( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + iBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + } + + for ( k = M4; k < M2; k++ ) + { + /* prototype filter */ + r1_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 0 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 1 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 2 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 3 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 4 * L2 )] ) ); // q + + r2_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 0 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 1 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 2 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 3 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 4 * L2 )] ) ); // q + + i1_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 0 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 1 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 2 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 3 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 4 * L2 )] ) ); // q + + i2_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )] ) ); // q + + r1_fx = Mpy_32_16_1( r1_fx, ptr_pf_sf ); // q - 1 + r2_fx = Mpy_32_16_1( r2_fx, ptr_pf_sf ); // q - 1 + i1_fx = Mpy_32_16_1( i1_fx, ptr_pf_sf ); // q - 1 + i2_fx = Mpy_32_16_1( i2_fx, ptr_pf_sf ); // q - 1 + + /* folding + pre modulation of DST IV */ + rr12_fx = L_add( r1_fx, r2_fx ); // q - 1 + ri12_fx = L_sub( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ + rBuffer_fx[2 * k] = L_sub( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + rBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + + /* folding + pre modulation of DCT IV */ + ir12_fx = L_sub( r1_fx, r2_fx ); // q - 1 + ii12_fx = L_add( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ + iBuffer_fx[2 * k] = L_sub( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + iBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + } + + *q_cldfb = sub( *q_cldfb, 3 ); + + /* FFT of DST IV */ + Word16 q_shift; + q_shift = sub( s_min( getScaleFactor32( rBuffer_fx, 2 * CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( iBuffer_fx, 2 * CLDFB_NO_CHANNELS_MAX ) ), find_guarded_bits_fx( M2 ) ); + *q_cldfb = add( *q_cldfb, q_shift ); + for ( Word16 ind = 0; ind < 2 * CLDFB_NO_CHANNELS_MAX; ind++ ) + { + rBuffer_fx[ind] = L_shl( rBuffer_fx[ind], q_shift ); + } + for ( Word16 ind = 0; ind < 2 * CLDFB_NO_CHANNELS_MAX; ind++ ) + { + iBuffer_fx[ind] = L_shl( iBuffer_fx[ind], q_shift ); + } + fft_cldfb_fx( rBuffer_fx, M2 ); + + /* post modulation of DST IV */ + for ( k = 0; k < M2; k++ ) + { + /*cplxMult(&realBuffer[M1-1-(2*k)],&realBuffer[2*k],rBuffer[2*k],rBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ + realBuffer_fx[M1 - 1 - ( 2 * k )] = L_sub( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_re_fx[k] ), Mpy_32_32( rBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ) ); // q - 5 + realBuffer_fx[2 * k] = L_add( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_im_fx[k] ), Mpy_32_32( rBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ) ); // q - 5 + } + *q_cldfb = sub( *q_cldfb, 2 ); + + /* FFT of DCT IV */ + fft_cldfb_fx( iBuffer_fx, M2 ); + + q_shift = s_min( getScaleFactor32( rBuffer_fx, 2 * CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( iBuffer_fx, 2 * CLDFB_NO_CHANNELS_MAX ) ); + *q_cldfb = add( *q_cldfb, q_shift ); + for ( Word16 ind = 0; ind < 2 * CLDFB_NO_CHANNELS_MAX; ind++ ) + { + rBuffer_fx[ind] = L_shl( rBuffer_fx[ind], q_shift ); + } + for ( Word16 ind = 0; ind < 2 * CLDFB_NO_CHANNELS_MAX; ind++ ) + { + iBuffer_fx[ind] = L_shl( iBuffer_fx[ind], q_shift ); + } + + /* post modulation of DCT IV */ + for ( k = 0; k < M2; k++ ) + { + /* do it inplace */ + /*cplxMult(&imagBuffer[2*k],&imagBuffer[M1-1-(2*k)],iBuffer[2*k],iBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ + imagBuffer_fx[2 * k] = L_sub( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), Mpy_32_32( iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ) ); // q - 5 + imagBuffer_fx[M1 - 1 - ( 2 * k )] = L_add( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), Mpy_32_32( iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ) ); // q - 5 + } + + if ( h_cldfb->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + /* rotation due to delay*/ + /*if(h_cldfb->da != M1)*/ + if ( rot_vctr_delay_re_fx != NULL ) + { + for ( k = 0; k < M1; k++ ) + { + Word32 cplx_aux_fx; + /* delay */ + /*cplxMult(&rBuffer[k], &iBuffer[k], realBuffer[i][k], imagBuffer[i][k], cos((EVS_PI/M1)*(k+0.5)*((h_cldfb->da-M1)*0.5)), + sin((EVS_PI/M1)*(k+0.5)*((h_cldfb->da-M1)*0.5)));*/ + /*cplxMult(&rBuffer[k], &iBuffer[k], realBuffer[k], imagBuffer[k], rot_vctr_delay_re[k], rot_vctr_delay_im[k]);*/ + /*cplxMult(&realBuffer[k], &imagBuffer[k], realBuffer[k], imagBuffer[k], rot_vctr_delay_re[k], rot_vctr_delay_im[k]);*/ + /*realBuffer[k] = rBuffer[k]; + imagBuffer[k] = iBuffer[k];*/ + cplx_aux_fx = L_sub( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_re_fx[k] ), Mpy_32_32( imagBuffer_fx[k], rot_vctr_delay_im_fx[k] ) ); // q - 5 + imagBuffer_fx[k] = L_add( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_im_fx[k] ), Mpy_32_32( imagBuffer_fx[k], rot_vctr_delay_re_fx[k] ) ); // q - 5 + realBuffer_fx[k] = cplx_aux_fx; + } + } + } + + timeBuffer_fx += L2 * 5; + timeBuffer_fx += h_cldfb->no_channels - h_cldfb->p_filter_length; + } + + /* update memory */ + if ( samplesToProcess > -1 ) + { + Copy32( buffer_fx + samplesToProcess, h_cldfb->cldfb_state_fx, offset ); + } + else + { + Copy32( buffer_fx + frameSize, h_cldfb->cldfb_state_fx, offset ); + } + + return; +} + +void cldfbAnalysis_ts_fx_fixed_q( + const Word32 *timeIn_fx, + /* i : time buffer */ // q + Word32 realBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : real value buffer */ // q - 5 + Word32 imagBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : imag value buffer */ // q - 5 + const Word16 samplesToProcess, /* i : samples to process */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word16 *q_cldfb ) +{ + Word16 i, k; + Word16 L2, M1, M2, M4; + Word16 no_col = h_cldfb->no_col; + + Word32 r1_fx, r2_fx, rr12_fx, ir12_fx; + Word32 i1_fx, i2_fx, ri12_fx, ii12_fx; + Word32 rBuffer_fx[2 * CLDFB_NO_CHANNELS_MAX]; + Word32 iBuffer_fx[2 * CLDFB_NO_CHANNELS_MAX]; + const Word32 *rot_vctr_re_fx; + const Word32 *rot_vctr_im_fx; + const Word32 *rot_vctr_delay_re_fx; + const Word32 *rot_vctr_delay_im_fx; + const Word16 *ptr_pf_fx; + Word16 ptr_pf_sf; + Word32 *timeBuffer_fx, buffer_fx[( CLDFB_NO_CHANNELS_MAX * CLDFB_NO_COL_MAX ) + ( 9 * CLDFB_NO_CHANNELS_MAX )]; + Word16 offset, frameSize; + + offset = h_cldfb->p_filter_length - h_cldfb->no_channels; + frameSize = h_cldfb->no_channels * h_cldfb->no_col; + + /* prepare input buffer */ + timeBuffer_fx = buffer_fx; + Copy32( h_cldfb->cldfb_state_fx, timeBuffer_fx, offset ); + + if ( samplesToProcess > -1 ) + { + Copy32( timeIn_fx, timeBuffer_fx + offset, samplesToProcess ); + set32_fx( timeBuffer_fx + offset + samplesToProcess, 0, ( frameSize - samplesToProcess ) ); + } + else + { + Copy32( timeIn_fx, timeBuffer_fx + offset, frameSize ); + } + + /* only process needed cols */ + if ( samplesToProcess > -1 ) + { + no_col = min( no_col, ( samplesToProcess + h_cldfb->no_channels - 1 ) / h_cldfb->no_channels ); + assert( no_col == 1 ); + } + + M1 = h_cldfb->no_channels; + M2 = M1 >> 1; + M4 = M1 >> 2; + L2 = M1 << 1; + + if ( M2 & 1 ) + { + M4 += 1; + } + + rot_vctr_re_fx = h_cldfb->rot_vec_ana_re_fx; // q = 29 + rot_vctr_im_fx = h_cldfb->rot_vec_ana_im_fx; // q = 29 + rot_vctr_delay_re_fx = h_cldfb->rot_vec_ana_delay_re_fx; // q = 31 + rot_vctr_delay_im_fx = h_cldfb->rot_vec_ana_delay_im_fx; // q = 31 + + ptr_pf_fx = h_cldfb->p_filter_fx; + ptr_pf_sf = h_cldfb->p_filter_sf; + + for ( i = 0; i < no_col; i++ ) + { + for ( k = 0; k < M4; k++ ) + { + /* prototype filter */ + r1_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 0 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 1 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 2 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 3 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 4 * L2 )] ) ); // q + + r2_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 0 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 1 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 2 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 3 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 + ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 4 * L2 )] ) ); // q + + i1_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )] ) ); // q + + i2_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 0 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 1 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 2 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 3 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 - 1 - ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 4 * L2 )] ) ); // q + + r1_fx = Mpy_32_16_1( r1_fx, ptr_pf_sf ); // q - 1 + r2_fx = Mpy_32_16_1( r2_fx, ptr_pf_sf ); // q - 1 + i1_fx = Mpy_32_16_1( i1_fx, ptr_pf_sf ); // q - 1 + i2_fx = Mpy_32_16_1( i2_fx, ptr_pf_sf ); // q - 1 + + /* folding + pre modulation of DST IV */ + rr12_fx = L_sub( r1_fx, r2_fx ); // q -1 + ri12_fx = L_negate( L_add( i1_fx, i2_fx ) ); // q - 1 + /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ + rBuffer_fx[2 * k] = L_sub( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + rBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + + ///* folding + pre modulation of DCT IV */ + ir12_fx = L_add( r1_fx, r2_fx ); // q - 1 + ii12_fx = L_sub( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ + iBuffer_fx[2 * k] = L_sub( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + iBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + } + + for ( k = M4; k < M2; k++ ) + { + /* prototype filter */ + r1_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 0 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 1 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 2 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 3 * L2 )] ) ); // q + r1_fx = L_sub( r1_fx, Mpy_32_16_1( timeBuffer_fx[L2 - M2 - 1 - ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 4 * L2 )] ) ); // q + + r2_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 0 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 1 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 2 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 3 * L2 )] ) ); // q + r2_fx = L_sub( r2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 5 * M2 + ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 4 * L2 )] ) ); // q + + i1_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 0 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 1 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 2 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 3 * L2 )] ) ); // q + i1_fx = L_sub( i1_fx, Mpy_32_16_1( timeBuffer_fx[L2 + M2 - 1 - ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 4 * L2 )] ) ); // q + + i2_fx = L_sub( 0, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 0 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 1 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 2 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 3 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )] ) ); // q + i2_fx = L_sub( i2_fx, Mpy_32_16_1( timeBuffer_fx[L2 - 3 * M2 + ( 2 * k ) + 4 * L2], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )] ) ); // q + + r1_fx = Mpy_32_16_1( r1_fx, ptr_pf_sf ); // q - 1 + r2_fx = Mpy_32_16_1( r2_fx, ptr_pf_sf ); // q - 1 + i1_fx = Mpy_32_16_1( i1_fx, ptr_pf_sf ); // q - 1 + i2_fx = Mpy_32_16_1( i2_fx, ptr_pf_sf ); // q - 1 + + /* folding + pre modulation of DST IV */ + rr12_fx = L_add( r1_fx, r2_fx ); // q - 1 + ri12_fx = L_sub( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ + rBuffer_fx[2 * k] = L_sub( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + rBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + + /* folding + pre modulation of DCT IV */ + ir12_fx = L_sub( r1_fx, r2_fx ); // q - 1 + ii12_fx = L_add( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ + iBuffer_fx[2 * k] = L_sub( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + iBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + } + + *q_cldfb = sub( *q_cldfb, 3 ); + + /* FFT of DST IV */ + fft_cldfb_fx( rBuffer_fx, M2 ); + + /* post modulation of DST IV */ + for ( k = 0; k < M2; k++ ) + { + /*cplxMult(&realBuffer[M1-1-(2*k)],&realBuffer[2*k],rBuffer[2*k],rBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ + realBuffer_fx[M1 - 1 - ( 2 * k )] = L_sub( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_re_fx[k] ), Mpy_32_32( rBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ) ); // q - 5 + realBuffer_fx[2 * k] = L_add( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_im_fx[k] ), Mpy_32_32( rBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ) ); // q - 5 + } + *q_cldfb = sub( *q_cldfb, 2 ); + + /* FFT of DCT IV */ + fft_cldfb_fx( iBuffer_fx, M2 ); + + /* post modulation of DCT IV */ + for ( k = 0; k < M2; k++ ) + { + /* do it inplace */ + /*cplxMult(&imagBuffer[2*k],&imagBuffer[M1-1-(2*k)],iBuffer[2*k],iBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ + imagBuffer_fx[2 * k] = L_sub( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), Mpy_32_32( iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ) ); // q - 5 + imagBuffer_fx[M1 - 1 - ( 2 * k )] = L_add( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), Mpy_32_32( iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ) ); // q - 5 + } + + if ( h_cldfb->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + /* rotation due to delay*/ + /*if(h_cldfb->da != M1)*/ + if ( rot_vctr_delay_re_fx != NULL ) + { + for ( k = 0; k < M1; k++ ) + { + Word32 cplx_aux_fx; + /* delay */ + /*cplxMult(&rBuffer[k], &iBuffer[k], realBuffer[i][k], imagBuffer[i][k], cos((EVS_PI/M1)*(k+0.5)*((h_cldfb->da-M1)*0.5)), + sin((EVS_PI/M1)*(k+0.5)*((h_cldfb->da-M1)*0.5)));*/ + /*cplxMult(&rBuffer[k], &iBuffer[k], realBuffer[k], imagBuffer[k], rot_vctr_delay_re[k], rot_vctr_delay_im[k]);*/ + /*cplxMult(&realBuffer[k], &imagBuffer[k], realBuffer[k], imagBuffer[k], rot_vctr_delay_re[k], rot_vctr_delay_im[k]);*/ + /*realBuffer[k] = rBuffer[k]; + imagBuffer[k] = iBuffer[k];*/ + cplx_aux_fx = L_sub( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_re_fx[k] ), Mpy_32_32( imagBuffer_fx[k], rot_vctr_delay_im_fx[k] ) ); // q - 5 + imagBuffer_fx[k] = L_add( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_im_fx[k] ), Mpy_32_32( imagBuffer_fx[k], rot_vctr_delay_re_fx[k] ) ); // q - 5 + realBuffer_fx[k] = cplx_aux_fx; + } + } + } + + timeBuffer_fx += L2 * 5; + timeBuffer_fx += h_cldfb->no_channels - h_cldfb->p_filter_length; + } + + /* update memory */ + if ( samplesToProcess > -1 ) + { + Copy32( buffer_fx + samplesToProcess, h_cldfb->cldfb_state_fx, offset ); + } + else + { + Copy32( buffer_fx + frameSize, h_cldfb->cldfb_state_fx, offset ); + } + + return; +} /*-------------------------------------------------------------------* * cldfbSynthesis() * @@ -666,12 +1189,250 @@ void cldfbSynthesis( return; } +void cldfbSynthesis_ivas_fx( + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ + HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ +) +{ + Word16 i; + Word16 k; + Word16 L2; + Word16 M1; + Word16 M2; + Word16 M41; + Word16 M42; + Word16 Mz; + + Word32 rBuffer_fx[2 * CLDFB_NO_CHANNELS_MAX]; + Word32 iBuffer_fx[2 * CLDFB_NO_CHANNELS_MAX]; + const Word32 *rot_vctr_re_fx; + const Word32 *rot_vctr_im_fx; + const Word32 *rot_vctr_delay_re_fx; + const Word32 *rot_vctr_delay_im_fx; + Word32 rr12_fx, ir12_fx; + Word32 ri12_fx, ii12_fx; + + Word32 *synthesisBuffer_fx, buffer_fx[( CLDFB_NO_CHANNELS_MAX * CLDFB_NO_COL_MAX ) + ( 10 * CLDFB_NO_CHANNELS_MAX )]; + Word32 new_samples_fx[2 * CLDFB_NO_CHANNELS_MAX]; + + Word32 *ptr_time_out_fx; + const Word16 *p_filter; + Word16 p_filter_sf; + + Word32 accu0, accu1, accu2, accu3, accu4; + Word16 no_col = h_cldfb->no_col; + move16(); + + M1 = h_cldfb->no_channels; + L2 = shl( M1, 1 ); + M2 = shr( M1, 1 ); + M41 = shr( M2, 1 ); + M42 = sub( M2, M41 ); + Mz = sub( M1, h_cldfb->bandsToZero ); + + /* only process needed cols */ + IF( samplesToProcess > -1 ) + { + no_col = min( no_col, ( samplesToProcess + h_cldfb->no_channels - 1 ) / h_cldfb->no_channels ); + move16(); + } + + rot_vctr_re_fx = h_cldfb->rot_vec_syn_re_fx; + rot_vctr_im_fx = h_cldfb->rot_vec_syn_im_fx; + + rot_vctr_delay_re_fx = h_cldfb->rot_vec_syn_delay_re_fx; + rot_vctr_delay_im_fx = h_cldfb->rot_vec_syn_delay_im_fx; + + synthesisBuffer_fx = buffer_fx; + Copy32( h_cldfb->cldfb_state_fx, synthesisBuffer_fx + ( M1 * no_col ), h_cldfb->p_filter_length ); + + p_filter = h_cldfb->p_filter_fx; + p_filter_sf = h_cldfb->p_filter_sf; + move16(); + ptr_time_out_fx = timeOut_fx; + + /*synthesisBuffer += M1 * h_cldfb->no_col;*/ + synthesisBuffer_fx += M1 * no_col; + + FOR( k = 0; k < no_col; k++ ) + { + IF( ( (Word16) h_cldfb->prototype == (Word16) CLDFB_PROTOTYPE_5_00MS ) ) + { + /* rotation due to delay*/ + /*if(h_cldfb->ds != M1)*/ + IF( rot_vctr_delay_re_fx != NULL ) + { + FOR( i = 0; i < M1; i++ ) + { + Word32 cplx_aux; + /* delay */ + /*cplxMult(&rBuffer[i], &iBuffer[i], realBuffer[k][i], imagBuffer[k][i], cos((EVS_PI/M1)*(i+0.5)*(-(h_cldfb->ds-M1)*0.5)), + sin((EVS_PI/M1)*(i+0.5)*(-(h_cldfb->ds-M1)*0.5)));*/ + /*cplxMult(&rBuffer[i], &iBuffer[i], realBuffer[k][i], imagBuffer[k][i], rot_vctr_delay_re[i], rot_vctr_delay_im[i]);*/ + /*cplxMult(&realBuffer[k][i], &imagBuffer[k][i], realBuffer[k][i], imagBuffer[k][i], rot_vctr_delay_re[i], rot_vctr_delay_im[i]);*/ + cplx_aux = L_sub( Mpy_32_32( realBuffer_fx[k][i], rot_vctr_delay_re_fx[i] ), Mpy_32_32( imagBuffer_fx[k][i], rot_vctr_delay_im_fx[i] ) ); // Qx + imagBuffer_fx[k][i] = L_add( Mpy_32_32( realBuffer_fx[k][i], rot_vctr_delay_im_fx[i] ), Mpy_32_32( imagBuffer_fx[k][i], rot_vctr_delay_re_fx[i] ) ); + move32(); + realBuffer_fx[k][i] = cplx_aux; + move32(); + /*realBuffer[k][i] = rBuffer[i];*/ + /*imagBuffer[k][i] = iBuffer[i];*/ + } + } + } + FOR( i = Mz; i < M1; i++ ) + { + realBuffer_fx[k][i] = L_deposit_l( 0 ); + move32(); + imagBuffer_fx[k][i] = L_deposit_l( 0 ); + move32(); + } + + FOR( i = 0; i < M2; i++ ) + { + /* pre modulation of DST IV */ + /*cplxMult(&rBuffer[2*i], &rBuffer[2*i+1], realBuffer[k][2*i], realBuffer[k][M1-1-2*i], rot_vctr_re[i], rot_vctr_im[i]);*/ + rBuffer_fx[2 * i] = L_sub( Mpy_32_32( realBuffer_fx[k][2 * i], rot_vctr_re_fx[i] ), Mpy_32_32( realBuffer_fx[k][M1 - 1 - 2 * i], rot_vctr_im_fx[i] ) ); // Qx + move32(); + rBuffer_fx[2 * i + 1] = L_add( Mpy_32_32( realBuffer_fx[k][2 * i], rot_vctr_im_fx[i] ), Mpy_32_32( realBuffer_fx[k][M1 - 1 - 2 * i], rot_vctr_re_fx[i] ) ); // Qx + move32(); + + /* pre modulation of DCT IV */ + /*cplxMult(&iBuffer[2*i], &iBuffer[2*i+1],-imagBuffer[k][2*i], imagBuffer[k][M1-1-2*i], rot_vctr_re[i], rot_vctr_im[i]);*/ + iBuffer_fx[2 * i] = L_sub( Mpy_32_32( ( L_negate( imagBuffer_fx[k][2 * i] ) ), rot_vctr_re_fx[i] ), Mpy_32_32( imagBuffer_fx[k][M1 - 1 - 2 * i], rot_vctr_im_fx[i] ) ); // Qx + move32(); + iBuffer_fx[2 * i + 1] = L_add( Mpy_32_32( ( L_negate( imagBuffer_fx[k][2 * i] ) ), rot_vctr_im_fx[i] ), Mpy_32_32( imagBuffer_fx[k][M1 - 1 - 2 * i], rot_vctr_re_fx[i] ) ); // Qx + move32(); + } + + /* FFT of DST IV */ + fft_cldfb_fx( rBuffer_fx, M2 ); + + /* FFT of DCT IV */ + fft_cldfb_fx( iBuffer_fx, M2 ); + + /* folding */ + FOR( i = 0; i < M41; i++ ) + { + /* post modulation of DST IV */ + rr12_fx = L_sub( Mpy_32_32( rBuffer_fx[M1 - 2 - 2 * i], rot_vctr_re_fx[M2 - 1 - i] ), Mpy_32_32( rBuffer_fx[M1 - 1 - 2 * i], rot_vctr_im_fx[M2 - 1 - i] ) ); // Qx + ri12_fx = L_add( Mpy_32_32( rBuffer_fx[M1 - 2 - 2 * i], rot_vctr_im_fx[M2 - 1 - i] ), Mpy_32_32( rBuffer_fx[M1 - 1 - 2 * i], rot_vctr_re_fx[M2 - 1 - i] ) ); // Qx + + /* post modulation of DCT IV */ + ir12_fx = L_sub( Mpy_32_32( iBuffer_fx[M1 - 2 - 2 * i], rot_vctr_re_fx[M2 - 1 - i] ), Mpy_32_32( iBuffer_fx[M1 - 1 - 2 * i], rot_vctr_im_fx[M2 - 1 - i] ) ); // Qx + ii12_fx = L_add( Mpy_32_32( iBuffer_fx[M1 - 2 - 2 * i], rot_vctr_im_fx[M2 - 1 - i] ), Mpy_32_32( iBuffer_fx[M1 - 1 - 2 * i], rot_vctr_re_fx[M2 - 1 - i] ) ); // Qx + + new_samples_fx[M1 + M2 + 1 + 2 * i] = L_negate( L_add( rr12_fx, ii12_fx ) ); // Qx + move32(); + new_samples_fx[M2 - 2 - 2 * i] = L_negate( L_add( ri12_fx, ir12_fx ) ); // Qx + move32(); + + new_samples_fx[M1 + M2 - 2 - 2 * i] = L_sub( rr12_fx, ii12_fx ); // Qx + move32(); + new_samples_fx[M2 + 1 + 2 * i] = L_sub( ir12_fx, ri12_fx ); // Qx + move32(); + } + + FOR( i = 0; i < M42; i++ ) + { + /* post modulation of DST IV */ + rr12_fx = L_sub( Mpy_32_32( rBuffer_fx[2 * i], rot_vctr_re_fx[i] ), Mpy_32_32( rBuffer_fx[2 * i + 1], rot_vctr_im_fx[i] ) ); // Qx + ri12_fx = L_add( Mpy_32_32( rBuffer_fx[2 * i], rot_vctr_im_fx[i] ), Mpy_32_32( rBuffer_fx[2 * i + 1], rot_vctr_re_fx[i] ) ); // Qx + + /* post modulation of DCT IV */ + ir12_fx = L_sub( Mpy_32_32( iBuffer_fx[2 * i], rot_vctr_re_fx[i] ), Mpy_32_32( iBuffer_fx[2 * i + 1], rot_vctr_im_fx[i] ) ); // Qx + ii12_fx = L_add( Mpy_32_32( iBuffer_fx[2 * i], rot_vctr_im_fx[i] ), Mpy_32_32( iBuffer_fx[2 * i + 1], rot_vctr_re_fx[i] ) ); // Qx + + new_samples_fx[M1 + M2 + 2 * i] = L_add( ri12_fx, ir12_fx ); // Qx + move32(); + new_samples_fx[M2 - 1 - 2 * i] = L_add( rr12_fx, ii12_fx ); // Qx + move32(); + + new_samples_fx[M1 + M2 - 1 - 2 * i] = L_sub( ir12_fx, ri12_fx ); // Qx + move32(); + new_samples_fx[M2 + 2 * i] = L_sub( rr12_fx, ii12_fx ); // Qx + move32(); + } + + /* synthesis prototype filter */ + FOR( i = 0; i < L2; i++ ) + { + accu0 = L_add( synthesisBuffer_fx[0 * L2 + i], Mpy_32_16_1( Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 0 * L2 + i )] ), p_filter_sf ) ); // Qx - 1 + accu1 = L_add( synthesisBuffer_fx[1 * L2 + i], Mpy_32_16_1( Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 1 * L2 + i )] ), p_filter_sf ) ); // Qx - 1 + accu2 = L_add( synthesisBuffer_fx[2 * L2 + i], Mpy_32_16_1( Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 2 * L2 + i )] ), p_filter_sf ) ); // Qx - 1 + accu3 = L_add( synthesisBuffer_fx[3 * L2 + i], Mpy_32_16_1( Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 3 * L2 + i )] ), p_filter_sf ) ); // Qx - 1 + accu4 = L_add( synthesisBuffer_fx[4 * L2 + i], Mpy_32_16_1( Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 4 * L2 + i )] ), p_filter_sf ) ); // Qx - 1 + + synthesisBuffer_fx[0 * L2 + i] = accu0; + move32(); + synthesisBuffer_fx[1 * L2 + i] = accu1; + move32(); + synthesisBuffer_fx[2 * L2 + i] = accu2; + move32(); + synthesisBuffer_fx[3 * L2 + i] = accu3; + move32(); + synthesisBuffer_fx[4 * L2 + i] = accu4; + move32(); + } + + FOR( i = 0; i < M1; i++ ) + { + ptr_time_out_fx[M1 - 1 - i] = synthesisBuffer_fx[4 * L2 + M1 + i]; + move32(); + } + + ptr_time_out_fx += M1; + + synthesisBuffer_fx -= M1; + + set32_fx( synthesisBuffer_fx, 0, M1 ); + } + + /* update memory */ + Copy32( buffer_fx, h_cldfb->cldfb_state_fx, h_cldfb->p_filter_length ); + + return; +} + + /*-------------------------------------------------------------------* * configureClfdb() * * configures a CLDFB handle *--------------------------------------------------------------------*/ +void configureCldfb_splitRenderer( + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ + const Word32 sampling_rate /* i : sampling rate */ +) +{ + h_cldfb->no_col = CLDFB_NO_COL_MAX; + h_cldfb->bandsToZero = 0; + h_cldfb->nab = 0; + + SWITCH( sampling_rate ) + { + case 8000: + h_cldfb->no_channels = 10; + case 16000: + h_cldfb->no_channels = 20; + case 32000: + h_cldfb->no_channels = 40; + case 48000: + h_cldfb->no_channels = 60; + default: + assert( "unsupported Sampling rate for cldfb\n" ); + } + + h_cldfb->p_filter_length = 10 * h_cldfb->no_channels; + cldfb_init_proto_and_twiddles_splitRenderer( h_cldfb ); + + return; +} + void configureCldfb( HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ const int32_t sampling_rate /* i : sampling rate */ @@ -695,6 +1456,48 @@ void configureCldfb( * * open and configures a CLDFB handle *--------------------------------------------------------------------*/ +ivas_error openCldfb_splitRend( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ + CLDFB_TYPE type, /* i : analysis or synthesis */ + const Word32 sampling_rate, /* i : sampling rate */ + CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +) +{ + HANDLE_CLDFB_FILTER_BANK hs; + Word16 buf_len; + + IF( ( hs = (HANDLE_CLDFB_FILTER_BANK) malloc( sizeof( CLDFB_FILTER_BANK ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); + } + + hs->type = type; + hs->prototype = prototype; + + configureCldfb_splitRenderer( hs, sampling_rate ); + hs->memory = NULL; + hs->memory_length = 0; + + IF( type == CLDFB_ANALYSIS ) + { + buf_len = sub( hs->p_filter_length, hs->no_channels ); + } + ELSE + { + buf_len = hs->p_filter_length; + } + + IF( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); + } + set_l( hs->cldfb_state_fx, 0, buf_len ); + hs->Q_cldfb_state = 0; + hs->Q_split = 0; + *h_cldfb = hs; + + return IVAS_ERR_OK; +} ivas_error openCldfb( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ @@ -727,6 +1530,13 @@ ivas_error openCldfb( buf_len = hs->p_filter_length; } + if ( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); + } + set_l( hs->cldfb_state_fx, 0, buf_len ); + hs->Q_cldfb_state = 0; + hs->Q_split = 0; if ( ( hs->cldfb_state = (float *) malloc( buf_len * sizeof( float ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); @@ -739,7 +1549,6 @@ ivas_error openCldfb( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * resampleCldfb() * @@ -877,6 +1686,27 @@ static float GetEnergyCldfb( * Remove handle *--------------------------------------------------------------------*/ +void deleteCldfb_splitRend( + HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ +) +{ + HANDLE_CLDFB_FILTER_BANK hs = *h_cldfb; + + IF( h_cldfb == NULL || *h_cldfb == NULL ) + { + return; + } + + IF( hs->cldfb_state_fx ) + { + free( hs->cldfb_state_fx ); + } + + free( hs ); + *h_cldfb = NULL; + + return; +} void deleteCldfb( HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ ) @@ -892,7 +1722,10 @@ void deleteCldfb( { free( hs->cldfb_state ); } - + if ( hs->cldfb_state_fx ) + { + free( hs->cldfb_state_fx ); + } free( hs ); *h_cldfb = NULL; @@ -905,7 +1738,248 @@ void deleteCldfb( * * Initializes rom pointer *--------------------------------------------------------------------*/ +static void cldfb_init_proto_and_twiddles_splitRenderer( + HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ +) +{ + /*find appropriate set of rotVecs*/ + SWITCH( hs->no_channels ) + { + case 10: + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L10_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L10_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L10_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L10_fx; + + IF( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) + { + hs->ds = 10; + hs->da = 10; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17036; + hs->p_filter_fx = CLDFB80_10_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_10_SCALE_FX; + } + ELSE IF( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + hs->ds = 40; + hs->da = -20; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15388; + hs->p_filter_fx = LDQMF_10_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_10_SCALE_FX; + } + BREAK; + case 16: + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L16_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L16_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L16_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L16_fx; + IF( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) + { + hs->ds = 20; + hs->da = 20; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17051; + hs->p_filter_fx = CLDFB80_16_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_16_SCALE_FX; + } + ELSE IF( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + hs->ds = 80; + hs->da = -40; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15388; + hs->p_filter_fx = LDQMF_16_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_16_SCALE_FX; + } + BREAK; + + case 20: + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L20_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L20_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L20_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L20_fx; + IF( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) + { + hs->ds = 20; + hs->da = 20; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17050; + hs->p_filter_fx = CLDFB80_20_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_20_SCALE_FX; + } + ELSE IF( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + hs->ds = 80; + hs->da = -40; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15390; + hs->p_filter_fx = LDQMF_20_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_20_SCALE_FX; + } + BREAK; + + case 30: + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L30_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L30_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L30_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L30_fx; + IF( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) + { + hs->ds = 30; + hs->da = 30; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17051; + hs->p_filter_fx = CLDFB80_30_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_30_SCALE_FX; + } + ELSE IF( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + hs->ds = 120; + hs->da = -60; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15388; + hs->p_filter_fx = LDQMF_30_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_30_SCALE_FX; + } + BREAK; + + case 32: + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L32_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L32_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L32_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L32_fx; + IF( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) + { + hs->ds = 32; + hs->da = 32; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17050; + hs->p_filter_fx = CLDFB80_32_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_32_SCALE_FX; + } + ELSE IF( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + hs->ds = 160; + hs->da = -80; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15392; + hs->p_filter_fx = LDQMF_32_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_32_SCALE_FX; + } + BREAK; + + case 40: + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L40_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L40_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L40_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L40_fx; + IF( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) + { + hs->ds = 40; + hs->da = 40; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17051; + hs->p_filter_fx = CLDFB80_40_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_40_SCALE_FX; + } + ELSE IF( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + hs->ds = 160; + hs->da = -80; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15391; + hs->p_filter_fx = LDQMF_40_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_40_SCALE_FX; + } + BREAK; + + case 60: + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L60_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L60_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L60_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L60_fx; + IF( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) + { + hs->ds = 60; + hs->da = 60; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17051; + hs->p_filter_fx = CLDFB80_60_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_60_SCALE_FX; + } + ELSE IF( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) + { + hs->ds = 240; + hs->da = -120; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15391; + hs->p_filter_fx = LDQMF_60_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_60_SCALE_FX; + } + BREAK; + } + + return; +} static void cldfb_init_proto_and_twiddles( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ) @@ -918,7 +1992,10 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_im = rot_vec_ana_im_L10; hs->rot_vec_syn_re = rot_vec_syn_re_L10; hs->rot_vec_syn_im = rot_vec_syn_im_L10; - + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L10_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L10_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L10_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L10_fx; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { hs->p_filter = CLDFB80_10; @@ -929,6 +2006,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = NULL; hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17036; + hs->p_filter_fx = CLDFB80_10_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_10_SCALE_FX; } else if ( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) { @@ -940,6 +2025,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = rot_vec_delay_im_LDQMF; hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15388; + hs->p_filter_fx = LDQMF_10_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_10_SCALE_FX; } break; @@ -948,6 +2041,10 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_im = rot_vec_ana_im_L16; hs->rot_vec_syn_re = rot_vec_syn_re_L16; hs->rot_vec_syn_im = rot_vec_syn_im_L16; + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L16_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L16_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L16_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L16_fx; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { hs->p_filter = CLDFB80_16; @@ -958,6 +2055,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = NULL; hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17051; + hs->p_filter_fx = CLDFB80_16_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_16_SCALE_FX; } else if ( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) { @@ -969,6 +2074,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = rot_vec_delay_im_LDQMF; hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15388; + hs->p_filter_fx = LDQMF_16_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_16_SCALE_FX; } break; @@ -977,6 +2090,10 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_im = rot_vec_ana_im_L20; hs->rot_vec_syn_re = rot_vec_syn_re_L20; hs->rot_vec_syn_im = rot_vec_syn_im_L20; + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L20_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L20_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L20_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L20_fx; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { hs->p_filter = CLDFB80_20; @@ -987,6 +2104,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = NULL; hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17050; + hs->p_filter_fx = CLDFB80_20_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_20_SCALE_FX; } else if ( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) { @@ -998,6 +2123,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = rot_vec_delay_im_LDQMF; hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15390; + hs->p_filter_fx = LDQMF_20_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_20_SCALE_FX; } break; @@ -1006,6 +2139,10 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_im = rot_vec_ana_im_L30; hs->rot_vec_syn_re = rot_vec_syn_re_L30; hs->rot_vec_syn_im = rot_vec_syn_im_L30; + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L30_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L30_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L30_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L30_fx; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { hs->p_filter = CLDFB80_30; @@ -1016,6 +2153,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = NULL; hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17051; + hs->p_filter_fx = CLDFB80_30_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_30_SCALE_FX; } else if ( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) { @@ -1027,6 +2172,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = rot_vec_delay_im_LDQMF; hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15388; + hs->p_filter_fx = LDQMF_30_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_30_SCALE_FX; } break; @@ -1035,6 +2188,10 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_im = rot_vec_ana_im_L32; hs->rot_vec_syn_re = rot_vec_syn_re_L32; hs->rot_vec_syn_im = rot_vec_syn_im_L32; + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L32_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L32_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L32_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L32_fx; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { hs->p_filter = CLDFB80_32; @@ -1045,6 +2202,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = NULL; hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17050; + hs->p_filter_fx = CLDFB80_32_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_32_SCALE_FX; } else if ( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) { @@ -1056,6 +2221,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = rot_vec_delay_im_LDQMF; hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15392; + hs->p_filter_fx = LDQMF_32_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_32_SCALE_FX; } break; @@ -1064,6 +2237,10 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_im = rot_vec_ana_im_L40; hs->rot_vec_syn_re = rot_vec_syn_re_L40; hs->rot_vec_syn_im = rot_vec_syn_im_L40; + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L40_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L40_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L40_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L40_fx; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { hs->p_filter = CLDFB80_40; @@ -1074,6 +2251,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = NULL; hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17051; + hs->p_filter_fx = CLDFB80_40_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_40_SCALE_FX; } else if ( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) { @@ -1085,6 +2270,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = rot_vec_delay_im_LDQMF; hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15391; + hs->p_filter_fx = LDQMF_40_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_40_SCALE_FX; } break; @@ -1093,6 +2286,10 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_im = rot_vec_ana_im_L60; hs->rot_vec_syn_re = rot_vec_syn_re_L60; hs->rot_vec_syn_im = rot_vec_syn_im_L60; + hs->rot_vec_ana_re_fx = rot_vec_ana_re_L60_fx; + hs->rot_vec_ana_im_fx = rot_vec_ana_im_L60_fx; + hs->rot_vec_syn_re_fx = rot_vec_syn_re_L60_fx; + hs->rot_vec_syn_im_fx = rot_vec_syn_im_L60_fx; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { hs->p_filter = CLDFB80_60; @@ -1103,6 +2300,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = NULL; hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->p_filter_sf = (Word16) 17051; + hs->p_filter_fx = CLDFB80_60_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = CLDFB80_60_SCALE_FX; } else if ( hs->prototype == CLDFB_PROTOTYPE_5_00MS ) { @@ -1114,6 +2319,14 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_ana_delay_im = rot_vec_delay_im_LDQMF; hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->p_filter_sf = (Word16) 15391; + hs->p_filter_fx = LDQMF_60_fx; + hs->q_scale = Q_CLDFB_SCALE_FX; + hs->scale_fx = LDQMF_60_SCALE_FX; } break; } @@ -1121,7 +2334,6 @@ static void cldfb_init_proto_and_twiddles( return; } - /*-------------------------------------------------------------------* * cldfb_save_memory() * diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 40f843789..8bba8fc3e 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -41,6 +41,154 @@ #include "options.h" /* clang-format off */ +/*----------------------------------------------------------------------------------* + *Q values + *----------------------------------------------------------------------------------*/ + +#define Q1 1 +#define Q2 2 +#define Q3 3 +#define Q4 4 +#define Q5 5 +#define Q6 6 +#define Q7 7 +#define Q8 8 +#define Q9 9 +#define Q10 10 +#define Q11 11 +#define Q12 12 +#define Q13 13 +#define Q14 14 +#define Q15 15 +#define Q16 16 +#define Q17 17 +#define Q18 18 +#define Q19 19 +#define Q20 20 +#define Q21 21 +#define Q22 22 +#define Q23 23 +#define Q24 24 +#define Q25 25 +#define Q26 26 +#define Q27 27 +#define Q28 28 +#define Q29 29 +#define Q30 30 +#define Q31 31 + +/*----------------------------------------------------------------------------------* + * one in Q + *----------------------------------------------------------------------------------*/ + +#define ONE_IN_Q1 2 +#define ONE_IN_Q2 4 +#define ONE_IN_Q3 8 +#define ONE_IN_Q4 16 +#define ONE_IN_Q5 32 +#define ONE_IN_Q6 64 +#define ONE_IN_Q7 128 +#define ONE_IN_Q8 256 +#define ONE_IN_Q9 512 +#define ONE_IN_Q10 1024 +#define ONE_IN_Q11 2048 +#define ONE_IN_Q12 4096 +#define ONE_IN_Q13 8192 +#define ONE_IN_Q14 16384 +#define ONE_IN_Q15 32768 +#define ONE_IN_Q16 65536 +#define ONE_IN_Q17 131072 +#define ONE_IN_Q18 262144 +#define ONE_IN_Q19 524288 +#define ONE_IN_Q20 1048576 +#define ONE_IN_Q21 2097152 +#define ONE_IN_Q22 4194304 +#define ONE_IN_Q23 8388608 +#define ONE_IN_Q24 16777216 +#define ONE_IN_Q25 33554432 +#define ONE_IN_Q26 67108864 +#define ONE_IN_Q27 134217728 +#define ONE_IN_Q28 268435456 +#define ONE_IN_Q29 536870912 +#define ONE_IN_Q30 1073741824 +#define ONE_IN_Q31 0x7fffffff +/*----------------------------------------------------------------------------------* + *Q values + *----------------------------------------------------------------------------------*/ + +#define Q1 1 +#define Q2 2 +#define Q3 3 +#define Q4 4 +#define Q5 5 +#define Q6 6 +#define Q7 7 +#define Q8 8 +#define Q9 9 +#define Q10 10 +#define Q11 11 +#define Q12 12 +#define Q13 13 +#define Q14 14 +#define Q15 15 +#define Q16 16 +#define Q17 17 +#define Q18 18 +#define Q19 19 +#define Q20 20 +#define Q21 21 +#define Q22 22 +#define Q23 23 +#define Q24 24 +#define Q25 25 +#define Q26 26 +#define Q27 27 +#define Q28 28 +#define Q29 29 +#define Q30 30 +#define Q31 31 + + /*----------------------------------------------------------------------------------* + * one in Q + *----------------------------------------------------------------------------------*/ + +#define ONE_IN_Q1 2 +#define ONE_IN_Q2 4 +#define ONE_IN_Q3 8 +#define ONE_IN_Q4 16 +#define ONE_IN_Q5 32 +#define ONE_IN_Q6 64 +#define ONE_IN_Q7 128 +#define ONE_IN_Q8 256 +#define ONE_IN_Q9 512 +#define ONE_IN_Q10 1024 +#define ONE_IN_Q11 2048 +#define ONE_IN_Q12 4096 +#define ONE_IN_Q13 8192 +#define ONE_IN_Q14 16384 +#define ONE_IN_Q15 32768 +#define ONE_IN_Q16 65536 +#define ONE_IN_Q17 131072 +#define ONE_IN_Q18 262144 +#define ONE_IN_Q19 524288 +#define ONE_IN_Q20 1048576 +#define ONE_IN_Q21 2097152 +#define ONE_IN_Q22 4194304 +#define ONE_IN_Q23 8388608 +#define ONE_IN_Q24 16777216 +#define ONE_IN_Q25 33554432 +#define ONE_IN_Q26 67108864 +#define ONE_IN_Q27 134217728 +#define ONE_IN_Q28 268435456 +#define ONE_IN_Q29 536870912 +#define ONE_IN_Q30 1073741824 +#define ONE_IN_Q31 0x7fffffff + +#define MAX_WORD16 32767 +#define ONE_IN_Q62 (Word64)0x4000000000000000 + +#define MAXVAL_WORD32 ( (int32_t) 0x7FFFFFFF ) +#define MINVAL_WORD32 ( (int32_t) 0x80000000 ) /*----------------------------------------------------------------------------------* * General constants @@ -50,8 +198,11 @@ #define MODE2 2 #define EVS_PI 3.14159265358979323846264338327950288f - +#define EVS_PI_FX 1686629713 //Q29 +#define EVS_PI_FX16 (Word16)(0x6488) +#define EVS_PI_BY_2_FX (Word16)(0x3244) #define PI2 ( 2 * EVS_PI ) +#define PI2_FX 1686629713 //Q28 #define RANDOM_INITSEED 21845 /* Seed for random generators */ #ifndef FLT_MIN #define FLT_MIN ( 1.175494351e-38F ) @@ -67,6 +218,7 @@ #define MAX16B_FLT 32767.0f #define MIN16B_FLT ( -32768.0f ) #define PCM16_TO_FLT_FAC 32768.0f +#define PCM16_TO_FLT_FAC_FX 1073741824L //16Q15 #define MDFT_NORM_SCALING ( 1.0f / PCM16_TO_FLT_FAC ) #define MAX_FRAME_COUNTER 200 #define MAX_BITS_PER_FRAME 10240 /* Bits per frame for max. bitrate 512kbps, == IVAS_MAX_BITS_PER_FRAME */ @@ -631,6 +783,7 @@ enum #define CLDFB_NO_COL_MAX_SWITCH_BFI 10 /* CLDFB resampling - max number of CLDFB col. for switching, BFI */ #define CLDFB_OVRLP_MIN_SLOTS 3 /* CLDFB resampling - minimize processing to minimum required for transition frame ACELP->TCX/HQ */ #define INV_CLDFB_BANDWIDTH ( 1.f / 800.f ) +#define INV_CLDFB_BANDWIDTH_FX 2684354 #define L_FILT_2OVER3 12 #define L_FILT_2OVER3_LP 3 @@ -657,6 +810,14 @@ typedef enum #define CLDFB80_40_SCALE 88.304726f #define CLDFB80_60_SCALE 88.028412f +#define CLDFB80_10_SCALE_FX 22603 +#define CLDFB80_16_SCALE_FX 22604 +#define CLDFB80_20_SCALE_FX 22605 +#define CLDFB80_30_SCALE_FX 22588 +#define CLDFB80_32_SCALE_FX 22605 +#define CLDFB80_40_SCALE_FX 22606 +#define CLDFB80_60_SCALE_FX 22535 + #define LDQMF_10_SCALE 84.567841f #define LDQMF_16_SCALE 84.567932f #define LDQMF_20_SCALE 84.567963f @@ -665,6 +826,16 @@ typedef enum #define LDQMF_40_SCALE 84.567986f #define LDQMF_60_SCALE 84.303284f +#define LDQMF_10_SCALE_FX 21649 +#define LDQMF_16_SCALE_FX 21649 +#define LDQMF_20_SCALE_FX 21649 +#define LDQMF_30_SCALE_FX 21632 +#define LDQMF_32_SCALE_FX 21649 +#define LDQMF_40_SCALE_FX 21649 +#define LDQMF_60_SCALE_FX 21581 + +#define Q_CLDFB_SCALE_FX 8 + #define L_FFT 256 /* Spectral analysis - length of the FFT */ #define LOG2_L_FFT 8 /* Spectral analysis - log2 of L_FFT */ @@ -1619,6 +1790,7 @@ typedef enum _DCTTYPE #define INV_PREECHO_SMOOTH_LENP1 ( 1 / ( PREECHO_SMOOTH_LEN + 1.0 ) ); #define EPSILON 0.000000000000001f +#define EPSILON_FX 1 #define MAX_SEGMENT_LENGTH 480 #define NUM_TIME_SWITCHING_BLOCKS 4 diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 55de10146..cfb8f2677 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -39,6 +39,7 @@ #include #include #include "ivas_error.h" +#include "typedef.h" /*----------------------------------------------------------------------------------* * Common API constants @@ -133,12 +134,13 @@ typedef struct _IVAS_ISM_METADATA typedef struct { + int32_t w_fx, x_fx, y_fx, z_fx; /* Q22 */ float w, x, y, z; - } IVAS_QUATERNION; typedef struct { + int32_t x_fx, y_fx, z_fx; float x, y, z; } IVAS_VECTOR3; @@ -349,6 +351,8 @@ typedef struct typedef struct { IVAS_REND_AudioBufferConfig config; + Word32 *data_fx; + Word16 *q_data_fx; float *data; } IVAS_REND_AudioBuffer; diff --git a/lib_com/complex_basop.c b/lib_com/complex_basop.c new file mode 100644 index 000000000..0a41aabaa --- /dev/null +++ b/lib_com/complex_basop.c @@ -0,0 +1,533 @@ +/***************************************************************************** + +* + +* Complex arithmetic operators + +* + +*****************************************************************************/ + + +#include "typedef.h" +#include "basop32.h" +#include "basop_mpy.h" +#include "enh64.h" + +#include "complex_basop.h" +#include "stl.h" + + +#if ( WMOPS ) + +extern BASIC_OP multiCounter[MAXCOUNTERS]; + +extern int currCounter; + +#endif /* if WMOPS */ + + +#ifdef COMPLEX_OPERATOR + +/* ================================ New Complex Basops ========================= */ + +cmplx CL_shr( cmplx inp, Word16 shift_val ) +{ + cmplx out; + out.re = L_shr( inp.re, shift_val ); + out.im = L_shr( inp.im, shift_val ); +#if ( WMOPS ) + multiCounter[currCounter].CL_shr++; + multiCounter[currCounter].L_shr--; + multiCounter[currCounter].L_shr--; +#endif + return out; +} + +cmplx CL_shl( cmplx inp, Word16 shift_val ) +{ + cmplx out; + out.re = L_shl( inp.re, shift_val ); + out.im = L_shl( inp.im, shift_val ); +#if ( WMOPS ) + multiCounter[currCounter].CL_shl++; + multiCounter[currCounter].L_shl--; + multiCounter[currCounter].L_shl--; +#endif + return out; +} + +cmplx CL_add( cmplx inp1, cmplx inp2 ) +{ + cmplx out; + out.re = L_add( inp1.re, inp2.re ); + out.im = L_add( inp1.im, inp2.im ); +#if ( WMOPS ) + multiCounter[currCounter].CL_add++; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].L_add--; +#endif + return out; +} + +cmplx CL_sub( cmplx inp1, cmplx inp2 ) +{ + cmplx out; + out.re = L_sub( inp1.re, inp2.re ); + out.im = L_sub( inp1.im, inp2.im ); +#if ( WMOPS ) + multiCounter[currCounter].CL_sub++; + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].L_sub--; +#endif + return out; +} + +cmplx CL_scale( cmplx x, Word16 y ) +{ + cmplx result; + result.re = Mpy_32_16_r( x.re, y ); + result.im = Mpy_32_16_r( x.im, y ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_r--; + multiCounter[currCounter].Mpy_32_16_r--; + multiCounter[currCounter].CL_scale++; +#endif /* #if (WMOPS) */ + return ( result ); +} + +cmplx CL_dscale( cmplx x, Word16 y1, Word16 y2 ) +{ + cmplx result; + result.re = Mpy_32_16_r( x.re, y1 ); + result.im = Mpy_32_16_r( x.im, y2 ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_r--; + multiCounter[currCounter].Mpy_32_16_r--; + multiCounter[currCounter].CL_dscale++; +#endif /* #if (WMOPS) */ + return ( result ); +} + +cmplx CL_msu_j( cmplx x, cmplx y ) +{ + cmplx result; + result.re = L_add( x.re, y.im ); + result.im = L_sub( x.im, y.re ); +#if ( WMOPS ) + multiCounter[currCounter].CL_msu_j++; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].L_sub--; +#endif + return result; +} + +cmplx CL_mac_j( cmplx x, cmplx y ) +{ + cmplx result; + result.re = L_sub( x.re, y.im ); + result.im = L_add( x.im, y.re ); +#if ( WMOPS ) + multiCounter[currCounter].CL_mac_j++; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].L_sub--; +#endif + return result; +} + +cmplx CL_move( cmplx x ) +{ +#if ( WMOPS ) + multiCounter[currCounter].CL_move++; +#endif + return x; +} + +Word32 CL_Extract_real( cmplx x ) +{ +#if ( WMOPS ) + multiCounter[currCounter].CL_Extract_real++; +#endif + return x.re; +} + +Word32 CL_Extract_imag( cmplx x ) +{ +#if ( WMOPS ) + multiCounter[currCounter].CL_Extract_imag++; +#endif + return x.im; +} + +cmplx CL_form( Word32 re, Word32 im ) +{ + cmplx result; + result.re = re; + result.im = im; +#if ( WMOPS ) + multiCounter[currCounter].CL_form++; +#endif + return result; +} + +cmplx CL_multr_32x16( cmplx input, cmplx_s coeff ) +{ + cmplx result; + result.re = W_round48_L( W_sub_nosat( W_mult_32_16( input.re, coeff.re ), W_mult_32_16( input.im, coeff.im ) ) ); + result.im = W_round48_L( W_add_nosat( W_mult_32_16( input.re, coeff.im ), W_mult_32_16( input.im, coeff.re ) ) ); +#if ( WMOPS ) + multiCounter[currCounter].CL_multr_32x16++; + multiCounter[currCounter].W_mult_32_16--; + multiCounter[currCounter].W_mult_32_16--; + multiCounter[currCounter].W_mult_32_16--; + multiCounter[currCounter].W_mult_32_16--; + multiCounter[currCounter].W_sub_nosat--; + multiCounter[currCounter].W_add_nosat--; + multiCounter[currCounter].W_round48_L--; + multiCounter[currCounter].W_round48_L--; +#endif + return result; +} + +cmplx CL_negate( cmplx x ) +{ + cmplx result; + result.re = L_negate( x.re ); + result.im = L_negate( x.im ); +#if ( WMOPS ) + multiCounter[currCounter].CL_negate++; + multiCounter[currCounter].L_negate--; + multiCounter[currCounter].L_negate--; +#endif + return result; +} + +cmplx CL_conjugate( cmplx x ) +{ + cmplx result; + result.re = x.re; + result.im = L_negate( x.im ); +#if ( WMOPS ) + multiCounter[currCounter].CL_conjugate++; + multiCounter[currCounter].L_negate--; +#endif + return result; +} + + +cmplx CL_mul_j( cmplx input ) +{ + cmplx temp, result; + temp = CL_negate( input ); + result.re = temp.im; + result.im = input.re; +#if ( WMOPS ) + multiCounter[currCounter].CL_mul_j++; + multiCounter[currCounter].CL_negate--; +#endif + return result; +} + +cmplx CL_swap_real_imag( cmplx input ) +{ + cmplx result; + result.re = input.im; + result.im = input.re; +#if ( WMOPS ) + multiCounter[currCounter].CL_swap_real_imag++; +#endif + return result; +} + +cmplx_s C_add( cmplx_s inp1, cmplx_s inp2 ) +{ + cmplx_s out; + out.re = add( inp1.re, inp2.re ); + out.im = add( inp1.im, inp2.im ); + +#if ( WMOPS ) + multiCounter[currCounter].C_add++; + multiCounter[currCounter].add--; + multiCounter[currCounter].add--; +#endif + return out; +} + +cmplx_s C_sub( cmplx_s inp1, cmplx_s inp2 ) +{ + cmplx_s out; + out.re = sub( inp1.re, inp2.re ); + out.im = sub( inp1.im, inp2.im ); + +#if ( WMOPS ) + multiCounter[currCounter].C_sub++; + multiCounter[currCounter].sub--; + multiCounter[currCounter].sub--; +#endif + return out; +} + +cmplx_s C_mul_j( cmplx_s input ) +{ + cmplx_s result; + Word16 temp; + temp = negate( input.im ); + result.re = temp; + result.im = input.re; + +#if ( WMOPS ) + multiCounter[currCounter].C_mul_j++; + multiCounter[currCounter].negate--; +#endif + return result; +} + +cmplx_s C_multr( cmplx_s x, cmplx_s c ) +{ + cmplx_s result; + result.re = round_fx( W_sat_l( W_sub_nosat( W_mult_16_16( x.re, c.re ), W_mult_16_16( x.im, c.im ) ) ) ); + result.im = round_fx( W_sat_l( W_add_nosat( W_mult_16_16( x.im, c.re ), W_mult_16_16( x.re, c.im ) ) ) ); + +#if ( WMOPS ) + multiCounter[currCounter].C_multr++; + multiCounter[currCounter].W_mult_16_16--; + multiCounter[currCounter].W_mult_16_16--; + multiCounter[currCounter].W_mult_16_16--; + multiCounter[currCounter].W_mult_16_16--; + multiCounter[currCounter].W_sub_nosat--; + multiCounter[currCounter].W_add_nosat--; + multiCounter[currCounter].W_sat_l--; + multiCounter[currCounter].W_sat_l--; + multiCounter[currCounter].round--; + multiCounter[currCounter].round--; +#endif + return result; +} + +cmplx_s C_form( Word16 re, Word16 im ) +{ + cmplx_s result; + result.re = re; + result.im = im; +#if ( WMOPS ) + multiCounter[currCounter].C_form++; +#endif + return result; +} + +cmplx C_scale( cmplx_s x, Word16 y ) +{ + cmplx result; + result.re = L_mult( x.re, y ); + result.im = L_mult( x.im, y ); +#if ( WMOPS ) + multiCounter[currCounter].L_mult--; + multiCounter[currCounter].L_mult--; + multiCounter[currCounter].C_scale++; +#endif /* #if (WMOPS) */ + return ( result ); +} + +cmplx_s CL_round32_16( cmplx x ) +{ + cmplx_s result; + result.re = round_fx( x.re ); + result.im = round_fx( x.im ); + +#if ( WMOPS ) + multiCounter[currCounter].CL_round32_16++; + multiCounter[currCounter].round--; + multiCounter[currCounter].round--; +#endif + return result; +} + +cmplx CL_scale_32( cmplx x, Word32 y ) +{ + cmplx result; + result.re = Mpy_32_32_r( x.re, y ); + result.im = Mpy_32_32_r( x.im, y ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32_r--; + multiCounter[currCounter].Mpy_32_32_r--; + multiCounter[currCounter].CL_scale_32++; +#endif /* #if (WMOPS) */ + return ( result ); +} + +cmplx CL_dscale_32( cmplx x, Word32 y1, Word32 y2 ) +{ + cmplx result; + result.re = Mpy_32_32_r( x.re, y1 ); + result.im = Mpy_32_32_r( x.im, y2 ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32_r--; + multiCounter[currCounter].Mpy_32_32_r--; + multiCounter[currCounter].CL_dscale_32++; +#endif /* #if (WMOPS) */ + return ( result ); +} + +cmplx CL_multr_32x32( cmplx x, cmplx y ) +{ + cmplx result; + result.re = W_round64_L( W_sub( W_mult_32_32( x.re, y.re ), W_mult_32_32( x.im, y.im ) ) ); + result.im = W_round64_L( W_add( W_mult_32_32( x.im, y.re ), W_mult_32_32( x.re, y.im ) ) ); + +#if ( WMOPS ) + multiCounter[currCounter].CL_multr_32x32++; + multiCounter[currCounter].W_mult_32_32--; + multiCounter[currCounter].W_mult_32_32--; + multiCounter[currCounter].W_mult_32_32--; + multiCounter[currCounter].W_mult_32_32--; + multiCounter[currCounter].W_round64_L--; + multiCounter[currCounter].W_round64_L--; + multiCounter[currCounter].W_sub--; + multiCounter[currCounter].W_add--; +#endif + return result; +} + +cmplx_s C_mac_r( cmplx x, cmplx_s y, Word16 c ) +{ + cmplx_s result; + cmplx temp = CL_add( x, C_scale( y, c ) ); + result = CL_round32_16( temp ); + +#if ( WMOPS ) + multiCounter[currCounter].C_mac_r++; + multiCounter[currCounter].CL_add--; + multiCounter[currCounter].C_scale--; + multiCounter[currCounter].CL_round32_16--; +#endif + return result; +} + +cmplx_s C_msu_r( cmplx x, cmplx_s y, Word16 c ) +{ + cmplx_s result; + cmplx temp = CL_sub( x, C_scale( y, c ) ); + result = CL_round32_16( temp ); + +#if ( WMOPS ) + multiCounter[currCounter].C_msu_r++; + multiCounter[currCounter].CL_sub--; + multiCounter[currCounter].C_scale--; + multiCounter[currCounter].CL_round32_16--; +#endif + return result; +} + +Word16 C_Extract_real( cmplx_s x ) +{ +#if ( WMOPS ) + multiCounter[currCounter].C_Extract_real++; +#endif + return x.re; +} + +Word16 C_Extract_imag( cmplx_s x ) +{ +#if ( WMOPS ) + multiCounter[currCounter].C_Extract_imag++; +#endif + return x.im; +} + +cmplx_s C_negate( cmplx_s x ) +{ + cmplx_s result; + result.re = negate( x.re ); + result.im = negate( x.im ); +#if ( WMOPS ) + multiCounter[currCounter].C_negate++; + multiCounter[currCounter].negate--; + multiCounter[currCounter].negate--; +#endif + return result; +} + +cmplx_s C_conjugate( cmplx_s x ) +{ + cmplx_s result; + result.re = x.re; + result.im = negate( x.im ); +#if ( WMOPS ) + multiCounter[currCounter].C_conjugate++; + multiCounter[currCounter].negate--; +#endif + return result; +} + +cmplx_s C_shr( cmplx_s inp, Word16 shift_val ) +{ + cmplx_s out; + out.re = shr( inp.re, shift_val ); + out.im = shr( inp.im, shift_val ); +#if ( WMOPS ) + multiCounter[currCounter].C_shr++; + multiCounter[currCounter].shr--; + multiCounter[currCounter].shr--; +#endif + return out; +} + +cmplx_s C_shl( cmplx_s inp, Word16 shift_val ) +{ + cmplx_s out; + out.re = shl( inp.re, shift_val ); + out.im = shl( inp.im, shift_val ); +#if ( WMOPS ) + multiCounter[currCounter].C_shl++; + multiCounter[currCounter].shl--; + multiCounter[currCounter].shl--; +#endif + return out; +} + +cmplx CL_scale_t( cmplx x, Word16 y ) +{ + cmplx result; + result.re = Mpy_32_16_1( x.re, y ); + result.im = Mpy_32_16_1( x.im, y ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].CL_scale++; +#endif + return ( result ); +} + +cmplx CL_dscale_t( cmplx x, Word16 y1, Word16 y2 ) +{ + cmplx result; + result.re = Mpy_32_16_1( x.re, y1 ); + result.im = Mpy_32_16_1( x.im, y2 ); +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].CL_dscale++; +#endif /* #if (WMOPS) */ + return ( result ); +} + +cmplx CL_mult_32x16( cmplx input, cmplx_s coeff ) +{ + cmplx result; + result.re = L_sub( Mpy_32_16_1( input.re, coeff.re ), Mpy_32_16_1( input.im, coeff.im ) ); + result.im = L_add( Mpy_32_16_1( input.re, coeff.im ), Mpy_32_16_1( input.im, coeff.re ) ); +#if ( WMOPS ) + multiCounter[currCounter].CL_multr_32x16++; + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].L_add--; +#endif + return result; +} + +#endif /* #ifdef COMPLEX_OPERATOR */ + +/* end of file */ diff --git a/lib_com/complex_basop.h b/lib_com/complex_basop.h new file mode 100644 index 000000000..1a47c525c --- /dev/null +++ b/lib_com/complex_basop.h @@ -0,0 +1,79 @@ +/***************************************************************************** + +* + +* Complex arithmetic operators + +* + +*****************************************************************************/ +#ifndef _COMPLEX_BASIC_OP_H +#define _COMPLEX_BASIC_OP_H + +#include "typedef.h" +#include "basop32.h" +#include "stl.h" + +#ifdef COMPLEX_OPERATOR + +typedef struct +{ + Word32 re; + Word32 im; +} cmplx; + +typedef struct +{ + Word16 re; + Word16 im; +} cmplx_s; + +/*___________________________________________________________________________ + | | + | Prototypes for complex arithmetic operators | + |___________________________________________________________________________| +*/ + +cmplx CL_shr( cmplx inp, Word16 shift_val ); +cmplx CL_shl( cmplx inp, Word16 shift_val ); +cmplx CL_add( cmplx inp1, cmplx inp2 ); +cmplx CL_sub( cmplx inp1, cmplx inp2 ); +cmplx CL_scale( cmplx x, Word16 y ); +cmplx CL_dscale( cmplx x, Word16 y1, Word16 y2 ); +cmplx CL_msu_j( cmplx x, cmplx y ); +cmplx CL_mac_j( cmplx x, cmplx y ); +cmplx CL_move( cmplx x ); +Word32 CL_Extract_real( cmplx x ); +Word32 CL_Extract_imag( cmplx x ); +cmplx CL_form( Word32 re, Word32 im ); +cmplx CL_multr_32x16( cmplx input, cmplx_s coeff ); +cmplx CL_negate( cmplx x ); +cmplx CL_conjugate( cmplx x ); +cmplx CL_mul_j( cmplx input ); +cmplx CL_swap_real_imag( cmplx input ); +cmplx_s C_add( cmplx_s inp1, cmplx_s inp2 ); +cmplx_s C_sub( cmplx_s inp1, cmplx_s inp2 ); +cmplx_s C_mul_j( cmplx_s input ); +cmplx_s C_multr( cmplx_s x, cmplx_s c ); +cmplx_s C_form( Word16 re, Word16 im ); + +cmplx C_scale( cmplx_s x, Word16 y ); +cmplx_s CL_round32_16( cmplx x ); +cmplx CL_scale_32( cmplx x, Word32 y ); +cmplx CL_dscale_32( cmplx x, Word32 y1, Word32 y2 ); +cmplx CL_multr_32x32( cmplx x, cmplx y ); +cmplx_s C_mac_r( cmplx x, cmplx_s y, Word16 c ); +cmplx_s C_msu_r( cmplx x, cmplx_s y, Word16 c ); +Word16 C_Extract_real( cmplx_s x ); +Word16 C_Extract_imag( cmplx_s x ); +cmplx_s C_negate( cmplx_s x ); +cmplx_s C_conjugate( cmplx_s x ); +cmplx_s C_shr( cmplx_s inp, Word16 shift_val ); +cmplx_s C_shl( cmplx_s inp, Word16 shift_val ); + +cmplx CL_scale_t( cmplx x, Word16 y ); +cmplx CL_dscale_t( cmplx x, Word16 y1, Word16 y2 ); +cmplx CL_mult_32x16( cmplx input, cmplx_s coeff ); +#endif /* #ifdef COMPLEX_OPERATOR */ + +#endif /* ifndef _COMPLEX_BASIC_OP_H */ diff --git a/lib_com/control.c b/lib_com/control.c new file mode 100644 index 000000000..10efb178c --- /dev/null +++ b/lib_com/control.c @@ -0,0 +1,284 @@ +/* + =========================================================================== + File: CONTROL.C v.2.3 - 30.Nov.2009 + =========================================================================== + + ITU-T STL BASIC OPERATORS + + CONTROL FLOW OPERATOR INTERNAL VARIABLE DECLARATIONS + + History: + 07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control + operators for the ITU-T Standard Tool Library as + described in Geneva, 20-30 January 2004 WP 3/16 Q10/16 + TD 11 document and subsequent discussions on the + wp3audio@yahoogroups.com email reflector. + March 06 v2.1 Changed to improve portability. + + ============================================================================ +*/ + +#include "stl.h" + +#ifdef WMOPS +int funcId_where_last_call_to_else_occurred; +long funcid_total_wmops_at_last_call_to_else; +int call_occurred = 1; +#endif + +//#ifdef CONTROL_CODE_OPS + +Flag LT_16( Word16 var1, Word16 var2 ) +{ + Flag F_ret = 0; + + if ( var1 < var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].LT_16++; +#endif + return F_ret; +} + +Flag GT_16( Word16 var1, Word16 var2 ) +{ + Flag F_ret = 0; + + if ( var1 > var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].GT_16++; +#endif + return F_ret; +} + +Flag LE_16( Word16 var1, Word16 var2 ) +{ + Flag F_ret = 0; + + if ( var1 <= var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].LE_16++; +#endif + return F_ret; +} + +Flag GE_16( Word16 var1, Word16 var2 ) +{ + Flag F_ret = 0; + + if ( var1 >= var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].GE_16++; +#endif + return F_ret; +} + +Flag EQ_16( Word16 var1, Word16 var2 ) +{ + Flag F_ret = 0; + + if ( var1 == var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].EQ_16++; +#endif + return F_ret; +} + +Flag NE_16( Word16 var1, Word16 var2 ) +{ + Flag F_ret = 0; + + if ( var1 != var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].NE_16++; +#endif + return F_ret; +} + +Flag LT_32( Word32 L_var1, Word32 L_var2 ) +{ + Flag F_ret = 0; + + if ( L_var1 < L_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].LT_32++; +#endif + return F_ret; +} + +Flag GT_32( Word32 L_var1, Word32 L_var2 ) +{ + Flag F_ret = 0; + + if ( L_var1 > L_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].GT_32++; +#endif + return F_ret; +} + +Flag LE_32( Word32 L_var1, Word32 L_var2 ) +{ + Flag F_ret = 0; + + if ( L_var1 <= L_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].LE_32++; +#endif + return F_ret; +} + +Flag GE_32( Word32 L_var1, Word32 L_var2 ) +{ + Flag F_ret = 0; + + if ( L_var1 >= L_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].GE_32++; +#endif + return F_ret; +} + +Flag EQ_32( Word32 L_var1, Word32 L_var2 ) +{ + Flag F_ret = 0; + + if ( L_var1 == L_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].EQ_32++; +#endif + return F_ret; +} + +Flag NE_32( Word32 L_var1, Word32 L_var2 ) +{ + Flag F_ret = 0; + + if ( L_var1 != L_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].NE_32++; +#endif + return F_ret; +} + +Flag LT_64( Word64 L64_var1, Word64 L64_var2 ) +{ + Flag F_ret = 0; + + if ( L64_var1 < L64_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].LT_64++; +#endif + return F_ret; +} + +Flag GT_64( Word64 L64_var1, Word64 L64_var2 ) +{ + Flag F_ret = 0; + + if ( L64_var1 > L64_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].GT_64++; +#endif + return F_ret; +} + +Flag LE_64( Word64 L64_var1, Word64 L64_var2 ) +{ + Flag F_ret = 0; + + if ( L64_var1 <= L64_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].LE_64++; +#endif + return F_ret; +} +Flag GE_64( Word64 L64_var1, Word64 L64_var2 ) +{ + Flag F_ret = 0; + + if ( L64_var1 >= L64_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].GE_64++; +#endif + return F_ret; +} + +Flag EQ_64( Word64 L64_var1, Word64 L64_var2 ) +{ + Flag F_ret = 0; + + if ( L64_var1 == L64_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].EQ_64++; +#endif + return F_ret; +} +Flag NE_64( Word64 L64_var1, Word64 L64_var2 ) +{ + Flag F_ret = 0; + + if ( L64_var1 != L64_var2 ) + { + F_ret = 1; + } +#if ( WMOPS ) + multiCounter[currCounter].NE_64++; +#endif + return F_ret; +} + +//#endif /* #ifdef CONTROL_CODE_OPS */ + + +/* end of file */ diff --git a/lib_com/control.h b/lib_com/control.h new file mode 100644 index 000000000..f71696560 --- /dev/null +++ b/lib_com/control.h @@ -0,0 +1,365 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _CONTROL_H +#define _CONTROL_H + +#include "stl.h" + +/***************************************************************************** + * + * Constants and Globals + * + *****************************************************************************/ +#if ( WMOPS ) +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; + +/* Technical note : + * The following 3 variables are only used for correct complexity + * evaluation of the following structure : + * IF{ + * ... + * } ELSE IF { + * ... + * } ELSE IF { + * ... + * } + * ... + * } ELSE { + * ... + * } + */ +extern int funcId_where_last_call_to_else_occurred; +extern long funcid_total_wmops_at_last_call_to_else; +extern int call_occurred; +#endif /* ifdef WMOPS */ + + +/***************************************************************************** + * + * Function Macros + * + *****************************************************************************/ + +/***************************************************************************** + * + * Function Name : FOR + * + * Purpose : + * + * The macro FOR should be used instead of the 'for' C statement. + * The complexity is independent of the number of loop iterations that are + * performed. + * + * Complexity weight : 3 (regardless of number of iterations). + * + *****************************************************************************/ +#ifndef WMOPS +#define FOR( a ) for ( a ) + +#else /* ifndef WMOPS */ +#define FOR( a ) \ + if ( incrFor(), 0 ) \ + ; \ + else \ + for ( a ) + +static __inline void incrFor( void ) +{ + multiCounter[currCounter].For++; +} +#endif /* ifndef WMOPS */ + + +/***************************************************************************** + * + * Function Name : WHILE + * + * Purpose : + * + * The macro WHILE should be used instead of the 'while' C statement. + * The complexity is proportional to the number of loop iterations that + * are performed. + * + * Complexity weight : 4 x 'number of loop iterations'. + * + *****************************************************************************/ +#ifndef WMOPS +#define WHILE( a ) while ( a ) + +#else /* ifndef WMOPS */ +#define WHILE( a ) while ( incrWhile(), a ) + +static __inline void incrWhile( void ) +{ + multiCounter[currCounter].While++; +} +#endif /* ifndef WMOPS */ + + +/***************************************************************************** + * + * Function Name : DO + * + * Purpose : + * + * The macro DO should be used instead of the 'do' C statement. + * + * Complexity weight : 0 (complexity counted by WHILE macro). + * + *****************************************************************************/ +#ifndef WMOPS +#define DO do + +#else /* ifndef WMOPS */ +#define DO do + +#endif /* ifndef WMOPS */ + + +/***************************************************************************** + * + * Function Name : IF + * + * Purpose : + * + * The macro IF should : + * + * - not be used when : + * - the 'if' structure does not have any 'else if' nor 'else' statement + * - and it conditions only one DSP basic operations. + * + * - be used instead of the 'if' C statement in every other case : + * - when there is an 'else' or 'else if' statement, + * - or when the 'if' conditions several DSP basic operations, + * - or when the 'if' conditions a function call. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define IF( a ) if ( a ) + +#else /* ifndef WMOPS */ +#define IF( a ) if ( incrIf(), a ) + +static __inline void incrIf( void ) +{ + /* Technical note : + * If the "IF" operator comes just after an "ELSE", its counter + * must not be incremented. + */ + if ( ( currCounter != funcId_where_last_call_to_else_occurred ) || ( TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else ) || ( call_occurred == 1 ) ) + multiCounter[currCounter].If++; + + call_occurred = 0; + funcId_where_last_call_to_else_occurred = MAXCOUNTERS; +} +#endif /* ifndef WMOPS */ + + +/***************************************************************************** + * + * Function Name : ELSE + * + * Purpose : + * + * The macro ELSE should be used instead of the 'else' C statement. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define ELSE else + +#else /* ifndef WMOPS */ +#define ELSE \ + else if ( incrElse(), 0 ); \ + else + +static __inline void incrElse( void ) +{ + multiCounter[currCounter].If++; + + /* We keep track of the funcId of the last function which used ELSE {...} structure. */ + funcId_where_last_call_to_else_occurred = currCounter; + + /* We keep track of the number of WMOPS of this funcId when the ELSE macro was called. */ + funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation(); + + /* call_occurred is set to 0, in order to count the next IF (if necessary) */ + call_occurred = 0; +} +#endif /* ifndef WMOPS */ + + +/***************************************************************************** + * + * Function Name : SWITCH + * + * Purpose : + * + * The macro SWITCH should be used instead of the 'switch' C statement. + * + * Complexity weight : 8 + * + *****************************************************************************/ +#ifndef WMOPS +#define SWITCH( a ) switch ( a ) + +#else /* ifndef WMOPS */ +#define SWITCH( a ) switch ( incrSwitch(), a ) + +static __inline void incrSwitch( void ) +{ + multiCounter[currCounter].Switch++; +} +#endif /* ifndef WMOPS */ + + +/***************************************************************************** + * + * Function Name : CONTINUE + * + * Purpose : + * + * The macro CONTINUE should be used instead of the 'continue' C statement. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define CONTINUE continue + +#else /* ifndef WMOPS */ +#define CONTINUE \ + if ( incrContinue(), 0 ) \ + ; \ + else \ + continue + +static __inline void incrContinue( void ) +{ + multiCounter[currCounter].Continue++; +} +#endif /* ifndef WMOPS */ + + +/***************************************************************************** + * + * Function Name : BREAK + * + * Purpose : + * + * The macro BREAK should be used instead of the 'break' C statement. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define BREAK break + +#else /* ifndef WMOPS */ +#define BREAK \ + if ( incrBreak(), 0 ) \ + ; \ + else \ + break + +static __inline void incrBreak( void ) +{ + multiCounter[currCounter].Break++; +} +#endif /* ifndef WMOPS */ + + +/***************************************************************************** + * + * Function Name : GOTO + * + * Purpose : + * + * The macro GOTO should be used instead of the 'goto' C statement. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define GOTO goto + +#else /* ifndef WMOPS */ +#define GOTO \ + if ( incrGoto(), 0 ) \ + ; \ + else \ + goto + +static __inline void incrGoto( void ) +{ + multiCounter[currCounter].Goto++; +} +#endif /* ifndef WMOPS */ + + +/* + * New control code basops + */ +//#ifdef CONTROL_CODE_OPS + +Flag LT_16( Word16 var1, Word16 var2 ); +Flag GT_16( Word16 var1, Word16 var2 ); +Flag LE_16( Word16 var1, Word16 var2 ); +Flag GE_16( Word16 var1, Word16 var2 ); +Flag EQ_16( Word16 var1, Word16 var2 ); +Flag NE_16( Word16 var1, Word16 var2 ); + +Flag LT_32( Word32 L_var1, Word32 L_var2 ); +Flag GT_32( Word32 L_var1, Word32 L_var2 ); +Flag LE_32( Word32 L_var1, Word32 L_var2 ); +Flag GE_32( Word32 L_var1, Word32 L_var2 ); +Flag EQ_32( Word32 L_var1, Word32 L_var2 ); +Flag NE_32( Word32 L_var1, Word32 L_var2 ); + +Flag LT_64( Word64 L64_var1, Word64 L64_var2 ); +Flag GT_64( Word64 L64_var1, Word64 L64_var2 ); +Flag LE_64( Word64 L64_var1, Word64 L64_var2 ); +Flag GE_64( Word64 L64_var1, Word64 L64_var2 ); +Flag EQ_64( Word64 L64_var1, Word64 L64_var2 ); +Flag NE_64( Word64 L64_var1, Word64 L64_var2 ); + +//#endif /* #ifdef CONTROL_CODE_OPS */ + +#endif /* _CONTROL_H */ + + +/* end of file */ diff --git a/lib_com/count.c b/lib_com/count.c new file mode 100644 index 000000000..ad2430900 --- /dev/null +++ b/lib_com/count.c @@ -0,0 +1,1302 @@ +/* + =========================================================================== + File: COUNT.C v.2.3 - 30.Nov.2009 + =========================================================================== + + ITU-T STL BASIC OPERATORS + + COMPLEXITY EVALUATION FUNCTIONS + + History: + 03 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control + operators for the ITU-T Standard Tool Library as + described in Geneva, 20-30 January 2004 WP 3/16 Q10/16 + TD 11 document and subsequent discussions on the + wp3audio@yahoogroups.com email reflector. + norm_s() weight reduced from 15 to 1. + norm_l() weight reduced from 30 to 1. + L_abs() weight reduced from 2 to 1. + L_add() weight reduced from 2 to 1. + L_negate() weight reduced from 2 to 1. + L_shl() weight reduced from 2 to 1. + L_shr() weight reduced from 2 to 1. + L_sub() weight reduced from 2 to 1. + mac_r() weight reduced from 2 to 1. + msu_r() weight reduced from 2 to 1. + mult_r() weight reduced from 2 to 1. + L_deposit_h() weight reduced from 2 to 1. + L_deposit_l() weight reduced from 2 to 1. + March 06 v2.1 Changed to improve portability. + Dec 06 v2.2 Changed to specify frame rate using setFrameRate() + Adding WMOPS_output_avg() for global average computation + L_mls() weight of 5. + div_l() weight of 32. + i_mult() weight of 3. + ============================================================================ +*/ + + +/***************************************************************************** + * + * This file contains functions for the automatic complexity calculation + * + *****************************************************************************/ + + +#include +#include +#include +#include "stl.h" +#include +#ifdef WMOPS + +#ifdef WMOPS +static double frameRate = FRAME_RATE; /* default value : 10 ms */ +#endif /* ifdef WMOPS */ + +#ifdef WMOPS +/* Global counter variable for calculation of complexity weight */ +/* Some enhancement written by Vail., GJR and M.Mul. during EVS time */ + +BASIC_OP multiCounter[MAXCOUNTERS]; +BASIC_OP glob_multiCounter; +int currCounter = 0; /* Zero equals global counter */ +#endif /* ifdef WMOPS */ + +#ifdef WMOPS +void setFrameRate( int samplingFreq, int frameLength ) +{ + if ( frameLength > 0 ) + { + frameRate = samplingFreq / 1000000.0 / frameLength; + } + return; +} + +#endif /* ifdef WMOPS */ + +#ifdef WMOPS +/* + * Below list is used for displaying the code profiling information in + * the file which name is defined by CODE_PROFILE_FILENAME. + * For further details see generic_WMOPS_output() function. + * Attention, the ordering in this table must be kept in synchronisation + * with the structure definition BASIC_OP. + */ +char *BasicOperationList[] = { + "add", "sub", "abs_s", "shl", "shr", + "extract_h", "extract_l", "mult", "L_mult", "negate", + "round", "L_mac", "L_msu", "L_macNs", "L_msuNs", + "L_add", "L_sub", "L_add_c", "L_sub_c", "L_negate", + "L_shl", "L_shr", "mult_r", "shr_r", "mac_r", + + "msu_r", "L_deposit_h", "L_deposit_l", "L_shr_r", "L_abs", + "L_sat", "norm_s", "div_s", "norm_l", "move16", + "move32", "Logic16", "Logic32", "Test", "s_max", + "s_min", "L_max", "L_min", "L40_max", "L40_min", + "shl_r", "L_shl_r", "L40_shr_r", "L40_shl_r", "norm_L40", + + "L40_shl", "L40_shr", "L40_negate", "L40_add", "L40_sub", + "L40_abs", "L40_mult", "L40_mac", "mac_r40", + "L40_msu", "msu_r40", "Mpy_32_16_ss", "Mpy_32_32_ss", "L_mult0", + "L_mac0", "L_msu0", "lshl", "lshr", "L_lshl", + "L_lshr", "L40_lshl", "L40_lshr", "s_and", "s_or", + + "s_xor", "L_and", "L_or", "L_xor", "rotl", + "rotr", "L_rotl", "L_rotr", "L40_set", "L40_deposit_h", + "L40_deposit_l", "L40_deposit32", "Extract40_H", "Extract40_L", "L_Extract40", + "L40_round", "L_saturate40", "round40", "IF", "GOTO", + "BREAK", "SWITCH", "FOR", "WHILE", "CONTINUE", + + "L_mls", "div_l", "i_mult" + +/* New complex basops */ + +/* New 64 bit basops */ +#ifdef ENH_64_BIT_OPERATOR + , + "move64", "W_add_nosat", "W_sub_nosat", "W_shl", "W_shr", "W_shl_nosat", "W_shr_nosat", "W_mac_32_16", "W_msu_32_16", "W_mult_32_16", "W_mult0_16_16", "W_mac0_16_16", "W_msu0_16_16", "W_mult_16_16", "W_mac_16_16", "W_msu_16_16", "W_shl_sat_l", "W_sat_l", "W_sat_m", "W_deposit32_l", "W_deposit32_h", "W_extract_l", "W_extract_h", "W_round48_L", "W_round32_s", "W_norm", "W_add", "W_sub", "W_neg", "W_abs", "W_mult_32_32", "W_mult0_32_32", "W_lshl", "W_lshr", "W_round64_L" + +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +#ifdef ENH_32_BIT_OPERATOR + , + "Mpy_32_16_1", "Mpy_32_16_r", "Mpy_32_32", "Mpy_32_32_r", "Madd_32_16", "Madd_32_16_r", "Msub_32_16", "Msub_32_16_r", "Madd_32_32", "Madd_32_32_r", "Msub_32_32", "Msub_32_32_r" +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +#ifdef ENH_U_32_BIT_OPERATOR + , + "UL_addNs", "UL_subNs", "UL_Mpy_32_32", "Mpy_32_32_uu", "Mpy_32_16_uu", "norm_ul_float", "UL_deposit_l" +#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ + +#ifdef CONTROL_CODE_OPS + , + "LT_16", "GT_16", "LE_16", "GE_16", "EQ_16", "NE_16", "LT_32", "GT_32", "LE_32", "GE_32", "EQ_32", "NE_32", "LT_64", "GT_64", "LE_64", "GE_64", "EQ_64", "NE_64" +#endif /* #ifdef CONTROL_CODE_OPS */ + +}; +#endif /* ifdef WMOPS */ + + +#ifdef WMOPS +const BASIC_OP op_weight = { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 2, 2, 1, + 1, 1, 1, 2, 1, + + 1, 1, 1, 2, 1, + 1, 1, 18, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 2, 2, 2, 2, 1, + + 1, 1, 1, 1, 1, + 1, 1, 1, 2, + 1, 2, 2, 2, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 3, + 3, 3, 3, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 3, 2, + 2, 6, 3, 3, 2, + + 1, 32, 1 + +/* New complex basops */ +#ifdef COMPLEX_OPERATOR + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1 + + , + 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1 + +#endif /* #ifdef COMPLEX_OPERATOR */ + +#ifdef ENH_64_BIT_OPERATOR + /* Weights of new 64 bit basops */ + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +#ifdef ENH_32_BIT_OPERATOR + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +#ifdef ENH_U_32_BIT_OPERATOR + , + 1, 1, 1, 2, 2, 1, 1 +#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ + +#ifdef CONTROL_CODE_OPS + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef CONTROL_CODE_OPS */ +}; +#endif /* ifdef WMOPS */ + + +Word32 TotalWeightedOperation( void ); +Word32 DeltaWeightedOperation( void ); + + +#ifdef WMOPS +/* Counters for separating counting for different objects */ + +/* FROM_EVS_DEV */ +/** +maxCounter: current number of counters. Each scope initialized with BASOP_sub_start() gets a own counter assigned. +objectName: Name of each counter passed to BASOP_sub_start(). +fwc_corr: +nbTimeObjectIsCalled: number of times a counter (object) is referenced in the current frame. +*/ + +static int maxCounter = 0; +static char *objectName[MAXCOUNTERS + 1]; + +static Word16 fwc_corr[MAXCOUNTERS + 1]; +static long int nbTimeObjectIsCalled[MAXCOUNTERS + 1]; + + +#define NbFuncMax ( 4096 ) + + +/** + funcid: current function call for each counter + bc : best case for each counter and function call + wc : worst case for each counter and function call + nbframe: number of frames for each counter. + glob_bc: global best case self time for each counter for current frame. + glob_wc: global worst case self time for each counter for current frame. + glob_sum_curr: global cummulative time for each counter for current frame. + glob_sum_bc: global best case cummulative time for each counter for current frame. + glob_sum_wc: global worst case cummulative time for each counter for current frame. + + total_wmops: total wmops self time for each counter for current frame. + total_sum: total wmops cummulative time for each counter for current frame. + LastWOper: values used for WMOPS deltas + */ + +static Word32 funcid[MAXCOUNTERS], nbframe[MAXCOUNTERS], nbcalls[MAXCOUNTERS]; +static Word32 glob_bc[MAXCOUNTERS], glob_wc[MAXCOUNTERS], bc[MAXCOUNTERS][NbFuncMax], wc[MAXCOUNTERS][NbFuncMax]; +static float total_wmops[MAXCOUNTERS]; +static Word32 LastWOper[MAXCOUNTERS]; +/* FROM_EVS_DEV */ +static float total_sum[MAXCOUNTERS]; +static Word16 call_tree[MAXCOUNTERS][MAXCOUNTERS]; +static int sum_curr[MAXCOUNTERS + 1]; +static int sum_bc[MAXCOUNTERS + 1]; +static int sum_wc[MAXCOUNTERS + 1]; +static int glob_sum_curr[MAXCOUNTERS + 1]; +static int glob_sum_bc[MAXCOUNTERS + 1]; +static int glob_sum_wc[MAXCOUNTERS + 1]; +#if MAX_CALLERS_SAVED_FRAMES +#define MAX_CALLERS_PRINT 20 +static float callers_frames[MAX_CALLERS_SAVED_FRAMES + 1][MAXCOUNTERS + 1]; +static int callers_frames_nos[MAX_CALLERS_SAVED_FRAMES]; +static float callers_totals[MAX_CALLERS_SAVED_FRAMES]; +#endif + +#endif /* ifdef WMOPS */ + + +#ifdef WMOPS +static char *my_strdup( const char *s ) +{ + /* + * duplicates UNIX function strdup() which is not ANSI standard: + * -- malloc() memory area big enough to hold the string s + * -- copy string into new area + * -- return pointer to new area + * + * returns NULL if either s==NULL or malloc() fails + */ + char *dup; + + if ( s == NULL ) + return NULL; + + /* allocate memory for copy of ID string (including string terminator) */ + /* NOTE: the ID strings will never be deallocated because there is no way to "destroy" a counter that is not longer needed */ + if ( ( dup = (char *) malloc( strlen( s ) + 1 ) ) == NULL ) + return NULL; + + return strcpy( dup, s ); +} +#endif /* ifdef WMOPS */ + + +int getCounterId( char *objectNameArg ) +{ +#if WMOPS + if ( maxCounter >= MAXCOUNTERS - 1 ) + return 0; + objectName[++maxCounter] = my_strdup( objectNameArg ); + return maxCounter; + +#else /* ifdef WMOPS */ + (void) objectNameArg; + return 0; /* Dummy */ + +#endif /* ifdef WMOPS */ +} + + +#if WMOPS +int readCounterId() +{ + return currCounter; +} +#endif /* ifdef WMOPS */ + + +#ifdef WMOPS +char *readCounterIdName() +{ + return objectName[currCounter]; +} +#endif /* ifdef WMOPS */ + +void setCounter( int counterId ) +{ +#if WMOPS + if ( ( counterId > maxCounter ) || ( counterId < 0 ) ) + { + currCounter = 0; + return; + } + currCounter = counterId; + call_occurred = 1; +#else + (void) counterId; +#endif /* ifdef WMOPS */ +} + + +void incrementNbTimeObjectIsCalled( int counterId ) +{ +#if WMOPS + if ( ( counterId > maxCounter ) || ( counterId < 0 ) ) + { + nbTimeObjectIsCalled[0]++; + return; + } + nbTimeObjectIsCalled[counterId]++; +#else + (void) counterId; +#endif /* ifdef WMOPS */ +} + + +#if WMOPS +static Word32 WMOPS_frameStat( void ) +{ + /* calculate the WMOPS seen so far and update the global + per-frame maximum (glob_wc) + */ + Word32 tot; + + tot = TotalWeightedOperation(); + if ( tot > glob_wc[currCounter] ) + { + glob_wc[currCounter] = tot; + } + + if ( tot < glob_bc[currCounter] ) + { + glob_bc[currCounter] = tot; + } + /* check if fwc() was forgotten at end of last frame */ + if ( tot > LastWOper[currCounter] ) + { + if ( !fwc_corr[currCounter] ) + { + fprintf( stderr, + "count: operations counted after last fwc() for '%s'; " + "-> fwc() called\n", + objectName[currCounter] ? objectName[currCounter] : "" ); + } + fwc(); + } + + return tot; +} +#endif /* ifdef WMOPS */ + + +#ifdef WMOPS +static void WMOPS_clearMultiCounter( void ) +{ + Word16 i; + + Word32 *ptr = (Word32 *) &multiCounter[currCounter]; + for ( i = 0; i < (Word16) ( sizeof( multiCounter[currCounter] ) / sizeof( Word32 ) ); i++ ) + { + *ptr++ = 0; + } +} +#endif /* ifdef WMOPS */ + + +void ClearNbTimeObjectsAreCalled() +{ +#if WMOPS + Word16 i; + + for ( i = 0; i < (Word16) ( sizeof( multiCounter[currCounter] ) / sizeof( Word32 ) ); i++ ) + { + nbTimeObjectIsCalled[i] = 0; + } +#endif /* ifdef WMOPS */ +} + +Word32 TotalWeightedOperation() +{ +#if WMOPS + Word16 i; + Word32 tot, *ptr, *ptr2; + + tot = 0; + ptr = (Word32 *) &multiCounter[currCounter]; + ptr2 = (Word32 *) &op_weight; + for ( i = 0; i < (Word16) ( sizeof( multiCounter[currCounter] ) / sizeof( Word32 ) ); i++ ) + { + tot += ( ( *ptr++ ) * ( *ptr2++ ) ); + } + + return ( (Word32) tot ); + +#else /* ifdef WMOPS */ + return 0; /* Dummy */ + +#endif /* ifdef WMOPS */ +} + +Word32 DeltaWeightedOperation() +{ +#if WMOPS + Word32 NewWOper, delta; + + NewWOper = TotalWeightedOperation(); + delta = NewWOper - LastWOper[currCounter]; + LastWOper[currCounter] = NewWOper; + return ( delta ); + +#else /* ifdef WMOPS */ + return 0; /* Dummy */ + +#endif /* ifdef WMOPS */ +} + + +void Init_WMOPS_counter( void ) +{ +#if WMOPS + Word16 i; + + /* reset function weight operation counter variable */ + + for ( i = 0; i < NbFuncMax; i++ ) + wc[currCounter][i] = (Word32) 0; + glob_wc[currCounter] = 0; + nbframe[currCounter] = 0; + total_wmops[currCounter] = 0.0; + for ( i = 0; i < NbFuncMax; i++ ) + { + bc[currCounter][i] = (Word32) MAX_32; + } + glob_bc[currCounter] = MAX_32; + nbcalls[currCounter] = 0; + total_sum[currCounter] = 0.0; + + /* initially clear all counters */ + WMOPS_clearMultiCounter(); + LastWOper[currCounter] = 0; + funcid[currCounter] = 0; + + /* Following line is useful for incrIf(), see control.h */ + call_occurred = 1; + funcId_where_last_call_to_else_occurred = MAXCOUNTERS; + + sum_bc[currCounter] = MAX_32; + sum_wc[currCounter] = 0; + sum_curr[currCounter] = 0; + for ( i = 0; i < MAXCOUNTERS; i++ ) + { + call_tree[currCounter][i] = -1; + } + + glob_sum_curr[currCounter] = 0; + glob_sum_wc[currCounter] = 0; + glob_sum_bc[currCounter] = MAX_32; + +#endif /* ifdef WMOPS */ +} + + +Word32 Reset_WMOPS_counter( void ) +{ +#if WMOPS + Word32 tot = WMOPS_frameStat(); + + /* increase the frame counter --> a frame is counted WHEN IT BEGINS */ + nbframe[currCounter]++; + /* Call counter */ + nbcalls[currCounter] += funcid[currCounter]; + /* add wmops used in last frame to count, then reset counter (in first frame, this is a no-op */ + total_wmops[currCounter] += (float) ( tot * frameRate ); + total_sum[currCounter] += (float) ( ( glob_sum_curr[currCounter] ) * frameRate ); + + /* clear counter before new frame starts */ + WMOPS_clearMultiCounter(); + LastWOper[currCounter] = 0; + funcid[currCounter] = 0; /* new frame, set function id to zero */ + + glob_sum_curr[currCounter] = 0; + sum_curr[currCounter] = 0; + return tot; +#else + return 0; +#endif /* ifdef WMOPS */ +} + + +Word32 fwc( void ) +{ + /* function worst case */ +#if WMOPS + Word32 tot; + + tot = DeltaWeightedOperation(); + if ( tot > wc[currCounter][funcid[currCounter]] ) + wc[currCounter][funcid[currCounter]] = tot; + + if ( tot < bc[currCounter][funcid[currCounter]] ) + bc[currCounter][funcid[currCounter]] = tot; + + funcid[currCounter]++; + + /*make sure that BASOP_frame_update(); is put at the end of the main loop*/ + if ( funcid[currCounter] >= NbFuncMax ) + { + printf( "to many function calls\n" ); + } + assert( funcid[currCounter] < NbFuncMax ); + return ( tot ); +#else + return 0; +#endif /* ifdef WMOPS */ +} + +void WMOPS_output( Word16 dtx_mode ) +{ +#if WMOPS + Word16 i; + Word32 tot, tot_wm, tot_wc; + + /* get operations since last reset (or init), but do not update the counters (except the glob_wc[] maximum) + so output CAN be called in each frame without problems. The frame counter is NOT updated! */ + tot = WMOPS_frameStat(); + tot_wm = (Word32) ( total_wmops[currCounter] + ( (float) tot ) * frameRate ); + + fprintf( stdout, + "%10s:WMOPS=%.3f", objectName[currCounter] ? objectName[currCounter] : "", + ( (float) tot ) * frameRate ); + + if ( nbframe[currCounter] != 0 ) + { + fprintf( stdout, " Average=%.3f", tot_wm / (float) nbframe[currCounter] ); + } + fprintf( stdout, " WorstCase=%.3f", ( (float) glob_wc[currCounter] ) * frameRate ); + + /* Worst worst case printed only when not in DTX mode */ + if ( dtx_mode == 0 ) + { + tot_wc = 0L; + for ( i = 0; i < funcid[currCounter]; i++ ) + tot_wc += wc[currCounter][i]; + fprintf( stdout, " WorstWC=%.3f", ( (float) tot_wc ) * frameRate ); + } + fprintf( stdout, " (%d frames)\n", nbframe[currCounter] ); +#else + (void) dtx_mode; +#endif /* ifdef WMOPS */ +} + +void WMOPS_output_avg( Word16 dtx_mode, Word32 *tot_wm, Word32 *num_frames ) +{ +#if WMOPS + Word16 i; + Word32 tot, tot_wc; + + /* get operations since last reset (or init), but do not update the counters (except the glob_wc[] maximum) + so output CAN be called in each frame without problems. The frame counter is NOT updated! */ + tot = WMOPS_frameStat(); + *tot_wm = (Word32) ( total_wmops[currCounter] + ( (float) tot ) * frameRate ); + *num_frames = nbframe[currCounter]; + + fprintf( stdout, "%10s:WMOPS=%.3f", objectName[currCounter] ? objectName[currCounter] : "", ( (float) tot ) * frameRate ); + + if ( nbframe[currCounter] != 0 ) + { + fprintf( stdout, " Average=%.3f", *tot_wm / (float) nbframe[currCounter] ); + } + fprintf( stdout, " WorstCase=%.3f", ( (float) glob_wc[currCounter] ) * frameRate ); + + /* Worst worst case printed only when not in DTX mode */ + if ( dtx_mode == 0 ) + { + tot_wc = 0L; + for ( i = 0; i < funcid[currCounter]; i++ ) + tot_wc += wc[currCounter][i]; + fprintf( stdout, " WorstWC=%.3f", ( (float) tot_wc ) * frameRate ); + } + fprintf( stdout, " (%d frames)\n", nbframe[currCounter] ); +#else + (void) dtx_mode; + (void) tot_wm; + (void) num_frames; +#endif /* ifdef WMOPS */ +} + +void generic_WMOPS_output( Word16 dtx_mode, char *test_file_name ) +{ +#if WMOPS + int saved_value; + Word16 i; + Word32 tot, tot_wm, tot_wc, *ptr, *ptr2; + Word40 grand_total; + FILE *WMOPS_file; + + saved_value = currCounter; + + /* Count the grand_total WMOPS so that % ratio per function group can be displayed. */ + grand_total = 0; + for ( currCounter = 0; currCounter <= maxCounter; currCounter++ ) + { + tot = WMOPS_frameStat(); + grand_total += tot; + } + + + if ( ( WMOPS_file = fopen( WMOPS_DATA_FILENAME, "a" ) ) != NULL ) + { + + printf( "opened file %s in order to print WMOPS for each function group.\n", WMOPS_DATA_FILENAME ); + + /* Print the file header line. */ + fprintf( WMOPS_file, "Test file name\tFunction Name \tFrame\tNb Times Called\tWMOPS\t%% versus grand total" ); + + if ( nbframe[saved_value] != 0 ) + fprintf( WMOPS_file, "\tAverage" ); + + fprintf( WMOPS_file, "\tWorstCase" ); + + /* Worst worst case printed only when not in DTX mode */ + if ( dtx_mode == 0 ) + fprintf( WMOPS_file, "\tWorstWC" ); + + fprintf( WMOPS_file, "\n" ); + + /* Print the WMOPS for each Function Group by scanning all the function groups with currCounter index. */ + for ( currCounter = 0; currCounter <= maxCounter; currCounter++ ) + { + + fprintf( WMOPS_file, "%s", test_file_name ); + fprintf( WMOPS_file, "\t%s", objectName[currCounter] ? objectName[currCounter] : "" ); + fprintf( WMOPS_file, "\t%d", nbframe[currCounter] ); + + tot = WMOPS_frameStat(); + tot_wm = (Word32) ( total_wmops[currCounter] + ( (float) tot ) * frameRate ); + + fprintf( WMOPS_file, "\t\t%ld", nbTimeObjectIsCalled[currCounter] ); + fprintf( WMOPS_file, "\t%.6f", ( (float) tot ) * frameRate ); + fprintf( WMOPS_file, "\t%.3f", ( (float) tot ) / grand_total * 100 ); + + if ( nbframe[currCounter] != 0 ) + fprintf( WMOPS_file, "\t%.3f", tot_wm / (float) nbframe[currCounter] ); + + fprintf( WMOPS_file, "\t%.3f", ( (float) glob_wc[currCounter] ) * frameRate ); + + /* Worst worst case printed only when not in DTX mode */ + if ( dtx_mode == 0 ) + { + tot_wc = 0L; + for ( i = 0; i < funcid[currCounter]; i++ ) + tot_wc += wc[currCounter][i]; + fprintf( WMOPS_file, "\t%.3f", ( (float) tot_wc ) * frameRate ); + } + fprintf( WMOPS_file, "\n" ); + } + + /* Print the file Grand Total line */ + fprintf( WMOPS_file, "%s", test_file_name ); + fprintf( WMOPS_file, "\tGrand Total" ); + fprintf( WMOPS_file, "\t%d", nbframe[saved_value] ); + fprintf( WMOPS_file, "\t\t%.6f", ( (float) grand_total ) * frameRate ); + fprintf( WMOPS_file, "\t100.000" ); + fprintf( WMOPS_file, "\n" ); + fclose( WMOPS_file ); + } + else + printf( "Can not open file %s for WMOPS editing\n", WMOPS_DATA_FILENAME ); + + + if ( ( WMOPS_file = fopen( WMOPS_TOTAL_FILENAME, "a" ) ) != NULL ) + { + printf( "opened file %s in order to print application's total WMOPS.\n", WMOPS_TOTAL_FILENAME ); + fprintf( WMOPS_file, "%s", test_file_name ); + fprintf( WMOPS_file, "\tframe=%d", nbframe[currCounter] ); + fprintf( WMOPS_file, "\tWMOPS=%.6f", ( (float) grand_total ) * frameRate ); + fprintf( WMOPS_file, "\n" ); + fclose( WMOPS_file ); + } + else + printf( "Can not open file %s for WMOPS editing.\n", WMOPS_TOTAL_FILENAME ); + + + if ( ( WMOPS_file = fopen( CODE_PROFILE_FILENAME, "a" ) ) != NULL ) + { + + printf( "opened file %s in order to print basic operation distribution statistics.\n", CODE_PROFILE_FILENAME ); + + /* Print the file header line. */ + fprintf( WMOPS_file, "Test file name\tBasic Operation Name\tframe\tWMOPS\t\t%% versus grand total\n" ); + + /* Print the WMOPS for each Basic Operation across all the defined */ + /* Function Groups. */ + for ( i = 0; i < (Word16) ( sizeof( op_weight ) / sizeof( Word32 ) ); i++ ) + { + fprintf( WMOPS_file, "%-16s", test_file_name ); + fprintf( WMOPS_file, "\t%s", BasicOperationList[i] ); + fprintf( WMOPS_file, "\t%d", nbframe[0] ); + + tot = 0; + ptr = (Word32 *) &multiCounter[0] + i; + ptr2 = (Word32 *) &op_weight + i; + for ( currCounter = 0; currCounter <= maxCounter; currCounter++ ) + { + tot += ( ( *ptr ) * ( *ptr2 ) ); + ptr += ( sizeof( op_weight ) / sizeof( Word32 ) ); + } + + fprintf( WMOPS_file, "\t%.6f", ( (float) tot ) * frameRate ); + fprintf( WMOPS_file, "\t%.3f", ( (float) tot ) / grand_total * 100 ); + fprintf( WMOPS_file, "\n" ); + } + + /* Print the file Grand Total line */ + fprintf( WMOPS_file, "%s", test_file_name ); + fprintf( WMOPS_file, "\tGrand Total" ); + fprintf( WMOPS_file, "\t%d", nbframe[saved_value] ); + fprintf( WMOPS_file, "\t%.6f", ( (float) grand_total ) * frameRate ); + fprintf( WMOPS_file, "\t100.000" ); + fprintf( WMOPS_file, "\n" ); + fclose( WMOPS_file ); + } + else + printf( "Can not open file %s for basic operations distribution statistic editing\n", CODE_PROFILE_FILENAME ); + + currCounter = saved_value; + +#else + (void) dtx_mode; + (void) test_file_name; +#endif /* ifdef WMOPS */ +} +/* FROM_EVS_DEV */ + +#define MAX_STACK 64 +static int stack[MAX_STACK]; +static int sptr; +static int sum_stack[MAX_STACK]; + +/* jdr 20120117: add FLC similar functions */ +void BASOP_frame_update( void ) +{ +#if WMOPS + int i, current; +#if MAX_CALLERS_SAVED_FRAMES + int k; +#endif + float total = 0.0f; + +#ifdef DEBUG + { + static int sptr_target = -2; + + if ( sptr_target == -2 ) + { + sptr_target = sptr; + } + else + { + if ( sptr_target != sptr ) + { + fprintf( stderr, "BASOP_sub_start/BASOP_sub_end imbalance detected!!!\n" ); + sptr_target = sptr; + } + } + } +#endif + + /* Get current counter */ + current = readCounterId(); + + /* Update global operation counters */ + for ( i = 1; i <= maxCounter; i++ ) + { + int j; + + for ( j = 0; j < (int) ( sizeof( BASIC_OP ) / sizeof( UWord32 ) ); j++ ) + { + ( (UWord32 *) &glob_multiCounter )[j] += ( (UWord32 *) &multiCounter[i] )[j]; + } + } + +#if MAX_CALLERS_SAVED_FRAMES + /* Reset all counters */ + for ( i = 1; i <= maxCounter; i++ ) + { + callers_frames[0][i] = 0.0f; + } +#endif + /* Reset all counters */ + for ( i = 1; i <= maxCounter; i++ ) + { + if ( current != i && funcid[i] > 0 ) + { + setCounter( i ); + + glob_sum_curr[currCounter] += sum_curr[currCounter]; + + if ( glob_sum_curr[currCounter] > glob_sum_wc[currCounter] ) + { + glob_sum_wc[currCounter] = glob_sum_curr[currCounter]; + } + if ( glob_sum_curr[currCounter] < glob_sum_bc[currCounter] ) + { + glob_sum_bc[currCounter] = glob_sum_curr[currCounter]; + } +#if MAX_CALLERS_SAVED_FRAMES + /* Keep a Copy before it is Reset */ + callers_frames[0][currCounter] = (float) Reset_WMOPS_counter(); + total += callers_frames[0][currCounter]; +#else + total += (float) Reset_WMOPS_counter(); +#endif + } + } + +#if MAX_CALLERS_SAVED_FRAMES + /* Keep Callers for this Worst Case Frame */ + /* Select Slot to Use (Slot 0 is the Current) */ + k = 0; + for ( i = k + 1; i < MAX_CALLERS_SAVED_FRAMES; i++ ) + { + /* Is it the Min? */ + if ( callers_totals[i] < callers_totals[k] ) + { /* Yes */ + k = i; + } + } + /* Current Greater than the Min? */ + if ( total > callers_totals[k] ) + { + k += 1; + /* Save Info of Callers */ + for ( i = 1; i <= maxCounter; i++ ) + { + callers_frames[k][i] = callers_frames[0][i]; + } + if ( i < MAXCOUNTERS ) + callers_frames[k][i] = -1; + /* Save Total */ + callers_totals[k - 1] = total; + /* Save Frame Number */ + callers_frames_nos[k - 1] = nbframe[0]; + } +#endif + if ( total < glob_bc[0] ) + { + glob_bc[0] = (Word32) total; + } + if ( total > glob_wc[0] ) + { + glob_wc[0] = (Word32) total; + } + /* Restore current counter */ + setCounter( current ); + + nbframe[0]++; +#endif /* if WMOPS */ +} + +void printStack( char *text, char *Id ) +{ +#if WMOPS + int i; + if ( !Id ) + return; + if ( !strcmp( "*", Id ) || ( !strcmp( Id, objectName[currCounter] ) ) ) + { + printf( "%s %s", text, objectName[currCounter] ); + for ( i = sptr - 1; i > 0; i-- ) + { + printf( " <- %s", objectName[stack[i]] ); + } + printf( "\n" ); + } +#else + printf( "%s %s\n", text, Id ? Id : "(no name)" ); +#endif +} + +void BASOP_push_wmops( const char *label ) +{ +#if WMOPS + int new_flag, prev_counter; + int i, j; + + /* Check if new counter label */ + new_flag = 1; + for ( i = 1; i <= maxCounter; i++ ) + { + if ( strcmp( objectName[i], label ) == 0 ) + { + new_flag = 0; + break; + } + } + + prev_counter = readCounterId(); + + /* Configure new record */ + if ( new_flag ) + { + i = (int) getCounterId( label ); + setCounter( i ); + Init_WMOPS_counter(); + } + else + { + setCounter( i ); + } + + + /* Push current context onto stack */ + if ( currCounter >= 0 ) + { + if ( sptr >= MAX_STACK ) + { + fprintf( stderr, "\r push_wmops(): stack exceeded, try inreasing MAX_STACK\n" ); + exit( -1 ); + } + stack[sptr++] = prev_counter; + + /* Reset accumulated WMOPS */ + sum_stack[sptr] = 0; + + /* update call tree */ + for ( j = 0; j < MAXCOUNTERS; j++ ) + { + if ( call_tree[i][j] == prev_counter ) + { + break; + } + else if ( call_tree[i][j] == -1 ) + { + call_tree[i][j] = (Word16) prev_counter; + break; + } + } + } + + /*wmops[currCounter].start_selfcnt = ops_cnt; + wmops[currCounter].start_cnt = ops_cnt; + nbTimeObjectIsCalled[currCounter]++;*/ + + incrementNbTimeObjectIsCalled( currCounter ); + + sum_curr[currCounter] = 0; + +#ifdef DEBUG_COUNTER + printf( "Entering: %s\n", readCounterIdName() ); +#endif + +#endif /* if WMOPS */ +} + + +Word32 BASOP_pop_wmops( void ) +{ +#if WMOPS + Word32 ops_cnt; + +#ifdef DEBUG_COUNTER + printf( "Exiting: %s\n", readCounterIdName() ); +#endif + + ops_cnt = fwc(); + + /* Get back previous context from stack */ + if ( sptr > 0 ) + { + int prevCounter; + + sum_stack[sptr] += ops_cnt; + prevCounter = currCounter; + setCounter( stack[--sptr] ); + sum_stack[sptr] += sum_stack[sptr + 1]; + sum_curr[prevCounter] += sum_stack[sptr + 1]; + } + else + { + /* current_record = -1; */ + setCounter( 0 ); + } + + if ( sum_curr[currCounter] > sum_wc[currCounter] ) + { + sum_wc[currCounter] = sum_curr[currCounter]; + } + if ( sum_curr[currCounter] < sum_bc[currCounter] ) + { + sum_bc[currCounter] = sum_curr[currCounter]; + } + + return ops_cnt; +#else /* if WMOPS */ + return 0; +#endif /* if WMOPS */ +} + +Word32 BASOP_get_wops( void ) +{ + return BASOP_pop_wmops(); +} + +#define FRAMES_PER_SECOND 50.0 +#define MILLION_CYCLES 1e6 +#define FAC ( FRAMES_PER_SECOND / MILLION_CYCLES ) + +static Word32 prom_cnt = 0; + +void WMOPS_destroy( void ) +{ +#if WMOPS + int i; + + /* release the memory allocated for the objectName array */ + for ( i = 0; i < MAXCOUNTERS + 1; i++ ) + { + if ( NULL != objectName[i] ) + { + free( objectName[i] ); + objectName[i] = NULL; + } + } + + maxCounter = 0; +#endif + + return; +} + + +void WMOPS_output_all( Word16 dtx_mode ) +{ +#if WMOPS + float ops_cnt = 0.0f; + int i; + + char *sfmts = "%-40s %8s %8s %7s %7s\n"; + char *dfmts = "%-40s %8.2f %8.3f %7.3f %7.3f\n"; + char *sfmt = "%-40s %8s %8s %7s %7s %7s %7s %7s\n"; + char *dfmt = "%-40s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; + + fprintf( stderr, "\nProgram Memory Analysis: %12.0f words\n", (float) prom_cnt ); + /*fprintf (stderr, "\nInstruction Type Analysis (for worst case frame):\n\n");*/ + fprintf( stderr, "\nInstruction Type Analysis (for worst case frame number %ld):\n\n", (long int) nbframe[0] ); /* added -- JPA */ + for ( i = 0; i < (int) ( sizeof( BasicOperationList ) / sizeof( char * ) ); i++ ) + { + if ( ( (UWord32 *) &glob_multiCounter )[i] > 0 ) + fprintf( stderr, "\t%16s: %12d\n", BasicOperationList[i], ( (UWord32 *) &glob_multiCounter )[i] ); + } + + fprintf( stderr, "\n\nWeighted MOPS Analysis:\n" ); + fprintf( stderr, "%74s %23s\n", "|------ SELF ------|", "|--- CUMULATIVE ---|" ); + fprintf( stderr, sfmt, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " ); + fprintf( stderr, sfmt, " ------------------------", " ------", "------", "------", "------", "------", "------", "------" ); + for ( i = 1; i <= maxCounter; i++ ) + { + if ( nbcalls[i] > 0 ) + { + fprintf( stderr, dfmt, + objectName[i], + ( nbframe[i] == 0 ) ? 0 : (float) nbcalls[i] / (float) nbframe[0], + ( glob_bc[i] == 0 ) ? 0 : frameRate * (float) glob_bc[i], + ( glob_wc[i] == 0 ) ? 0 : frameRate * (float) glob_wc[i], + ( nbframe[i] == 0 ) ? 0 : (float) total_wmops[i] / (float) nbframe[i], + frameRate * ( glob_sum_bc[i] ), + frameRate * ( glob_sum_wc[i] ), + ( nbframe[i] == 0 ) ? 0 : (float) ( total_sum[i] / (float) nbframe[i] ) ); + /* frameRate*(glob_bc[i]+wmops_children_bc[i]), */ + /* frameRate*(glob_wc[i]+wmops_children_wc[i]), */ + /* (nbframe[i] == 0) ? 0 : (float)((total_wmops[i] + total_wmops_children[i]) /(float)nbframe[i])); */ + } + ops_cnt += total_wmops[i]; + } + + fprintf( stderr, sfmts, " -----------------", " ------", "------", "------", "------" ); + if ( nbframe[i] > 0 ) + { + fprintf( stderr, dfmts, + "total", + (double) nbframe[0], + frameRate * glob_bc[0], + frameRate * glob_wc[0], + ( nbframe[0] == 0 ) ? 0 : ops_cnt / nbframe[0] ); + } + + (void) dtx_mode; + +#if MAX_CALLERS_SAVED_FRAMES + for ( i = 1; i <= MAX_CALLERS_SAVED_FRAMES; i++ ) + { + int j, k, l, m; + const char *frame_rank[] = { "st", "nd", "rd", "th" }; + float current; + + k = 0; + for ( j = k + 1; j < MAX_CALLERS_SAVED_FRAMES; j++ ) + { + /* Is it the Max? */ + if ( callers_totals[j] > callers_totals[k] ) + { /* Yes */ + k = j; + } + } + k += 1; + + fprintf( stderr, "\nActive Callers Report for %i%s Worst Case Frame #: %i\n", + i, i <= 3 ? frame_rank[i - 1] : frame_rank[3], + callers_frames_nos[k - 1] ); + /* Print up to 'MAX_CALLERS_PRINT' Callers */ + current = 0.0f; + for ( l = 0; l < MAX_CALLERS_PRINT; l++ ) + { + /* Find Highest Complexity */ + m = 1; + for ( j = m + 1; j <= maxCounter; j++ ) + { + if ( callers_frames[k][j] < 0 ) + break; + if ( callers_frames[k][j] > callers_frames[k][m] ) + m = j; + } + /* Done ? */ + if ( callers_frames[k][m] == 0 ) + break; + fprintf( stderr, " %-52s %10.3f\n", objectName[m], callers_frames[k][m] * frameRate ); + /* Count it */ + current += callers_frames[k][m]; + /* Mark as Done */ + callers_frames[k][m] = 0.0f; + } + /* Check if All Printed */ + if ( current + 0.001f < callers_totals[k - 1] ) + { + fprintf( stderr, " Only first %i Callers have been Printed!\n", MAX_CALLERS_PRINT ); + fprintf( stderr, " %-52s %10.3f\n", "Total for non Printed", ( callers_totals[k - 1] - current ) * frameRate ); + } + fprintf( stderr, " %-52s %10.3f\n", "Total", callers_totals[k - 1] * frameRate ); + /* Mark as Done */ + callers_totals[k - 1] = 0.0f; + } +#endif + WMOPS_destroy(); + +#endif /* if WMOPS */ +} +void WMOPS_output_all_std( Word16 dtx_mode ) +{ +#if WMOPS + float ops_cnt = 0.0f; + int i; + + char *sfmts = "%-40s %8s %8s %7s %7s\n"; + char *dfmts = "%-40s %8.2f %8.3f %7.3f %7.3f\n"; + char *sfmt = "%-40s %8s %8s %7s %7s %7s %7s %7s\n"; + char *dfmt = "%-40s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; + + fprintf( stdout, "\nProgram Memory Analysis: %12.0f words\n", (float) prom_cnt ); + /*fprintf (stdout, "\nInstruction Type Analysis (for worst case frame):\n\n");*/ + fprintf( stdout, "\nInstruction Type Analysis (for worst case frame number %ld):\n\n", (long int) nbframe[0] ); /* added -- JPA */ + if ( nbframe[0] > 0 ) + { + for ( i = 0; i < (int) ( sizeof( BasicOperationList ) / sizeof( char * ) ); i++ ) + { + if ( ( (UWord32 *) &glob_multiCounter )[i] > 0 ) + fprintf( stdout, "\t%16s: %12d\n", BasicOperationList[i], ( (UWord32 *) &glob_multiCounter )[i] ); + } + } + fprintf( stdout, "\n\nWeighted MOPS Analysis:\n" ); + fprintf( stdout, "%74s %23s\n", "|------ SELF ------|", "|--- CUMULATIVE ---|" ); + fprintf( stdout, sfmt, " routine", "calls/fr", " min ", " max ", " avg ", " min ", " max ", " avg " ); + fprintf( stdout, sfmt, " ------------------------", " ------", "------", "------", "------", "------", "------", "------" ); + for ( i = 1; i <= maxCounter; i++ ) + { + fprintf( stdout, dfmt, + objectName[i], + ( nbframe[i] == 0 ) ? 0 : (float) nbcalls[i] / (float) nbframe[0], + ( glob_bc[i] == MAX_32 ) ? 0 : frameRate * (float) glob_bc[i], + ( glob_wc[i] == 0 ) ? 0 : frameRate * (float) glob_wc[i], + ( nbframe[i] == 0 ) ? 0 : (float) total_wmops[i] / (float) nbframe[i], + frameRate * ( glob_sum_bc[i] ), + frameRate * ( glob_sum_wc[i] ), + ( nbframe[i] == 0 ) ? 0 : (float) ( ( total_sum[i] ) / (float) nbframe[i] ) ); + /* frameRate*(glob_bc[i]+wmops_children_bc[i]), */ + /* frameRate*(glob_wc[i]+wmops_children_wc[i]), */ + /* (nbframe[i] == 0) ? 0 : (float)((total_sum[i]) /(float)nbframe[i])); */ + ops_cnt += total_wmops[i]; + } + + fprintf( stdout, sfmts, " -----------------", " ------", "------", "------", "------" ); + if ( nbframe[0] > 0 ) + { + fprintf( stdout, dfmts, + "total", + (double) nbframe[0], + frameRate * glob_bc[0], + frameRate * glob_wc[0], + ( nbframe[0] == 0 ) ? 0 : ops_cnt / nbframe[0] ); + } + + (void) dtx_mode; + + + WMOPS_destroy(); + +#endif /* if WMOPS */ +} + + +void Reset_all_WMOPS_counter( void ) +{ +#if WMOPS + int i; + int currCounterSave; + + currCounterSave = currCounter; + + for ( i = 2; i <= maxCounter; i++ ) + { + setCounter( i ); + Init_WMOPS_counter(); + objectName[i] = 0; + } + + currCounter = currCounterSave; + maxCounter = 1; +#endif /* if WMOPS */ +} + +/* Returns the total min/max/avg WMOPS values like printed in BASOP_end(). */ +void BASOP_get_total_wmops( double *min, double *max, double *avg ) +{ +#if WMOPS + if ( min != NULL ) + *min = frameRate * glob_bc[0]; + if ( max != NULL ) + *max = frameRate * glob_wc[0]; + if ( avg != NULL ) + { + int i; + double ops_cnt = 0; + for ( i = 1; i <= maxCounter; i++ ) + ops_cnt += total_wmops[i]; + *avg = ( nbframe[0] == 0 ) ? 0 : ops_cnt / nbframe[0]; + } +#endif /* if WMOPS */ +} +#if WMOPS +/* helper functions for matlab version */ +void BASOP_sub_sub_start( char *msg ) +{ + BASOP_sub_start( msg ); +} + +void BASOP_sub_sub_end( void ) +{ + BASOP_sub_end(); +} +#endif +/* end of file */ + +#endif +/* end of file */ diff --git a/lib_com/count.h b/lib_com/count.h new file mode 100644 index 000000000..1274780fa --- /dev/null +++ b/lib_com/count.h @@ -0,0 +1,573 @@ +/* + =========================================================================== + File: COUNT.H v.2.3 - 30.Nov.2009 + =========================================================================== + + ITU-T STL BASIC OPERATORS + + PROTOTYPES & DEFINITION FOR COUNTING OPERATIONS + + History + 09.Aug.1999 V1.0.0 Input to UGST from ETSI AMR (count.h); + + 26.Jan.2000 V1.1.0 Added counter entries for G.723.1's + L_mls(), div_l(), i_mult() [from basop32.c] + + 05.Jul.2000 V1.2.0 Added counter entries for 32bit shiftless + operators L_mult0(), L_mac0(), L_msu0() + + 03 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control + operators for the ITU-T Standard Tool Library as + described in Geneva, 20-30 January 2004 WP 3/16 Q10/16 + TD 11 document and subsequent discussions on the + wp3audio@yahoogroups.com email reflector. + March 06 v2.1 Changed to improve portability. + Dec 06 v2.2 Changed to specify frame rate using setFrameRate() + Adding WMOPS_output_avg() for global average computation + L_mls() weight of 5. + div_l() weight of 32. + i_mult() weight of 3. + ============================================================================ +*/ + + +/****************************************************************************** + * Functions for counting operations. + * + * These functions make it possible to measure the wMOPS of a codec. + * + * All functions in this file, and in other *.h files, update a structure so + * that it will be possible to track how many calls to add(), sub(), L_mult() + * ... was made by the code and to estimate the wMOPS (and MIPS) for a certain + * part of the code. + * + * It is also possible to measure the wMOPS separatly for different parts + * of the codec. + * + * This is done by creating a counter group (getCounterId) for each part of + * the code that one wants a seperate measure for. Before a part of the code + * is executed a call to the "setCounter" function is needed to identify + * which counter group to use. + * + * Currently there is a limit of 255 different counter groups. + * + * In the end of this file, there is a piece of code illustrating how the + * functions can be used. + * + ******************************************************************************/ + + +#ifndef _COUNT_H +#define _COUNT_H "$Id$" + +/*#define WMOPS 1*/ /* <<<- enable or disable WMOPS profiling features here */ + +#define MAXCOUNTERS ( 512 ) +#define MAX_CALLERS_SAVED_FRAMES 5 /* # of Frame for which WMOPS Complexity Details will be saved, 0 = Disabled */ +#ifdef WMOPS + +int getCounterId( char *objectName ); +/* + * Create a counter group, the "objectname" will be used when printing + * statistics for this counter group. + * + * Returns 0 if no more counter groups are available. + */ + + +int readCounterId( void ); +/* + * Returns the current CounterId. + */ + + +void setCounter( int counterId ); +/* + * Defines which counter group to use, default is zero. + */ + + +char *readCounterIdName( void ); +/* + * Returns the current CounterId name. + */ +void printStack( char *text, char *Id ); +/* + * print stack + * text: Any text to print initially + * Id: NULL, if no prints are wanted + * "*", if all prints are wanted (default) + * "pitch_ol" or any other function name + */ + +void incrementNbTimeObjectIsCalled( int counterId ); +/* + * This function enables to increment by 1 a counter + * tracking the number of times the application enters a groups of functions. + * If the counterId is not refering to a defined function counter group, then it is + * the default function group (0) which is impacted. + * + */ + + +void ClearNbTimeObjectsAreCalled( void ); +/* + * This function enables to clear to 0 all the counters enabling to + * track the number of times the application enters any groups of functions. + */ + + +void Init_WMOPS_counter( void ); +/* + * Initiates the current counter group. + */ + + +Word32 Reset_WMOPS_counter( void ); +/* + * Resets the current counter group. + */ + + +void WMOPS_output( Word16 notPrintWorstWorstCase ); +/* + * Prints the statistics to the screen, if the argument is non zero + * the statistics for worst worst case will not be printed. This is typically + * done for dtx frames. + * + */ + +void WMOPS_output_avg( Word16 dtx_mode, Word32 *tot_wm, Word32 *num_frames ); +/* + * same as WMOPS_output + returns the total wmops counter and the number of frames + * to support the computation of global average. + * + */ + + +Word32 fwc( void ); +/* + * worst worst case counter. + * + * This function calculates the worst possible case that can be reached. + * + * This is done by calling this function for each subpart of the calculations + * for a frame. This function then stores the maximum wMOPS for each part. + * + * The WMOPS_output function add together all parts and presents the sum. + */ + +void setFrameRate( int samplingFreq, int frameLength ); +/* + * This function can overwrite the value of the frameRate variable that is + * initialized by the FRAME_RATE constant. + */ + + +#define WMOPS_DATA_FILENAME "wmops_data.txt" +/* + * WMOPS_DATA_FILENAME is the macro defining the name of the file + * where the Weighted Million of Operations per Second (wMOPS) + * are appended, function group by function group. + */ + + +#define CODE_PROFILE_FILENAME "code_profile.txt" +/* + * CODE_PROFILE_FILENAME is the macro defining the name of the file + * where the Weighted Million of Operations per Second (WMOPS) + * are appended, basic operation by basic operation. + */ + + +#define WMOPS_TOTAL_FILENAME "wmops_total.txt" +/* + * WMOPS_TOTAL_FILENAME is the macro defining the name of the file + * where the Weighted Million of Operations per Second (WMOPS) + * are printed, globally for the application. + */ + + +#define FRAME_RATE ( 0.0001F ) /* in this version frame_rate can be overwriten online by the new setFrameRate function */ + /* FRAME_RATE of 0.000025 is corresponding to 40ms frame.*/ + /* FRAME_RATE of 0.00005 is corresponding to 20ms frame.*/ + /* FRAME_RATE of 0.0001 is corresponding to 10ms frame.*/ + /* + * FRAME_RATE is the macro defining the calling rate of the + * application to benchmark. + */ + + +/* Global counter variable for calculation of complexity weight */ +typedef struct +{ + UWord32 add; /* Complexity Weight of 1 */ + UWord32 sub; /* Complexity Weight of 1 */ + UWord32 abs_s; /* Complexity Weight of 1 */ + UWord32 shl; /* Complexity Weight of 1 */ + UWord32 shr; /* Complexity Weight of 1 */ + + UWord32 extract_h; /* Complexity Weight of 1 */ + UWord32 extract_l; /* Complexity Weight of 1 */ + UWord32 mult; /* Complexity Weight of 1 */ + UWord32 L_mult; /* Complexity Weight of 1 */ + UWord32 negate; /* Complexity Weight of 1 */ + + UWord32 round; /* Complexity Weight of 1 */ + UWord32 L_mac; /* Complexity Weight of 1 */ + UWord32 L_msu; /* Complexity Weight of 1 */ + UWord32 L_macNs; /* Complexity Weight of 1 */ + UWord32 L_msuNs; /* Complexity Weight of 1 */ + + UWord32 L_add; /* Complexity Weight of 1 */ + UWord32 L_sub; /* Complexity Weight of 1 */ + UWord32 L_add_c; /* Complexity Weight of 2 */ + UWord32 L_sub_c; /* Complexity Weight of 2 */ + UWord32 L_negate; /* Complexity Weight of 1 */ + + UWord32 L_shl; /* Complexity Weight of 1 */ + UWord32 L_shr; /* Complexity Weight of 1 */ + UWord32 mult_r; /* Complexity Weight of 1 */ + UWord32 shr_r; /* Complexity Weight of 3 */ + UWord32 mac_r; /* Complexity Weight of 1 */ + + UWord32 msu_r; /* Complexity Weight of 1 */ + UWord32 L_deposit_h; /* Complexity Weight of 1 */ + UWord32 L_deposit_l; /* Complexity Weight of 1 */ + UWord32 L_shr_r; /* Complexity Weight of 3 */ + UWord32 L_abs; /* Complexity Weight of 1 */ + + UWord32 L_sat; /* Complexity Weight of 4 */ + UWord32 norm_s; /* Complexity Weight of 1 */ + UWord32 div_s; /* Complexity Weight of 18 */ + UWord32 norm_l; /* Complexity Weight of 1 */ + UWord32 norm_ul; /* Complexity Weight of 1 */ + UWord32 move16; /* Complexity Weight of 1 */ + + UWord32 move32; /* Complexity Weight of 2 */ + UWord32 Logic16; /* Complexity Weight of 1 */ + UWord32 Logic32; /* Complexity Weight of 2 */ + UWord32 Test; /* Complexity Weight of 2 */ + UWord32 s_max; /* Complexity Weight of 1 */ + + UWord32 s_min; /* Complexity Weight of 1 */ + UWord32 L_max; /* Complexity Weight of 1 */ + UWord32 L_min; /* Complexity Weight of 1 */ + UWord32 L40_max; /* Complexity Weight of 1 */ + UWord32 L40_min; /* Complexity Weight of 1 */ + + UWord32 shl_r; /* Complexity Weight of 2 */ + UWord32 L_shl_r; /* Complexity Weight of 2 */ + UWord32 L40_shr_r; /* Complexity Weight of 2 */ + UWord32 L40_shl_r; /* Complexity Weight of 2 */ + UWord32 norm_L40; /* Complexity Weight of 1 */ + + UWord32 L40_shl; /* Complexity Weight of 1 */ + UWord32 L40_shr; /* Complexity Weight of 1 */ + UWord32 L40_negate; /* Complexity Weight of 1 */ + UWord32 L40_add; /* Complexity Weight of 1 */ + UWord32 L40_sub; /* Complexity Weight of 1 */ + + UWord32 L40_abs; /* Complexity Weight of 1 */ + UWord32 L40_mult; /* Complexity Weight of 1 */ + UWord32 L40_mac; /* Complexity Weight of 1 */ + UWord32 mac_r40; /* Complexity Weight of 2 */ + + UWord32 L40_msu; /* Complexity Weight of 1 */ + UWord32 msu_r40; /* Complexity Weight of 2 */ + UWord32 Mpy_32_16_ss; /* Complexity Weight of 2 */ + UWord32 Mpy_32_32_ss; /* Complexity Weight of 2 */ + UWord32 L_mult0; /* Complexity Weight of 1 */ + + UWord32 L_mac0; /* Complexity Weight of 1 */ + UWord32 L_msu0; /* Complexity Weight of 1 */ + UWord32 lshl; /* Complexity Weight of 1 */ + UWord32 lshr; /* Complexity Weight of 1 */ + UWord32 L_lshl; /* Complexity Weight of 1 */ + + UWord32 L_lshr; /* Complexity Weight of 1 */ + UWord32 L40_lshl; /* Complexity Weight of 1 */ + UWord32 L40_lshr; /* Complexity Weight of 1 */ + UWord32 s_and; /* Complexity Weight of 1 */ + UWord32 s_or; /* Complexity Weight of 1 */ + + UWord32 s_xor; /* Complexity Weight of 1 */ + UWord32 L_and; /* Complexity Weight of 1 */ + UWord32 L_or; /* Complexity Weight of 1 */ + UWord32 L_xor; /* Complexity Weight of 1 */ + UWord32 rotl; /* Complexity Weight of 3 */ + + UWord32 rotr; /* Complexity Weight of 3 */ + UWord32 L_rotl; /* Complexity Weight of 3 */ + UWord32 L_rotr; /* Complexity Weight of 3 */ + UWord32 L40_set; /* Complexity Weight of 1 */ + UWord32 L40_deposit_h; /* Complexity Weight of 1 */ + + UWord32 L40_deposit_l; /* Complexity Weight of 1 */ + UWord32 L40_deposit32; /* Complexity Weight of 1 */ + UWord32 Extract40_H; /* Complexity Weight of 1 */ + UWord32 Extract40_L; /* Complexity Weight of 1 */ + UWord32 L_Extract40; /* Complexity Weight of 1 */ + + UWord32 L40_round; /* Complexity Weight of 1 */ + UWord32 L_saturate40; /* Complexity Weight of 1 */ + UWord32 round40; /* Complexity Weight of 1 */ + UWord32 If; /* Complexity Weight of 3 */ + UWord32 Goto; /* Complexity Weight of 2 */ + + UWord32 Break; /* Complexity Weight of 2 */ + UWord32 Switch; /* Complexity Weight of 6 */ + UWord32 For; /* Complexity Weight of 3 */ + UWord32 While; /* Complexity Weight of 3 */ + UWord32 Continue; /* Complexity Weight of 2 */ + + UWord32 L_mls; /* Complexity Weight of 1 */ + UWord32 div_l; /* Complexity Weight of 32 */ + UWord32 i_mult; /* Complexity Weight of 1 */ + + /* New complex basic operators */ +#ifdef COMPLEX_OPERATOR + UWord32 CL_shr; /* Complexity Weight of 1 */ + UWord32 CL_shl; /* Complexity Weight of 1 */ + UWord32 CL_add; /* Complexity Weight of 1 */ + UWord32 CL_sub; /* Complexity Weight of 1 */ + UWord32 CL_scale; /* Complexity Weight of 1 */ + UWord32 CL_dscale; /* Complexity Weight of 1 */ + UWord32 CL_msu_j; /* Complexity Weight of 1 */ + UWord32 CL_mac_j; /* Complexity Weight of 1 */ + UWord32 CL_move; /* Complexity Weight of 1 */ + UWord32 CL_Extract_real; /* Complexity Weight of 1 */ + UWord32 CL_Extract_imag; /* Complexity Weight of 1 */ + UWord32 CL_form; /* Complexity Weight of 1 */ + UWord32 CL_multr_32x16; /* Complexity Weight of 2 */ + UWord32 CL_negate; /* Complexity Weight of 1 */ + UWord32 CL_conjugate; /* Complexity Weight of 1 */ + UWord32 CL_mul_j; /* Complexity Weight of 1 */ + UWord32 CL_swap_real_imag; /* Complexity Weight of 1 */ + UWord32 C_add; /* Complexity Weight of 1 */ + UWord32 C_sub; /* Complexity Weight of 1 */ + UWord32 C_mul_j; /* Complexity Weight of 1 */ + UWord32 C_multr; /* Complexity Weight of 2 */ + UWord32 C_form; /* Complexity Weight of 1 */ + + UWord32 C_scale; /* Complexity Weight of 1 */ + UWord32 CL_round32_16; /* Complexity Weight of 1 */ + UWord32 CL_scale_32; /* Complexity Weight of 1 */ + UWord32 CL_dscale_32; /* Complexity Weight of 1 */ + UWord32 CL_multr_32x32; /* Complexity Weight of 2 */ + UWord32 C_mac_r; /* Complexity Weight of 2 */ + UWord32 C_msu_r; /* Complexity Weight of 2 */ + UWord32 C_Extract_real; /* Complexity Weight of 1 */ + UWord32 C_Extract_imag; /* Complexity Weight of 1 */ + UWord32 C_negate; /* Complexity Weight of 1 */ + UWord32 C_conjugate; /* Complexity Weight of 1 */ + UWord32 C_shr; /* Complexity Weight of 1 */ + UWord32 C_shl; /* Complexity Weight of 1 */ + +#endif /* #ifdef COMPLEX_OPERATOR */ + +/* New 64 bit basops */ +#ifdef ENH_64_BIT_OPERATOR + UWord32 move64; /* Complexity Weight of 1 */ + UWord32 W_add_nosat; /* Complexity Weight of 1 */ + UWord32 W_sub_nosat; /* Complexity Weight of 1 */ + UWord32 W_shl; /* Complexity Weight of 1 */ + UWord32 W_shr; /* Complexity Weight of 1 */ + UWord32 W_shl_nosat; /* Complexity Weight of 1 */ + UWord32 W_shr_nosat; /* Complexity Weight of 1 */ + UWord32 W_mac_32_16; /* Complexity Weight of 1 */ + UWord32 W_msu_32_16; /* Complexity Weight of 1 */ + UWord32 W_mult_32_16; /* Complexity Weight of 1 */ + UWord32 W_mult0_16_16; /* Complexity Weight of 1 */ + UWord32 W_mac0_16_16; /* Complexity Weight of 1 */ + UWord32 W_msu0_16_16; /* Complexity Weight of 1 */ + UWord32 W_mult_16_16; /* Complexity Weight of 1 */ + UWord32 W_mac_16_16; /* Complexity Weight of 1 */ + UWord32 W_msu_16_16; /* Complexity Weight of 1 */ + UWord32 W_shl_sat_l; /* Complexity Weight of 1 */ + UWord32 W_sat_l; /* Complexity Weight of 1 */ + UWord32 W_sat_m; /* Complexity Weight of 1 */ + UWord32 W_deposit32_l; /* Complexity Weight of 1 */ + UWord32 W_deposit32_h; /* Complexity Weight of 1 */ + UWord32 W_extract_l; /* Complexity Weight of 1 */ + UWord32 W_extract_h; /* Complexity Weight of 1 */ + UWord32 W_round48_L; /* Complexity Weight of 1 */ + UWord32 W_round32_s; /* Complexity Weight of 1 */ + UWord32 W_norm; /* Complexity Weight of 1 */ + + UWord32 W_add; /* Complexity Weight of 1 */ + UWord32 W_sub; /* Complexity Weight of 1 */ + UWord32 W_neg; /* Complexity Weight of 1 */ + UWord32 W_abs; /* Complexity Weight of 1 */ + UWord32 W_mult_32_32; /* Complexity Weight of 1 */ + UWord32 W_mult0_32_32; /* Complexity Weight of 1 */ + UWord32 W_lshl; /* Complexity Weight of 1 */ + UWord32 W_lshr; /* Complexity Weight of 1 */ + UWord32 W_round64_L; /* Complexity Weight of 1 */ + +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +#ifdef ENH_32_BIT_OPERATOR + UWord32 Mpy_32_16_1; /* Complexity Weight of 1 */ + UWord32 Mpy_32_16_r; /* Complexity Weight of 1 */ + UWord32 Mpy_32_32; /* Complexity Weight of 1 */ + UWord32 Mpy_32_32_r; /* Complexity Weight of 1 */ + UWord32 Madd_32_16; /* Complexity Weight of 1 */ + UWord32 Madd_32_16_r; /* Complexity Weight of 1 */ + UWord32 Msub_32_16; /* Complexity Weight of 1 */ + UWord32 Msub_32_16_r; /* Complexity Weight of 1 */ + UWord32 Madd_32_32; /* Complexity Weight of 1 */ + UWord32 Madd_32_32_r; /* Complexity Weight of 1 */ + UWord32 Msub_32_32; /* Complexity Weight of 1 */ + UWord32 Msub_32_32_r; /* Complexity Weight of 1 */ +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +#ifdef ENH_U_32_BIT_OPERATOR + UWord32 UL_addNs; /* Complexity Weight of 1 */ + UWord32 UL_subNs; /* Complexity Weight of 1 */ + UWord32 UL_Mpy_32_32; /* Complexity Weight of 1 */ + UWord32 Mpy_32_32_uu; /* Complexity Weight of 2 */ + UWord32 Mpy_32_16_uu; /* Complexity Weight of 2 */ + UWord32 norm_ul_float; /* Complexity Weight of 1 */ + UWord32 UL_deposit_l; /* Complexity Weight of 1 */ +#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ + +#ifdef CONTROL_CODE_OPS + UWord32 LT_16; /* Complexity Weight of 1 */ + UWord32 GT_16; /* Complexity Weight of 1 */ + UWord32 LE_16; /* Complexity Weight of 1 */ + UWord32 GE_16; /* Complexity Weight of 1 */ + UWord32 EQ_16; /* Complexity Weight of 1 */ + UWord32 NE_16; /* Complexity Weight of 1 */ + UWord32 LT_32; /* Complexity Weight of 1 */ + UWord32 GT_32; /* Complexity Weight of 1 */ + UWord32 LE_32; /* Complexity Weight of 1 */ + UWord32 GE_32; /* Complexity Weight of 1 */ + UWord32 EQ_32; /* Complexity Weight of 1 */ + UWord32 NE_32; /* Complexity Weight of 1 */ + UWord32 LT_64; /* Complexity Weight of 1 */ + UWord32 GT_64; /* Complexity Weight of 1 */ + UWord32 LE_64; /* Complexity Weight of 1 */ + UWord32 GE_64; /* Complexity Weight of 1 */ + UWord32 EQ_64; /* Complexity Weight of 1 */ + UWord32 NE_64; /* Complexity Weight of 1 */ + +#endif /* #ifdef CONTROL_CODE_OPS */ +} BASIC_OP; + + +Word32 TotalWeightedOperation( void ); +Word32 DeltaWeightedOperation( void ); + + +void generic_WMOPS_output( Word16 notPrintWorstWorstCase, char *test_file_name ); +/* + * This function enable to append : + * - to WMOPS_DATA_FILENAME file, the WMOPS information related + * to the execution of the application, function group by function + * group. + * - to CODE_PROFILE_FILENAME file, the WMOPS information related + * to the execution of the application, basic operation by basic + * operation. + * - to WMOPS_TOTAL_FILENAME file, the total WMOPS information related + * to the execution of the application. + * + * Note that : + * if the files exists, the data will be written at the end of file. + * + * test_file_name : Is a character string referencing each calls to + * generic_WMOPS_output(). Usually, it is the name of a test + * sequence file. + * + * notPrintWorstWorstCase : Same usage as in WMOPS_output(). + */ +void WMOPS_output_all( Word16 dtx_mode ); +void WMOPS_output_all_std( Word16 dtx_mode ); + +/* + * free all allocated counter memory + */ +void WMOPS_destroy( void ); + +/* jdr 20120117: add FLC similar functions */ +/* mul 20130729: set BASOP_COUNT_SUBROUTINES to count on a per-BASOP_sub_start()/BASOP_sub_end() base; + otherwise, count only between BASOP_push_wmops(), BASOP_push_wmops() */ +#define BASOP_COUNT_SUBROUTINES +void BASOP_push_wmops( const char *label ); +Word32 BASOP_pop_wmops( void ); + +#define BASOP_init \ + { \ + setFrameRate( 32000, 640 ); \ + Init_WMOPS_counter(); /* 20ms frames */ \ + } +#define BASOP_end \ + { \ + WMOPS_output_all_std( 0 ); \ + } +/*#define BASOP_end { WMOPS_output_all(0); }*/ +#define BASOP_end_noprint \ + { \ + WMOPS_destroy(); \ + } + +#ifdef BASOP_COUNT_SUBROUTINES +#define BASOP_sub_start( label ) \ + { \ + BASOP_push_wmops( label ); \ + } +#define BASOP_sub_end() \ + { \ + BASOP_pop_wmops(); \ + } +void BASOP_sub_sub_start( char *msg ); +void BASOP_sub_sub_end( void ); +#else +#define BASOP_sub_start( label ) +#define BASOP_sub_end() +#endif + +void BASOP_frame_update( void ); +void Reset_all_WMOPS_counter( void ); + +Word32 BASOP_get_wops( void ); + +/*! Returns the total min/max/avg WMOPS values like printed in BASOP_end(). */ +void BASOP_get_total_wmops( double *min, double *max, double *avg ); + + +#define SUB_WMOPS_INIT( label ) BASOP_sub_start( label ) +#define END_SUB_WMOPS BASOP_sub_end() + + +#if !defined WMOPS_FL //&& defined WMOPS +#include +#define reset_wmops() BASOP_init +// extern int cntr_push_pop; +#define push_wmops( x ) \ + { \ + BASOP_push_wmops( x ); \ + } +#define pop_wmops() \ + { \ + BASOP_pop_wmops(); \ + } +#define update_wmops() \ + { \ + BASOP_frame_update(); \ + } +#define print_wmops() \ + { \ + WMOPS_output_all_std( 0 ); \ + } +#define update_mem() ; +#endif + + +#endif /* _COUNT_H */ + + +/* end of file */ + +#endif +/* end of file */ diff --git a/lib_com/enh1632.h b/lib_com/enh1632.h index 8e943d42f..c3a0d5c41 100644 --- a/lib_com/enh1632.h +++ b/lib_com/enh1632.h @@ -68,6 +68,13 @@ #include "stl.h" +#if ( WMOPS ) +#include "count.h" +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif /* ifdef WMOPS */ + + /***************************************************************************** * * Prototypes for enhanced 16/32 bit arithmetic operators diff --git a/lib_com/enh32.c b/lib_com/enh32.c new file mode 100644 index 000000000..593256da8 --- /dev/null +++ b/lib_com/enh32.c @@ -0,0 +1,231 @@ +/***************************************************************************** + * + * Enhanced 32 bit operators : + * + * Mpy_32_16_1() + * Mpy_32_16_r() + * Mpy_32_32() + * Mpy_32_32_r() + * Madd_32_16() + * Msub_32_16() + * Madd_32_32() + * Msub_32_32() + * + *****************************************************************************/ + + +/***************************************************************************** + * + * Include-Files + * + *****************************************************************************/ +#include +#include +#include "enh32.h" +#include "enh64.h" +#include "basop_mpy.h" +#if ( WMOPS ) +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif /* if WMOPS */ + +#ifdef ENH_32_BIT_OPERATOR +/***************************************************************************** + * + * Local Functions + * + *****************************************************************************/ + +/***************************************************************************** + * + * Constants and Globals + * + *****************************************************************************/ + + +/***************************************************************************** + * + * Functions + * + *****************************************************************************/ + +// static Word32 Mpy_32_16_1 (Word32 L_var1, Word16 var2) { +// Word32 L_var_out = W_sat_m (W_mult_32_16 (L_var1, var2) ); +//#if (WMOPS) +// multiCounter[currCounter].Mpy_32_16_1++; +// multiCounter[currCounter].W_mult_32_16--; +// multiCounter[currCounter].W_sat_m--; +//#endif /* if WMOPS */ +// return L_var_out; +// } +// +// static Word32 Mpy_32_16_r (Word32 L_var1, Word16 var2) { +// Word32 L_var_out = W_round48_L (W_mult_32_16 (L_var1, var2 ) ); +//#if (WMOPS) +// multiCounter[currCounter].Mpy_32_16_r++; +// multiCounter[currCounter].W_mult_32_16--; +// multiCounter[currCounter].W_round48_L--; +//#endif /* if WMOPS */ +// return L_var_out; +// } +// +// static Word32 Mpy_32_32 (Word32 L_var1, Word32 L_var2) { +// Word32 L_var_out; +// Word64 L64_var1; +//#ifdef BASOP_NOGLOB_DECLARE_LOCAL +// Flag Overflow = 0; +//#endif +// +// L64_var1 = ((Word64)L_var1 * L_var2); +//#ifdef BASOP_NOGLOB +// L64_var1 = W_shl_o (L64_var1, 1, &Overflow); +//#else /* BASOP_NOGLOB */ +// L64_var1 = W_shl (L64_var1, 1); +//#endif /* BASOP_NOGLOB */ +// L_var_out = W_extract_h (L64_var1 ); +//#if (WMOPS) +// multiCounter[currCounter].Mpy_32_32++; +// multiCounter[currCounter].W_shl--; +// multiCounter[currCounter].W_extract_h--; +//#endif /* if WMOPS */ +// return L_var_out; +// } +// + +Word32 Madd_32_16( Word32 L_var3, Word32 L_var1, Word16 var2 ) +{ + Word32 L_var_out; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + L_var_out = Mpy_32_16_1( L_var1, var2 ); +#ifdef BASOP_NOGLOB + L_var_out = L_add_o( L_var3, L_var_out, &Overflow ); +#else /* BASOP_NOGLOB */ + L_var_out = L_add( L_var3, L_var_out ); +#endif /* BASOP_NOGLOB */ + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].Madd_32_16++; +#endif /* if WMOPS */ + return L_var_out; +} + +Word32 Madd_32_16_r( Word32 L_var3, Word32 L_var1, Word16 var2 ) +{ + Word32 L_var_out; + + L_var_out = Mpy_32_16_r( L_var1, var2 ); + L_var_out = L_add( L_var3, L_var_out ); + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_r--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].Madd_32_16_r++; +#endif /* if WMOPS */ + return L_var_out; +} + +Word32 Msub_32_16( Word32 L_var3, Word32 L_var1, Word16 var2 ) +{ + Word32 L_var_out; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + L_var_out = Mpy_32_16_1( L_var1, var2 ); +#ifdef BASOP_NOGLOB + L_var_out = L_sub_o( L_var3, L_var_out, &Overflow ); +#else /* BASOP_NOGLOB */ + L_var_out = L_sub( L_var3, L_var_out ); +#endif + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_1--; + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].Msub_32_16++; +#endif /* if WMOPS */ + return L_var_out; +} + +Word32 Msub_32_16_r( Word32 L_var3, Word32 L_var1, Word16 var2 ) +{ + Word32 L_var_out; + + L_var_out = Mpy_32_16_r( L_var1, var2 ); + L_var_out = L_sub( L_var3, L_var_out ); + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_r--; + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].Msub_32_16_r++; +#endif /* if WMOPS */ + return L_var_out; +} + +Word32 Madd_32_32( Word32 L_var3, Word32 L_var1, Word32 L_var2 ) +{ + Word32 L_var_out; + + L_var_out = Mpy_32_32( L_var1, L_var2 ); + L_var_out = L_add( L_var3, L_var_out ); + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].Madd_32_32++; +#endif /* if WMOPS */ + return L_var_out; +} + +Word32 Madd_32_32_r( Word32 L_var3, Word32 L_var1, Word32 L_var2 ) +{ + Word32 L_var_out; + + L_var_out = Mpy_32_32_r( L_var1, L_var2 ); + L_var_out = L_add( L_var3, L_var_out ); + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32_r--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].Madd_32_32_r++; +#endif /* if WMOPS */ + return L_var_out; +} + +Word32 Msub_32_32( Word32 L_var3, Word32 L_var1, Word32 L_var2 ) +{ + Word32 L_var_out; + + L_var_out = Mpy_32_32( L_var1, L_var2 ); + L_var_out = L_sub( L_var3, L_var_out ); + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32--; + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].Msub_32_32++; +#endif /* if WMOPS */ + return L_var_out; +} + +Word32 Msub_32_32_r( Word32 L_var3, Word32 L_var1, Word32 L_var2 ) +{ + Word32 L_var_out; + + L_var_out = Mpy_32_32_r( L_var1, L_var2 ); + L_var_out = L_sub( L_var3, L_var_out ); + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32_r--; + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].Msub_32_32_r++; +#endif /* if WMOPS */ + return L_var_out; +} + +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +/* end of file */ diff --git a/lib_com/enh32.h b/lib_com/enh32.h new file mode 100644 index 000000000..df5a3b252 --- /dev/null +++ b/lib_com/enh32.h @@ -0,0 +1,36 @@ + +#ifndef _ENH32_H +#define _ENH32_H + +#include "stl.h" + +#ifndef Word64 +#define Word64 long long int +#endif + +/***************************************************************************** + * + * Prototypes for enhanced 32 bit arithmetic operators + * + *****************************************************************************/ +#ifdef ENH_32_BIT_OPERATOR + +// Word32 Mpy_32_16_1 (Word32 L_var1, Word16 var2); +// Word32 Mpy_32_16_r (Word32 L_var1, Word16 var2); +// Word32 Mpy_32_32 (Word32 L_var1, Word32 L_var2); +// Word32 Mpy_32_32_r (Word32 L_var1, Word32 L_var2); +Word32 Madd_32_16( Word32 L_var3, Word32 L_var1, Word16 var2 ); +Word32 Madd_32_16_r( Word32 L_var3, Word32 L_var1, Word16 var2 ); +Word32 Msub_32_16( Word32 L_var3, Word32 L_var1, Word16 var2 ); +Word32 Msub_32_16_r( Word32 L_var3, Word32 L_var1, Word16 var2 ); +Word32 Madd_32_32( Word32 L_var3, Word32 L_var1, Word32 L_var2 ); +Word32 Madd_32_32_r( Word32 L_var3, Word32 L_var1, Word32 L_var2 ); +Word32 Msub_32_32( Word32 L_var3, Word32 L_var1, Word32 L_var2 ); +Word32 Msub_32_32_r( Word32 L_var3, Word32 L_var1, Word32 L_var2 ); + +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +#endif /*_ENH32_H*/ + + +/* end of file */ diff --git a/lib_com/enh64.c b/lib_com/enh64.c new file mode 100644 index 000000000..f0b804076 --- /dev/null +++ b/lib_com/enh64.c @@ -0,0 +1,1866 @@ +/***************************************************************************** + * + * Enhanced 64 bit operators : + * + * W_mac_32_16() + * W_mac0_16_16() + * W_msu0_16_16() + * + *****************************************************************************/ + + +/***************************************************************************** + * + * Include-Files + * + *****************************************************************************/ +#include +#include +#include "enh64.h" + +#if ( WMOPS ) +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif /* if WMOPS */ + + +/***************************************************************************** + * + * Local Functions + * + *****************************************************************************/ + +/***************************************************************************** + * + * Constants and Globals + * + *****************************************************************************/ + + +/***************************************************************************** + * + * Functions + * + *****************************************************************************/ + +#ifdef ENH_64_BIT_OPERATOR + + +/*___________________________________________________________________________ +| | +| Function Name : W_add_nosat | +| | +| Purpose : | +| | +| 64 bits addition of the two 64 bits variables (L64_var1+L64_var2) | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| L64_var2 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|___________________________________________________________________________| +*/ +Word64 W_add_nosat( Word64 L64_var1, Word64 L64_var2 ) +{ + Word64 L64_var_out; + + L64_var_out = L64_var1 + L64_var2; + +#if ( WMOPS ) + multiCounter[currCounter].W_add_nosat++; +#endif + + return L64_var_out; +} + + +/*___________________________________________________________________________ +| | +| Function Name : W_sub_nosat | +| | +| Purpose : | +| | +| 64 bits subtraction of the two 64 bits variables (L64_var1-L64_var2) | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| L64_var2 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|___________________________________________________________________________| +*/ +Word64 W_sub_nosat( Word64 L64_var1, Word64 L64_var2 ) +{ + Word64 L64_var_out; + + L64_var_out = L64_var1 - L64_var2; + +#if ( WMOPS ) + multiCounter[currCounter].W_sub_nosat++; +#endif + + return L64_var_out; +} + + +/*___________________________________________________________________________ +| | +| Function Name : W_shl | +| | +| Purpose : | +| | +| Arithmetically shift the 64 bit input L64_var1 left var2 positions. Zero| +| fill the var2 LSB of the result. If var2 is negative, arithmetically | +| shift L64_var1 right by -var2 with sign extension. Saturate the result | +| in case of underflows or overflows. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the| +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|___________________________________________________________________________| +*/ +#ifdef BASOP_NOGLOB +Word64 W_shl_o( Word64 L64_var1, Word16 var2, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word64 W_shl( Word64 L64_var1, Word16 var2 ) +{ +#endif /* BASOP_NOGLOB */ + + Word64 L64_var_out = 0LL; + + if ( var2 <= 0 ) + { + if ( var2 < -64 ) + var2 = -64; + var2 = -var2; + L64_var_out = L64_var1 >> var2; + } + else + { + for ( ; var2 > 0; var2-- ) + { + if ( L64_var1 > (Word64) 0X3fffffffffffffffLL ) + { +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + L64_var_out = (Word64) 0X7fffffffffffffffLL; + break; + } + else + { + if ( L64_var1 < (Word64) 0xc000000000000000LL ) + { +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + L64_var_out = (Word64) 0x8000000000000000LL; + break; + } + } + L64_var1 *= 2; + L64_var_out = L64_var1; + } + } +#if ( WMOPS ) + multiCounter[currCounter].W_shl++; +#endif + + /* BASOP_CHECK();*/ + + return ( L64_var_out ); +} + +#ifdef BASOP_NOGLOB +Word64 W_shl( Word64 L64_var1, Word16 var2 ) +{ + return W_shl_o( L64_var1, var2, NULL ); +} +#endif /* BASOP_NOGLOB */ + + +/*___________________________________________________________________________ +| | +| Function Name : W_shr | +| | +| Purpose : | +| | +| Arithmetically shift the 64 bit input L64_var1 right var2 positions. | +| Zero fill the var2 LSB of the result. If var2 is negative, | +| arithmetically shift L64_var1 left by -var2 with sign extension. | +| Saturate the result in case of underflows or overflows. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the| +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|___________________________________________________________________________| +*/ +Word64 W_shr( Word64 L64_var1, Word16 var2 ) +{ + Word64 L64_var_out; + + if ( var2 < 0 ) + { + var2 = -var2; + L64_var_out = W_shl( L64_var1, var2 ); + +#if ( WMOPS ) + multiCounter[currCounter].W_shl--; +#endif /* if WMOPS */ + } + else + { + L64_var_out = L64_var1 >> var2; + } + +#if ( WMOPS ) + multiCounter[currCounter].W_shr++; +#endif /* if WMOPS */ + + return ( L64_var_out ); +} + + +/*___________________________________________________________________________ +| | +| Function Name : W_shl_nosat | +| | +| Purpose : | +| | +| Arithmetically shifts left the 64-bit variable W_var1 by var2 positions. | +| if var2 is negative, W_var1 is shifted to the least significant bits by | +| (�var2) positions with extension of the sign bit . | +| if var2 is positive, W_var1 is shifted to the most significant bits by | +| (var2) positions without saturation control on 64 bits. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the| +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|___________________________________________________________________________| +*/ +Word64 W_shl_nosat( Word64 L64_var1, Word16 var2 ) +{ + + Word64 L64_var_out = 0LL; + + if ( var2 <= 0 ) + { + var2 = -var2; + L64_var_out = L64_var1 >> var2; + } + else + { + L64_var_out = L64_var1 << var2; + } +#if ( WMOPS ) + multiCounter[currCounter].W_shl_nosat++; +#endif + + /* BASOP_CHECK();*/ + + return ( L64_var_out ); +} + + +/*___________________________________________________________________________ +| | +| Function Name : W_shr_nosat | +| | +| Purpose : | +| | +| Arithmetically shifts right the 64-bit variable W_var1 by var2 positions. | +| if var2 is negative, W_var1 is shifted to the most significant bits by | +| (�var2) positions without saturation control on 64 bits. | +| if var2 is positive, W_var1 is shifted to the least significant bits by | +| (var2) positions with extension of the sign bit . | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the| +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|___________________________________________________________________________| +*/ +Word64 W_shr_nosat( Word64 L64_var1, Word16 var2 ) +{ + Word64 L64_var_out; + + if ( var2 < 0 ) + { + var2 = -var2; + L64_var_out = L64_var1 << var2; + } + else + { + L64_var_out = L64_var1 >> var2; + } + +#if ( WMOPS ) + multiCounter[currCounter].W_shr_nosat++; +#endif /* if WMOPS */ + + return ( L64_var_out ); +} + + +/*_________________________________________________________________________________________________ +| | +| Function Name : W_mac_32_16 | +| | +| Purpose : | +| | +| Multiply L_var2 by var3 and shift the result left by 1. Add the 64 bit | +| result to L64_var1, return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| L_var2 | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var2 <= 0x7fff ffff | +| | +| var3 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var3 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_mac_32_16( Word64 L64_var1, Word32 L_var2, Word16 var3 ) +{ + Word64 L64_var_out = ( (Word64) L_var2 * var3 ) << 1; + L64_var_out += L64_var1; +#if ( WMOPS ) + multiCounter[currCounter].W_mac_32_16++; +#endif /* if WMOPS */ + return L64_var_out; +} + + +/*_________________________________________________________________________________________________ +| | +| Function Name : W_msu_32_16 | +| | +| Purpose : | +| | +| Multiply L_var2 by var3 and shift the result left by 1. Subtract the 64 bit | +| result from L64_var1, return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| L_var2 | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var2 <= 0x7fff ffff | +| | +| var3 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var3 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_msu_32_16( Word64 L64_var1, Word32 L_var2, Word16 var3 ) +{ + Word64 L64_var_out = ( (Word64) L_var2 * var3 ) << 1; + L64_var_out = L64_var1 - L64_var_out; +#if ( WMOPS ) + multiCounter[currCounter].W_msu_32_16++; +#endif /* if WMOPS */ + return L64_var_out; +} + + +/*_________________________________________________________________________________________________ +| | +| Function Name : W_mult_32_16 | +| | +| Purpose : | +| | +| Multiply L_var1 by var2 and shift the result left by 1. Return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L_var1 | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var2 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_mult_32_16( Word32 L_var1, Word16 var2 ) +{ + Word64 L64_var_out = ( (Word64) L_var1 * var2 ) << 1; +#if ( WMOPS ) + multiCounter[currCounter].W_mult_32_16++; +#endif /* if WMOPS */ + return L64_var_out; +} + +/*________________________________________________________________________________________________ +| | +| Function Name : W_mult0_16_16 | +| | +| Purpose : | +| | +| Multiply var1 by var2 and return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| var1 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_acc <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_mult0_16_16( Word16 var1, Word16 var2 ) +{ + Word64 L64_var_out = (Word64) var1 * var2; +#if ( WMOPS ) + multiCounter[currCounter].W_mult0_16_16++; +#endif /* if WMOPS */ + return L64_var_out; +} + +/*________________________________________________________________________________________________ +| | +| Function Name : W_mac0_16_16 | +| | +| Purpose : | +| | +| Multiply var2 by var3 and add the 64 bit result to L64_var1, return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var2 <= 0x0000 7fff. | +| | +| var3 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var3 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_mac0_16_16( Word64 L64_var1, Word16 var2, Word16 var3 ) +{ + Word64 L64_var_out = (Word64) var2 * var3; + L64_var_out += L64_var1; +#if ( WMOPS ) + multiCounter[currCounter].W_mac0_16_16++; +#endif /* if WMOPS */ + return L64_var_out; +} + + +/*________________________________________________________________________________________________ +| | +| Function Name : W_msu0_16_16 | +| | +| Purpose : | +| | +| Multiply var2 by var3 and subtract the 64 bit result from L64_var1, return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var2 <= 0x0000 7fff. | +| | +| var3 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var3 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_msu0_16_16( Word64 L64_var1, Word16 var2, Word16 var3 ) +{ + Word64 L64_var_out = (Word64) var2 * var3; + L64_var_out = L64_var1 - L64_var_out; +#if ( WMOPS ) + multiCounter[currCounter].W_msu0_16_16++; +#endif /* if WMOPS */ + return L64_var_out; +} + + +/*_____________________________________________________________________________________ +| | +| Function Name : W_sat_l | +| | +| Purpose : | +| | +| Saturate the lower 32 bits of the 64 bit input number L64_var into 32 bits. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L_var_out | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var_out <= 0x7fff 0000. | +|_____________________________________________________________________________________| +*/ +Word32 W_sat_l( Word64 L64_var ) +{ + Word32 L_var_out; + + if ( L64_var > 0x7FFFFFFF ) + { + L_var_out = 0x7FFFFFFF; + } + else if ( L64_var < (int) 0x80000000 ) + { + L_var_out = 0x80000000; + } + else + { + L_var_out = (Word32) L64_var; + } + +#if ( WMOPS ) + multiCounter[currCounter].W_sat_l++; +#endif /* if WMOPS */ + + return L_var_out; +} + + +/*___________________________________________________________________________________ +| | +| Function Name : W_sat_m | +| | +| Purpose : | +| | +| Truncates the lower 16 bits of the 64 bit input L64_var | +| and saturates the number into 32 bits. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L_var_out | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var_out <= 0x7fff 0000. | +|_____________________________________________________________________________________| +*/ +Word32 W_sat_m( Word64 L64_var ) +{ + Word32 L_var_out; + + L64_var = L64_var >> 16; + L_var_out = W_sat_l( L64_var ); + +#if ( WMOPS ) + multiCounter[currCounter].W_sat_l--; + multiCounter[currCounter].W_sat_m++; +#endif /* if WMOPS */ + + return L_var_out; +} + + +/*__________________________________________________________________________________ +| | +| Function Name : W_deposit32_l | +| | +| Purpose : | +| | +| Deposit the 32 bit L_var1 into the 32 LS bits of the 64 bit output. The | +| 32 MS bits of the output are sign extended. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L_var1 | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= var_out <= 0x7fff 0000. | | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|__________________________________________________________________________________| +*/ +Word64 W_deposit32_l( Word32 L_var1 ) +{ + Word64 L64_var_out; + + L64_var_out = (Word64) L_var1; + +#if ( WMOPS ) + multiCounter[currCounter].W_deposit32_l++; +#endif + + return ( L64_var_out ); +} + + +/*__________________________________________________________________________________ +| | +| Function Name : W_deposit32_h | +| | +| Purpose : | +| | +| Deposit the 32 bit L_var1 into the 32 MS bits of the 64 bit output. The | +| 32 LS bits of the output are zeroed. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L_var1 | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= var_out <= 0x7fff 0000. | | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|__________________________________________________________________________________| +*/ +Word64 W_deposit32_h( Word32 L_var1 ) +{ + Word64 L64_var_out; + + L64_var_out = (Word64) L_var1 << 32; + +#if ( WMOPS ) + multiCounter[currCounter].W_deposit32_h++; +#endif + + return ( L64_var_out ); +} + + +/*__________________________________________________________________________________ +| | +| Function Name : W_extract_l | +| | +| Purpose : | +| | +| Return the 32 LSB of L64_var1. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L_var_out | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var_out <= 0x7fff 0000. | +|__________________________________________________________________________________| +*/ +Word32 W_extract_l( Word64 L64_var1 ) +{ + Word32 L_var_out; + + L_var_out = (Word32) L64_var1; + +#if ( WMOPS ) + multiCounter[currCounter].W_extract_l++; +#endif /* if WMOPS */ + + return ( L_var_out ); +} + + +/*__________________________________________________________________________________ +| | +| Function Name : W_extract_h | +| | +| Purpose : | +| | +| Return the 32 MSB of L64_var1. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L_var_out | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var_out <= 0x7fff 0000. | +|__________________________________________________________________________________| +*/ +Word32 W_extract_h( Word64 L64_var1 ) +{ + Word32 L_var_out; + + L_var_out = (Word32) ( L64_var1 >> 32 ); + +#if ( WMOPS ) + multiCounter[currCounter].W_extract_h++; +#endif /* if WMOPS */ + + return ( L_var_out ); +} + + +/*________________________________________________________________________________________________ +| | +| Function Name : W_mult_16_16 | +| | +| Purpose : | +| | +| Multiply var1 by var2 and shift the result left by 1. Return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| var1 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_acc <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_mult_16_16( Word16 var1, Word16 var2 ) +{ + Word64 L64_var_out = ( (Word64) var1 * var2 ) << 1; +#if ( WMOPS ) + multiCounter[currCounter].W_mult_16_16++; +#endif /* if WMOPS */ + return L64_var_out; +} +/*________________________________________________________________________________________________ +| | +| Function Name : W_mac_16_16 | +| | +| Purpose : | +| | +| Multiply var1 by var2 and shift the result left by 1 and add the 64 bit result to L64_acc, | +| return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_acc | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_acc <= 0x7fffffff ffffffffLL. | +| | +| var1 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var2 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_mac_16_16( Word64 L64_acc, Word16 var1, Word16 var2 ) +{ + Word64 L64_var_out = ( (Word64) var1 * var2 ) << 1; + L64_acc = L64_acc + L64_var_out; + +#if ( WMOPS ) + multiCounter[currCounter].W_mac_16_16++; +#endif /* if WMOPS */ + return L64_acc; +} + + +/*________________________________________________________________________________________________ +| | +| Function Name : W_msu_16_16 | +| | +| Purpose : | +| | +| Multiply var2 by var3 and shift the result left by1 and subtract the 64 bit result | +| from L64_var1, return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var2 <= 0x0000 7fff. | +| | +| var3 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var3 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_msu_16_16( Word64 L64_var1, Word16 var2, Word16 var3 ) +{ + Word64 L64_var_out = ( (Word64) var2 * var3 ) << 1; + L64_var_out = L64_var1 - L64_var_out; +#if ( WMOPS ) + multiCounter[currCounter].W_msu_16_16++; +#endif /* if WMOPS */ + return L64_var_out; +} + + +/*___________________________________________________________________________ +| | +| Function Name : W_shl_sat_l | +| | +| Purpose : | +| | +| Arithmetically shift the 64 bit input L64_var left by n positions with | +| lower 32 bit saturation and return the 32 LSB of 64 bit result | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var <= 0x7fffffff ffffffffLL. | +| | +| n | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= n <= 0x7fff 0000. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L_result | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_result <= 0x7fff 0000. | +|___________________________________________________________________________| +*/ +Word32 W_shl_sat_l( Word64 L64_var, Word16 n ) +{ + Word32 L_result; + Word64 d_var_64; + + d_var_64 = W_shl( L64_var, n ); + L_result = W_sat_l( d_var_64 ); + +#if ( WMOPS ) + multiCounter[currCounter].W_shl_sat_l++; + multiCounter[currCounter].W_shl--; + multiCounter[currCounter].W_sat_l--; +#endif /* if WMOPS */ + + return L_result; +} + + +/*__________________________________________________________________________________ +| | +| Function Name : W_round48_L | +| | +| Purpose : | +| | +| Round asymmetrically lower 16 bits, and | +| saturate the 17.47-bit values to 1.31-bit values | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L_var_out | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | +|__________________________________________________________________________________| +*/ +#ifdef BASOP_NOGLOB +Word32 W_round48_L_o( Word64 L64_var1, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word32 W_round48_L( Word64 L64_var1 ) +{ +#endif /* BASOP_NOGLOB */ + Word64 L64_var_out; + Word32 L_result; + + Word64 L64_var2 = 0x80000000; + Word64 L64_MIN = 0x8000000000000000LL; + Word64 L64_MAX = 0x7FFFFFFFFFFFFFFFLL; + + L64_var1 = W_shl( L64_var1, 16 ); + + L64_var_out = L64_var1 + L64_var2; + + if ( ( ( L64_var1 ^ L64_var2 ) & L64_MIN ) == 0 ) + { + if ( ( L64_var_out ^ L64_var1 ) & L64_MIN ) + { + L64_var_out = ( L64_var1 < 0 ) ? L64_MIN : L64_MAX; +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + } + } + L_result = W_extract_h( L64_var_out ); +#if ( WMOPS ) + multiCounter[currCounter].W_round48_L++; + multiCounter[currCounter].W_extract_h--; + multiCounter[currCounter].W_shl--; +#endif /* if WMOPS */ + + return ( L_result ); +} + +#ifdef BASOP_NOGLOB +Word32 W_round48_L( Word64 L64_var1 ) +{ + return W_round48_L_o( L64_var1, NULL ); +} +#endif /* BASOP_NOGLOB */ + +/*__________________________________________________________________________________ +| | +| Function Name : W_round32_s | +| | +| Purpose : | +| | +| Round asymmetrically lower 32 bits, and | +| saturate the 17.47-bit values to 1.15-bit values | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| var_out | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var_out <= 0x0000 7fff. | +|__________________________________________________________________________________| +*/ +#ifdef BASOP_NOGLOB +Word16 W_round32_s_o( Word64 L64_var1, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word16 W_round32_s( Word64 L64_var1 ) +{ +#endif /* BASOP_NOGLOB */ + Word64 L64_var_out; + Word32 L_var; + Word16 var_out; + + + Word64 L64_var2 = 0x800000000000LL; + Word64 L64_MIN = 0x8000000000000000LL; + Word64 L64_MAX = 0x7FFFFFFFFFFFFFFFLL; + + L64_var1 = W_shl( L64_var1, 16 ); + L64_var_out = L64_var1 + L64_var2; + + if ( ( ( L64_var1 ^ L64_var2 ) & L64_MIN ) == 0 ) + { + if ( ( L64_var_out ^ L64_var1 ) & L64_MIN ) + { + L64_var_out = ( L64_var1 < 0 ) ? L64_MIN : L64_MAX; +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + } + } + L_var = W_extract_h( L64_var_out ); + var_out = extract_h( L_var ); +#if ( WMOPS ) + multiCounter[currCounter].W_round32_s++; + multiCounter[currCounter].W_extract_h--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].W_shl--; +#endif /* if WMOPS */ + + return ( var_out ); +} + +#ifdef BASOP_NOGLOB +Word16 W_round32_s( Word64 L64_var1 ) +{ + return W_round32_s_o( L64_var1, NULL ); +} +#endif /* BASOP_NOGLOB */ + +/*___________________________________________________________________________ +| | +| Function Name : W_norm | +| | +| Purpose : | +| | +| Produces the number of left shifts needed to normalize the 64 bit varia-| +| ble L64_var1. +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| var_out | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0x0000 0000 <= var_out <= 0x0000 003f. | +|___________________________________________________________________________| +*/ +Word16 W_norm( Word64 L64_var1 ) +{ + Word16 var_out; + if ( L64_var1 == 0 ) + { + var_out = 0; + } + else + { + if ( L64_var1 == (Word64) 0xffffffffffffffffLL ) + { + var_out = 63; + } + else + { + if ( L64_var1 < 0 ) + { + L64_var1 = ~L64_var1; + } + for ( var_out = 0; L64_var1 < (Word64) 0x4000000000000000LL; var_out++ ) + { + L64_var1 <<= 1; + } + } + } +#if ( WMOPS ) + multiCounter[currCounter].W_norm++; +#endif /* if WMOPS */ + return ( var_out ); +} + + +/*______________________________________________________________________________ +| | +| Function Name : W_add | +| | +| Purpose : | +| | +| 64 bits addition of the two 64 bits variables (L64_var1+L64_var2) with | +| overflow control and saturation; the result is set at 0x7fffffffffffffffLL | +| when overflow occurs or at 0x8000000000000000LL when underflow occurs. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| L64_var2 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|_______________________________________________________________________________| +*/ +#ifdef BASOP_NOGLOB +Word64 W_add_o( Word64 L64_var1, Word64 L64_var2, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word64 W_add( Word64 L64_var1, Word64 L64_var2 ) +{ +#endif /* BASOP_NOGLOB */ + Word64 L64_var_out; + + L64_var_out = L64_var1 + L64_var2; + + if ( ( ( L64_var1 ^ L64_var2 ) & MIN_64 ) == 0 ) + { + if ( ( L64_var_out ^ L64_var1 ) & MIN_64 ) + { + L64_var_out = ( L64_var1 < 0 ) ? MIN_64 : MAX_64; +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + } + } + +#if ( WMOPS ) + multiCounter[currCounter].W_add++; +#endif + return L64_var_out; +} + +#ifdef BASOP_NOGLOB +Word64 W_add( Word64 L64_var1, Word64 L64_var2 ) +{ + return W_add_o( L64_var1, L64_var2, NULL ); +} +#endif /* BASOP_NOGLOB */ + +/*______________________________________________________________________________ +| | +| Function Name : W_sub | +| | +| Purpose : | +| | +| 64 bits subtraction of the two 64 bits variables (L64_var1-L64_var2) with | +| overflow control and saturation; the result is set at 0x7fffffffffffffffLL | +| when overflow occurs or at 0x8000000000000000LL when underflow occurs. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| L64_var2 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|_______________________________________________________________________________| +*/ +#ifdef BASOP_NOGLOB +Word64 W_sub_o( Word64 L64_var1, Word64 L64_var2, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word64 W_sub( Word64 L64_var1, Word64 L64_var2 ) +{ +#endif /* BASOP_NOGLOB */ + Word64 L64_var_out; + + L64_var_out = L64_var1 - L64_var2; + + if ( ( ( L64_var1 ^ L64_var2 ) & MIN_64 ) != 0 ) + { + if ( ( L64_var_out ^ L64_var1 ) & MIN_64 ) + { + L64_var_out = ( L64_var1 < 0 ) ? MIN_64 : MAX_64; +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + } + } + +#if ( WMOPS ) + multiCounter[currCounter].W_add++; +#endif + return L64_var_out; +} + +#ifdef BASOP_NOGLOB +Word64 W_sub( Word64 L64_var1, Word64 L64_var2 ) +{ + return W_sub_o( L64_var1, L64_var2, NULL ); +} +#endif /* BASOP_NOGLOB */ + + +/*______________________________________________________________________________ +| | +| Function Name : W_neg | +| | +| Purpose : | +| | +| Negate the 64 bit variable L64_var1 with overflow control and saturation; | +| Saturate and set overflow in the case where input is 0x8000000000000000LL. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +|_______________________________________________________________________________| +*/ +#ifdef BASOP_NOGLOB +Word64 W_neg_o( Word64 L64_var1, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word64 W_neg( Word64 L64_var1 ) +{ +#endif /* BASOP_NOGLOB */ + Word64 L64_var_out; + + if ( L64_var1 == MIN_64 ) + { + L64_var_out = MAX_64; +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + } + else + { + L64_var_out = -L64_var1; + } + +#if ( WMOPS ) + multiCounter[currCounter].W_neg++; +#endif + + return ( L64_var_out ); +} + +#ifdef BASOP_NOGLOB +Word64 W_neg( Word64 L64_var1 ) +{ + return W_neg_o( L64_var1, NULL ); +} +#endif /* BASOP_NOGLOB */ + + +/*___________________________________________________________________________ + | | + | Function Name : W_abs | + | | + | Purpose : | + | | + | Absolute value of L64_var1; Saturate in case where the input is | + | 0x8000000000000000LL | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L64_var1 64 bit long signed integer (Word64) whose value falls in the | + | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | L64_var_out | + | 64 bit long signed integer (Word64) whose value falls in the | + | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | + |___________________________________________________________________________| +*/ +#ifdef BASOP_NOGLOB +Word64 W_abs_o( Word64 L64_var1, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word64 W_abs( Word64 L64_var1 ) +{ +#endif /* BASOP_NOGLOB */ + Word64 L64_var_out; + + if ( L64_var1 == MIN_64 ) + { + L64_var_out = MAX_64; +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + } + else + { + if ( L64_var1 < 0 ) + { + L64_var_out = -L64_var1; + } + else + { + L64_var_out = L64_var1; + } + } + +#if ( WMOPS ) + multiCounter[currCounter].W_abs++; +#endif + + return ( L64_var_out ); +} + +#ifdef BASOP_NOGLOB +Word64 W_abs( Word64 L64_var1 ) +{ + return W_abs_o( L64_var1, NULL ); +} +#endif /* BASOP_NOGLOB */ + +/*_________________________________________________________________________________________________ +| | +| Function Name : W_mult_32_32 | +| | +| Purpose : | +| | +| Multiply L_var1 by L_var2 and shift the result left by 1.Saturate and set overflow in case | +| where both inputs are 0x80000000 . Return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L_var1 | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff | +| | +| L_var2 | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +#ifdef BASOP_NOGLOB +Word64 W_mult_32_32_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) +{ +#else /* BASOP_NOGLOB */ +Word64 W_mult_32_32( Word32 L_var1, Word32 L_var2 ) +{ +#endif /* BASOP_NOGLOB */ + Word64 L64_var_out; + + if ( ( L_var1 == MIN_32 ) && ( L_var2 == MIN_32 ) ) + { + L64_var_out = MAX_64; +#ifdef BASOP_NOGLOB + set_overflow( Overflow ); +#else /* BASOP_NOGLOB */ + Overflow = 1; +#endif /* BASOP_NOGLOB */ + } + else + { + L64_var_out = ( (Word64) L_var1 * L_var2 ) << 1; + } + +#if ( WMOPS ) + multiCounter[currCounter].W_mult_32_32++; +#endif /* if WMOPS */ + return L64_var_out; +} + +#ifdef BASOP_NOGLOB +Word64 W_mult_32_32( Word32 L_var1, Word32 L_var2 ) +{ + return W_mult_32_32_o( L_var1, L_var2, NULL ); +} +#endif /* BASOP_NOGLOB */ + +/*_________________________________________________________________________________________________ +| | +| Function Name : W_mult0_32_32 | +| | +| Purpose : | +| | +| Multiply L_var1 by L_var2. Return a 64 bit result. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L_var1 | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff | +| | +| L_var2 | +| 32 bit signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var1 <= 0x7fff ffff | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long long signed integer (Word64) whose value falls in the | +| range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | +|_________________________________________________________________________________________________| +*/ +Word64 W_mult0_32_32( Word32 L_var1, Word32 L_var2 ) +{ + Word64 L64_var_out; + + L64_var_out = (Word64) L_var1 * L_var2; + + +#if ( WMOPS ) + multiCounter[currCounter].W_mult0_32_32++; +#endif /* if WMOPS */ + return L64_var_out; +} + + +/*_____________________________________________________________________________ +| | +| Function Name : W_lshl | +| | +| Purpose : | +| | +| Logically shift the 64 bit unsigned input L64_var1 left by var2 positions. | +| Zero fill the var2 LSB of the result. If var2 is negative, logically shift | +| L64_var1 right by -var2 with zero fill in the MSB. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long unsigned signed integer (UWord64) whose value falls | +| in the range : 0LL <= L64_var1 <= 0xffffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long unsigned signed integer (UWord64) whose value falls | +| in the range : 0LL <= L64_var1 <= 0xffffffff ffffffffLL. | +|______________________________________________________________________________| +*/ +UWord64 W_lshl( UWord64 L64_var1, Word16 var2 ) +{ + + UWord64 L64_var_out = 0LL; + + if ( var2 < 0 ) + { + L64_var_out = L64_var1 >> ( -var2 ); + } + else + { + L64_var_out = L64_var1 << var2; + } +#if ( WMOPS ) + multiCounter[currCounter].W_lshl++; +#endif + + return ( L64_var_out ); +} + +/*_____________________________________________________________________________ +| | +| Function Name : W_lshr | +| | +| Purpose : | +| | +| Logically shift the 64 bit unsigned input L64_var1 right by var2 positions.| +| Zero fill the var2 MSB of the result. If var2 is negative, logically shift | +| L64_var1 left by -var2 with zero fill in the LSB. | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 64 bit long unsigned signed integer (UWord64) whose value falls | +| in the range : 0LL <= L64_var1 <= 0xffffffff ffffffffLL. | +| | +| var2 | +| 16 bit short signed integer (Word16) whose value falls in the | +| range : 0xffff 8000 <= var1 <= 0x0000 7fff. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L64_var_out | +| 64 bit long unsigned signed integer (UWord64) whose value falls | +| in the range : 0LL <= L64_var1 <= 0xffffffff ffffffffLL. | +|______________________________________________________________________________| +*/ +UWord64 W_lshr( UWord64 L64_var1, Word16 var2 ) +{ + + UWord64 L64_var_out = 0LL; + + if ( var2 < 0 ) + { + L64_var_out = L64_var1 << ( -var2 ); + } + else + { + L64_var_out = L64_var1 >> var2; + } +#if ( WMOPS ) + multiCounter[currCounter].W_lshr++; +#endif + + return ( L64_var_out ); +} + + +/*__________________________________________________________________________________ +| | +| Function Name : W_round64_L | +| | +| Purpose : | +| | +| Round asymmetrically lower 32 bits, and | +| saturate the 1.63-bit values to 1.31-bit values | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L_var_out | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | +|__________________________________________________________________________________| +*/ +Word32 W_round64_L( Word64 L64_var1 ) +{ + Word64 L64_var_out; + Word32 L_result; + + + Word64 L64_tmp = 0x80000000; + L64_var_out = W_add( L64_var1, L64_tmp ); + L_result = W_extract_h( L64_var_out ); + +#if ( WMOPS ) + multiCounter[currCounter].W_round64_L++; + multiCounter[currCounter].W_extract_h--; + multiCounter[currCounter].W_add--; +#endif /* if WMOPS */ + + return ( L_result ); +} + +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +/* end of file */ diff --git a/lib_com/enh64.h b/lib_com/enh64.h new file mode 100644 index 000000000..9016a27ae --- /dev/null +++ b/lib_com/enh64.h @@ -0,0 +1,85 @@ + +#ifndef _ENH64_H +#define _ENH64_H + +#include "stl.h" + +#ifndef Word64 +#define Word64 long long int +#endif + +#ifndef UWord64 +#define UWord64 unsigned long long int +#endif + +#define MAX_64 (Word64) 0x7fffffffffffffffLL +#define MIN_64 (Word64) 0x8000000000000000LL + +/***************************************************************************** + * + * Prototypes for enhanced 64 bit arithmetic operators + * + *****************************************************************************/ +#ifdef ENH_64_BIT_OPERATOR +Word64 W_add_nosat( Word64 L64_var1, Word64 L64_var2 ); +Word64 W_sub_nosat( Word64 L64_var1, Word64 L64_var2 ); +Word64 W_shl( Word64 L64_var1, Word16 var2 ); +Word64 W_shr( Word64 L64_var1, Word16 var2 ); +Word64 W_shl_nosat( Word64 L64_var1, Word16 var2 ); +Word64 W_shr_nosat( Word64 L64_var1, Word16 var2 ); +Word64 W_mult_32_16( Word32 L_var1, Word16 var2 ); +Word64 W_mac_32_16( Word64 L64_acc, Word32 L_var1, Word16 var2 ); +Word64 W_msu_32_16( Word64 L64_acc, Word32 L_var1, Word16 var2 ); +Word64 W_mult0_16_16( Word16 var1, Word16 var2 ); +Word64 W_mac0_16_16( Word64 L64_acc, Word16 var1, Word16 var2 ); +Word64 W_msu0_16_16( Word64 L64_acc, Word16 var1, Word16 var2 ); +Word64 W_mult_16_16( Word16 var1, Word16 var2 ); +Word64 W_mac_16_16( Word64 L64_acc, Word16 var1, Word16 var2 ); +Word64 W_msu_16_16( Word64 L64_acc, Word16 var1, Word16 var2 ); + +Word64 W_deposit32_l( Word32 L_var1 ); +Word64 W_deposit32_h( Word32 L_var1 ); + +Word32 W_sat_l( Word64 L64_var ); +Word32 W_sat_m( Word64 L64_var ); +Word32 W_shl_sat_l( Word64 L64_var, Word16 n ); + +Word32 W_extract_l( Word64 L64_var1 ); +Word32 W_extract_h( Word64 L64_var1 ); + +Word32 W_round48_L( Word64 L64_var1 ); +Word16 W_round32_s( Word64 L64_var1 ); + +Word16 W_norm( Word64 L_var1 ); + + +Word64 W_add( Word64 L64_var1, Word64 L64_var2 ); +Word64 W_sub( Word64 L64_var1, Word64 L64_var2 ); +Word64 W_neg( Word64 L64_var1 ); +Word64 W_abs( Word64 L64_var1 ); +Word64 W_mult_32_32( Word32 L_var1, Word32 L_var2 ); +Word64 W_mult0_32_32( Word32 L_var1, Word32 L_var2 ); +UWord64 W_lshl( UWord64 L64_var1, Word16 var2 ); +UWord64 W_lshr( UWord64 L64_var1, Word16 var2 ); +Word32 W_round64_L( Word64 L64_var1 ); + +#ifdef BASOP_NOGLOB +/* + * Overflowing operators + */ +Word64 W_shl_o( Word64 L64_var1, Word16 var2, Flag *Overflow ); +Word32 W_round48_L_o( Word64 L64_var1, Flag *Overflow ); +Word16 W_round32_s_o( Word64 L64_var1, Flag *Overflow ); +Word64 W_add_o( Word64 L64_var1, Word64 L64_var2, Flag *Overflow ); +Word64 W_sub_o( Word64 L64_var1, Word64 L64_var2, Flag *Overflow ); +Word64 W_neg_o( Word64 L64_var1, Flag *Overflow ); +Word64 W_abs_o( Word64 L64_var1, Flag *Overflow ); +Word64 W_mult_32_32_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ); +#endif /* BASOP_NOGLOB */ + +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +#endif /*_ENH64_H*/ + + +/* end of file */ diff --git a/lib_com/enhUL32.c b/lib_com/enhUL32.c new file mode 100644 index 000000000..1328a328c --- /dev/null +++ b/lib_com/enhUL32.c @@ -0,0 +1,425 @@ +/* + ============================================================================ + File: ENHUL32.C v.1.0 - 01.July.2018 + ============================================================================ + + ENHANCED UNSIGNED 32-BIT ARITHMETIC OPERATORS + History: + v.0.5 - 21.March.2014 + + ============================================================================ +*/ + +/***************************************************************************** + * + * Enhanced Unsigned 32 bit operators : + * see complete list in .h file + * + *****************************************************************************/ + +/***************************************************************************** + * + * Include-Files + * + *****************************************************************************/ +#include +#include +#include "stl.h" +#include "enhUL32.h" + +#if ( WMOPS ) +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif /* if WMOPS */ + + +/***************************************************************************** + * + * Constants and Globals + * + *****************************************************************************/ + + +/***************************************************************************** + * + * Functions + * + *****************************************************************************/ +#ifdef ENH_U_32_BIT_OPERATOR + +/*___________________________________________________________________________ + | | + | Function Name : UL_deposit_l | + | | + | Purpose : | + | | + | Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The | + | 16 MS bits of the output are not sign extended. | + |___________________________________________________________________________| +*/ + +UWord32 UL_deposit_l( UWord16 uvar ) +{ + UWord32 UL_result; + UL_result = (UWord32) uvar; /* no sign extension*/ +#if ( WMOPS ) + multiCounter[currCounter].UL_deposit_l++; +#endif + return ( UL_result ); +} +#ifdef FIX_NORM_UL_LOC +/*_____________________________________________________________________________ + | | + | Function Name : norm_ul | + | | + | Purpose : | + | | + | Produces the number of left shifts needed to normalize the 32 bit varia- | + | ble UL_var1 for positive values on the interval with minimum of | + | 0 and maximum of 0xffffffff, ; in order to normalize the | + | result, the following operation must be done : | + | | + | norm_UL_var1 = UL_lshl(UL_var1, norm_ul(UL_var1)). | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | UL_var1 | + | 32 bit long unsigned integer (UWord32) whose value falls in the | + | range : 0x0000 0000 <= var1 <= 0xffff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0x0000 0000 <= var_out <= 0x0000 001f. (0..31d) | + |_____________________________________________________________________________| +*/ +Word16 norm_ul( UWord32 UL_var1 ) +{ + Word16 var_out; + + if ( UL_var1 == 0 ) + { + var_out = 0; + } + else + { + /* simply test shift up until highest bit is set */ + for ( var_out = 0; UL_var1 < (UWord32) 0x80000000U; var_out++ ) + { + UL_var1 <<= 1; + } + } + +#if ( WMOPS ) + multiCounter[currCounter].norm_ul++; +#endif + + return ( var_out ); +} +#endif +/*___________________________________________________________________________ + | | + | Function Name : UL_addNs | + | | + | Purpose : | + | | + | 32 bits addition of the two unsigned 32 bits variables | + | (L_var1+L_var2) with overflow control, but without saturation | + | | + | Outputs : | + | | + | *wrap = 1 if wrap occured, otherwize 0 | + | | + | Return Value : | + | | + | UL_var3 = modulo(UL_var1+UL_var2,32) | + |___________________________________________________________________________| +*/ + +UWord32 UL_addNs( UWord32 UL_var1, UWord32 UL_var2, UWord16 *wrap ) +{ + UWord32 UL_var3; + + /* STL Overflow flag is not updated */ + UL_var3 = UL_var1 + UL_var2; /* 32-bit wrap may occur, like in C */ + + if ( ( (UWord64) UL_var1 + (UWord64) UL_var2 ) > 0xFFFFFFFFU ) + { + *wrap = 1; /* wrapped output */ + } + else + { + *wrap = 0; + } + +#if WMOPS + multiCounter[currCounter].UL_addNs++; +#endif + + return UL_var3; +} + +/*___________________________________________________________________________ + | | + | Function Name : UL_subNs | + | | + | Purpose : | + | | + | 32 bits subtraction of the two unsigned 32 bits variables | + | (L_var1-L_var2) with overflow control, but without saturation | + | | + | Outputs : | + | | + | *sgn = 1 if wrap (to "negative" occured, otherwise 0) | + | | + | Return Value : | + | | + | UL_var3 = modulo(UL_var1-UL_var2,32) | + |___________________________________________________________________________| +*/ + +UWord32 UL_subNs( UWord32 UL_var1, UWord32 UL_var2, UWord16 *sgn ) +{ + UWord32 UL_var3; + + UL_var3 = UL_var1 - UL_var2; /*wrap may occur, like in C */ + if ( UL_var1 >= UL_var2 ) + { + *sgn = 0; + } + else + { + *sgn = 1; /* "negative", wrapped output */ + } + +#if WMOPS + multiCounter[currCounter].UL_subNs++; +#endif + return UL_var3; +} + +/*________________________________________________________________________________ + | | + | Function Name : Mpy_32_16_uu | + | | + | Purpose : | + | | + | Multiplies the 2 unsigned values UL_var1 and uvar2. | + | The operation is performed in fractional mode : | + | - UL_var1 is supposed to be in Q32 format. | + | - var2 is supposed to be in Q16 format. | + | - The result is produced in Q48 format : UL_varout_h points to the | + | 32 MSBits while varout_l points to the 16 LSBits. | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | UL_var1 32 bit long unsigned integer (UWord32) whose value falls in | + | the range : 0x0000 0000 <= L_var1 <= 0xffff ffff. | + | | + | var2 16 bit short unsigned integer (UWord16) whose value falls in | + | the range : 0x0000 <= var2 <= 0x0000 ffff. | + | | + | Outputs : | + | | + | *UL_varout_h 32 bit long unsigned integer (UWord32) whose value falls in | + | the range : 0x0000 0000 <= UL_varout_h <= 0xffff ffff. | + | | + | *varout_l 16 bit short unsigned integer (UWord16) whose value falls in | + | the range : 0x0000 0000 <= varout_l <= 0x0000 ffff. | + | | + | Return Value : | + | | + | none | + |________________________________________________________________________________| +*/ +void Mpy_32_16_uu( UWord32 UL_var1, UWord16 uvar2, UWord32 *UL_varout_h, UWord16 *varout_l ) +{ + UWord64 UL64_var1; + + /* 4294967295 * 65535 < 281474976710655 */ + /* (uint64(2)^16-1 )*(uint64(2)^32-1) < (uint64(2)^(16+32)-1) */ + UL64_var1 = ( (UWord64) UL_var1 ) * ( (UWord64) uvar2 ); + *varout_l = (UWord16) UL64_var1; + *UL_varout_h = (UWord32) ( UL64_var1 >> 16 ); + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_16_uu++; +#endif /* if WMOPS */ + + return; +} + +/*__________________________________________________________________________________ + | | + | Function Name : Mpy_32_32_uu | + | | + | Purpose : | + | | + | Multiplies the 2 unsigned values UL_var1 and UL_var2. | + | The operation is performed in fractional mode : | + | - UL_var1 and UL_var2 are supposed to be in Q32 format. | + | - The result is produced in Q64 format : UL_varout_h points to the | + | 32 MSBits while UL_varout_l points to the 32 LSBits. | + | | + | Complexity weight : 4 | + | | + | Inputs : | + | | + | UL_var1 32 bit long unsigned integer (UWord32) whose value falls in the | + | range : 0x0000 0000 <= L_var1 <= 0xffff ffff. | + | | + | UL_var2 32 bit long unsigned integer (UWord32) whose value falls in the | + | range : 0x0000 0000 <= L_var2 <= 0xffff ffff. | + | | + | Outputs : | + | | + | *UL_varout_h 32 bit long signed integer (Word32) whose value falls in | + | the range : 0x0000 0000 <= UL_varout_h <= 0xffff ffff. | + | | + | *UL_varout_l 32 bit short unsigned integer (UWord32) whose value falls in | + | the range : 0x0000 0000 <= UL_varout_l <= 0xffff ffff. | + | | + | Return Value : | + | | + | none | + |__________________________________________________________________________________| + */ +void Mpy_32_32_uu( UWord32 UL_var1, UWord32 UL_var2, UWord32 *UL_varout_h, UWord32 *UL_varout_l ) +{ + UWord64 UL64_var1; + /* (uint64(2)^32-1 )*(uint64(2)^32-1) < (uint64(2)^(32+32)-1) */ + UL64_var1 = ( (UWord64) UL_var1 ) * ( (UWord64) UL_var2 ); + *UL_varout_h = (UWord32) ( UL64_var1 >> 32 ); + *UL_varout_l = (UWord32) ( UL64_var1 ); + +#if ( WMOPS ) + multiCounter[currCounter].Mpy_32_32_uu++; +#endif /* if WMOPS */ + + return; +} + +/*_____________________________________________________________________________________ + | | + | Function Name : UL_Mpy_32_32 | + | | + | Purpose : | + | | + | Multiplies the 2 unsigned values UL_var1 and UL_var2 | + | and returns the lower 32 bits, without saturation control. | + | | + | - UL_var1 and UL_var2 are supposed to be in Q32 format. | + | - The result is produced in Q64 format, the 32 LSBits. | + | | + | operates like a regular 32-by-32 bit unsigned int multiplication in ANSI-C. | + | UWord32) = (unsigned int)*(unsigned int); | + | | + | | + | Complexity weight : 2 | + | | + | Inputs : | + | | + | UL_var1 32 bit long unsigned integer (UWord32) whose value falls in the | + | range : 0x0000 0000 <= UL_var1 <= 0xffff ffff. | + | | + | UL_var2 32 bit long unsigned integer (UWord32) whose value falls in the | + | range : 0x0000 0000 <= UL_var2 <= 0xffff ffff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | *UL_varout_l 32 bit short unsigned integer (UWord32) whose value falls in | + | the range : 0x0000 0000 <= UL_varout_l <= 0xffff ffff. | + | | + |_____________________________________________________________________________________| +*/ +UWord32 UL_Mpy_32_32( UWord32 UL_var1, UWord32 UL_var2 ) +{ + UWord32 UL_varout_l; + +#define MASK32 0xFFFFFFFFU + /* MASK32 may be needed in case Hardware is using larger than 32 bits for UWord32 type */ + UL_varout_l = ( UL_var1 & MASK32 ) * ( UL_var2 & MASK32 ); + UL_varout_l = UL_varout_l & MASK32; +#undef MASK32 + +#if ( WMOPS ) + multiCounter[currCounter].UL_Mpy_32_32++; +#endif /* if WMOPS */ + + return UL_varout_l; +} + + +#ifdef STL_TYPECASTS +/* (Reuse of existing signed STL "L" operators) with + typecasting to make the resulting "UL" code a lot cleaner and more readable. */ + +UWord32 UL_lshl( UWord32 UL_var1, Word16 var2 ) +{ + return ( (UWord32) L_lshl( (Word32) UL_var1, var2 ) ); +} + +UWord32 UL_lshr( UWord32 UL_var1, Word16 var2 ) +{ + return ( (UWord32) L_lshr( (Word32) UL_var1, var2 ) ); +} + +UWord32 UL_and( UWord32 UL_var1, UWord32 UL_var2 ) +{ + return (UWord32) L_and( (Word32) UL_var1, (Word32) UL_var2 ); +} + +UWord32 UL_or( UWord32 UL_var1, UWord32 UL_var2 ) +{ + return (UWord32) L_or( (Word32) UL_var1, (Word32) UL_var2 ); +} + +UWord32 UL_xor( UWord32 UL_var1, UWord32 UL_var2 ) +{ + return (UWord32) L_xor( (Word32) UL_var1, (Word32) UL_var2 ); +} + +UWord32 UL_deposit_h( UWord16 uvar1 ) +{ + return (UWord32) L_deposit_h( (Word32) uvar1 ); +} + +UWord16 u_extract_h( UWord32 UL_var1 ) +{ + return (UWord16) extract_h( (Word32) UL_var1 ); +} + +UWord16 u_extract_l( UWord32 UL_var1 ) +{ + return (UWord32) extract_l( (Word32) UL_var1 ); +} + +/* enable convenient reuse of Non-saturating UL_subNs , UL_addNs while "D"iscarding the sgn/wrap output flags */ +UWord32 UL_subNsD( UWord32 UL_var1, UWord32 UL_var2 ) +{ + UWord16 dummy_sign; + return UL_subNs( UL_var1, UL_var2, &dummy_sign ); +} + +UWord32 UL_addNsD( UWord32 UL_var1, UWord32 UL_var2 ) +{ + UWord16 dummy_wrap; + return UL_addNs( UL_var1, UL_var2, &dummy_wrap ); +} +#endif + +#endif /* ENH_U_32_BIT_OPERATOR */ + +/* end of file */ diff --git a/lib_com/enhUL32.h b/lib_com/enhUL32.h new file mode 100644 index 000000000..55493331b --- /dev/null +++ b/lib_com/enhUL32.h @@ -0,0 +1,78 @@ +/* + ============================================================================ + File: ENHUL32.H v.1.0 - 01.July.2018 + ============================================================================ + + + ============================================================================ +*/ + +#ifndef _ENHUL32_H +#define _ENHUL32_H + +/***************************************************************************** + * + * Constants and Globals + * + *****************************************************************************/ +#define STL_TYPECASTS /* logical shift and bitwise manipulation functions */ + /* algorithmically exact to existing signed L_lshr and L_lshr */ + +#include "stl.h" + +#ifndef UWord64 +#define UWord64 unsigned long long /* for local use inside UL_Mpy_32_* */ +#endif + +#if ( WMOPS ) +#include "count.h" +extern BASIC_OP multiCounter[MAXCOUNTERS]; /* existing signed counters are reused for unsigedn operators */ +extern int currCounter; +#endif /* if WMOPS */ + +/***************************************************************************** + * + * Prototypes for enhanced unsigned 32 bit arithmetic operators + * + *****************************************************************************/ +#ifdef ENH_U_32_BIT_OPERATOR +UWord32 UL_addNs( UWord32 a, UWord32 b, UWord16 *wrap ); +UWord32 UL_subNs( UWord32 a, UWord32 b, UWord16 *sgn ); + +UWord32 UL_Mpy_32_32( UWord32 a, UWord32 b ); +void Mpy_32_32_uu( UWord32 a, UWord32 b, UWord32 *c_h, UWord32 *c_l ); /* does not saturate */ +void Mpy_32_16_uu( UWord32 a, UWord16 b, UWord32 *c_h, UWord16 *c_l ); /* does not saturate */ + +#ifdef FIX_NORM_UL_LOC +Word16 norm_ul( UWord32 UL_var1 ); +#endif +UWord32 UL_deposit_l( UWord16 ); /* deposit low without sign extension */ +#endif /* ENH_U_32_BIT_OPERATOR */ + +/***************************************************************************** + * + * Inline Functions + * + *****************************************************************************/ + +#ifdef STL_TYPECASTS +/* (Reuse of existing signed STL "L" operators) with + typecasting to make the resulting "UL" code a lot cleaner and more readable. */ +UWord32 UL_lshl( UWord32 UL_var1, Word16 var2 ); +UWord32 UL_lshr( UWord32 UL_var1, Word16 var2 ); +UWord32 UL_and( UWord32 UL_var1, UWord32 UL_var2 ); +UWord32 UL_or( UWord32 UL_var1, UWord32 UL_var2 ); +UWord32 UL_xor( UWord32 UL_var1, UWord32 UL_var2 ); +UWord32 UL_deposit_h( UWord16 uvar1 ); +UWord16 u_extract_h( UWord32 UL_var1 ); +UWord16 u_extract_l( UWord32 UL_var1 ); + +/* enable convenient reuse of Non-saturating UL_subNs , UL_addNs + while "D"iscarding the sgn/wrap output flags */ +UWord32 UL_subNsD( UWord32 UL_var1, UWord32 UL_var2 ); +UWord32 UL_addNsD( UWord32 UL_var1, UWord32 UL_var2 ); +#endif + +#endif /*_ENHUL32_H*/ + +/* end of file */ diff --git a/lib_com/fft_cldfb.c b/lib_com/fft_cldfb.c index 0ea848abd..3e559f235 100644 --- a/lib_com/fft_cldfb.c +++ b/lib_com/fft_cldfb.c @@ -40,6 +40,10 @@ #include "prot.h" #include "ivas_cnst.h" #include "wmc_auto.h" +#include "enh64.h" +#include "enh32.h" +#include "complex_basop.h" +#include "basop_settings.h" #if __STDC_VERSION__ >= 199901L #if defined __ICL @@ -1221,3 +1225,1220 @@ void fft_cldfb( return; } + +#define Mpy_32_xx Mpy_32_16_1 + +#define FFTC( x ) WORD322WORD16( (Word32) x ) + +#define C31 ( FFTC( 0x91261468 ) ) /* FL2WORD32( -0.86602540) -sqrt(3)/2 */ + +#define C51 ( FFTC( 0x79bc3854 ) ) /* FL2WORD32( 0.95105652) */ +#define C52 ( FFTC( 0x9d839db0 ) ) /* FL2WORD32(-1.53884180/2) */ +#define C53 ( FFTC( 0xd18053ce ) ) /* FL2WORD32(-0.36327126) */ +#define C54 ( FFTC( 0x478dde64 ) ) /* FL2WORD32( 0.55901699) */ +#define C55 ( FFTC( 0xb0000001 ) ) /* FL2WORD32(-1.25/2) */ + +#define C81 ( FFTC( 0x5a82799a ) ) /* FL2WORD32( 7.071067811865475e-1) */ +#define C82 ( FFTC( 0xa57d8666 ) ) /* FL2WORD32(-7.071067811865475e-1) */ + +#define C161 ( FFTC( 0x5a82799a ) ) /* FL2WORD32( 7.071067811865475e-1) INV_SQRT2 */ +#define C162 ( FFTC( 0xa57d8666 ) ) /* FL2WORD32(-7.071067811865475e-1) -INV_SQRT2 */ + +#define C163 ( FFTC( 0x7641af3d ) ) /* FL2WORD32( 9.238795325112867e-1) COS_PI_DIV8 */ +#define C164 ( FFTC( 0x89be50c3 ) ) /* FL2WORD32(-9.238795325112867e-1) -COS_PI_DIV8 */ + +#define C165 ( FFTC( 0x30fbc54d ) ) /* FL2WORD32( 3.826834323650898e-1) COS_3PI_DIV8 */ +#define C166 ( FFTC( 0xcf043ab3 ) ) /* FL2WORD32(-3.826834323650898e-1) -COS_3PI_DIV8 */ + + +#define cplxMpy4_8_0( re, im, a, b, c, d ) \ + re = L_shr( L_sub( Mpy_32_xx( a, c ), Mpy_32_xx( b, d ) ), 1 ); \ + im = L_shr( L_add( Mpy_32_xx( a, d ), Mpy_32_xx( b, c ) ), 1 ); + +#define cplxMpy4_8_1( re, im, a, b ) \ + re = L_shr( a, 1 ); \ + im = L_shr( b, 1 ); + +void fft16_with_cmplx_data( cmplx *pInp, Word16 bsacle ); + + +#undef SCALEFACTOR5 +#undef SCALEFACTOR8 +#undef SCALEFACTOR10 +#undef SCALEFACTOR16 +#undef SCALEFACTOR20 +#undef SCALEFACTOR30 +#undef SCALEFACTOR30_1 +#undef SCALEFACTOR30_2 + +#define SCALEFACTOR5 ( 0 ) +#define SCALEFACTOR8 ( 0 ) +#define SCALEFACTOR10 ( 0 ) +#define SCALEFACTOR16 ( 0 ) +#define SCALEFACTOR20 ( 0 ) +#define SCALEFACTOR30 ( 0 ) +#define SCALEFACTOR30_1 ( 0 ) +#define SCALEFACTOR30_2 ( 0 ) +/** + * \brief Function performs a complex 8-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR8 bits. + * + * WOPS with 32x16 bit multiplications: 108 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +static void fft8_with_cmplx_data( cmplx *inp ) +{ + cmplx x0, x1, x2, x3, x4, x5, x6, x7; + cmplx s0, s1, s2, s3, s4, s5, s6, s7; + cmplx t0, t1, t2, t3, t4, t5, t6, t7; + + /* Pre-additions */ + x0 = CL_shr( inp[0], SCALEFACTOR8 ); + x1 = CL_shr( inp[1], SCALEFACTOR8 ); + x2 = CL_shr( inp[2], SCALEFACTOR8 ); + x3 = CL_shr( inp[3], SCALEFACTOR8 ); + x4 = CL_shr( inp[4], SCALEFACTOR8 ); + x5 = CL_shr( inp[5], SCALEFACTOR8 ); + x6 = CL_shr( inp[6], SCALEFACTOR8 ); + x7 = CL_shr( inp[7], SCALEFACTOR8 ); + + /* loops are unrolled */ + { + t0 = CL_add( x0, x4 ); + t1 = CL_sub( x0, x4 ); + + t2 = CL_add( x1, x5 ); + t3 = CL_sub( x1, x5 ); + + t4 = CL_add( x2, x6 ); + t5 = CL_sub( x2, x6 ); + + t6 = CL_add( x3, x7 ); + t7 = CL_sub( x3, x7 ); + } + + /* Pre-additions and core multiplications */ + + s0 = CL_add( t0, t4 ); + s2 = CL_sub( t0, t4 ); + + s4 = CL_mac_j( t1, t5 ); + s5 = CL_msu_j( t1, t5 ); + + s1 = CL_add( t2, t6 ); + s3 = CL_sub( t2, t6 ); + s3 = CL_mul_j( s3 ); + + t0 = CL_add( t3, t7 ); + t1 = CL_sub( t3, t7 ); + + s6 = CL_scale_t( CL_msu_j( t1, t0 ), C81 ); + s7 = CL_dscale_t( CL_swap_real_imag( CL_msu_j( t0, t1 ) ), C81, C82 ); + + /* Post-additions */ + + inp[0] = CL_add( s0, s1 ); + inp[4] = CL_sub( s0, s1 ); + + inp[2] = CL_sub( s2, s3 ); + inp[6] = CL_add( s2, s3 ); + + inp[3] = CL_add( s4, s7 ); + inp[7] = CL_sub( s4, s7 ); + + inp[1] = CL_add( s5, s6 ); + inp[5] = CL_sub( s5, s6 ); +#if ( WMOPS ) + multiCounter[currCounter].CL_move += 8; +#endif +} + +/** + * \brief Function performs a complex 5-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR5 bits. + * + * WOPS with 32x16 bit multiplications: 88 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +static void fft5_with_cmplx_data( cmplx *inp ) +{ + cmplx x0, x1, x2, x3, x4; + cmplx y1, y2, y3, y4; + cmplx t; + + x0 = CL_shr( inp[0], SCALEFACTOR5 ); + x1 = CL_shr( inp[1], SCALEFACTOR5 ); + x2 = CL_shr( inp[2], SCALEFACTOR5 ); + x3 = CL_shr( inp[3], SCALEFACTOR5 ); + x4 = CL_shr( inp[4], SCALEFACTOR5 ); + + y1 = CL_add( x1, x4 ); + y4 = CL_sub( x1, x4 ); + y3 = CL_add( x2, x3 ); + y2 = CL_sub( x2, x3 ); + t = CL_scale_t( CL_sub( y1, y3 ), C54 ); + y1 = CL_add( y1, y3 ); + inp[0] = CL_add( x0, y1 ); + + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + y1 = CL_add( inp[0], ( CL_shl( CL_scale_t( y1, C55 ), 1 ) ) ); + y3 = CL_sub( y1, t ); + y1 = CL_add( y1, t ); + + t = CL_scale_t( CL_add( y4, y2 ), C51 ); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + y4 = CL_add( t, CL_shl( CL_scale_t( y4, C52 ), 1 ) ); + y2 = CL_add( t, CL_scale_t( y2, C53 ) ); + + + /* combination */ + inp[1] = CL_msu_j( y1, y2 ); + inp[4] = CL_mac_j( y1, y2 ); + + inp[2] = CL_mac_j( y3, y4 ); + inp[3] = CL_msu_j( y3, y4 ); + +#if ( WMOPS ) + multiCounter[currCounter].CL_move += 5; +#endif +} + +/** + * \brief Function performs a complex 10-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR10 bits. + * + * WOPS with 32x16 bit multiplications: 196 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +static void fft10_with_cmplx_data( cmplx *inp_data ) +{ + cmplx r1, r2, r3, r4; + cmplx x0, x1, x2, x3, x4, t; + cmplx y[10]; + + /* FOR i=0 */ + { + x0 = CL_shr( inp_data[0], SCALEFACTOR10 ); + x1 = CL_shr( inp_data[2], SCALEFACTOR10 ); + x2 = CL_shr( inp_data[4], SCALEFACTOR10 ); + x3 = CL_shr( inp_data[6], SCALEFACTOR10 ); + x4 = CL_shr( inp_data[8], SCALEFACTOR10 ); + + r1 = CL_add( x3, x2 ); + r4 = CL_sub( x3, x2 ); + r3 = CL_add( x1, x4 ); + r2 = CL_sub( x1, x4 ); + t = CL_scale_t( CL_sub( r1, r3 ), C54 ); + r1 = CL_add( r1, r3 ); + y[0] = CL_add( x0, r1 ); + r1 = CL_add( y[0], ( CL_shl( CL_scale_t( r1, C55 ), 1 ) ) ); + r3 = CL_sub( r1, t ); + r1 = CL_add( r1, t ); + t = CL_scale_t( ( CL_add( r4, r2 ) ), C51 ); + r4 = CL_add( t, CL_shl( CL_scale_t( r4, C52 ), 1 ) ); + r2 = CL_add( t, CL_scale_t( r2, C53 ) ); + + + y[2] = CL_msu_j( r1, r2 ); + y[8] = CL_mac_j( r1, r2 ); + y[4] = CL_mac_j( r3, r4 ); + y[6] = CL_msu_j( r3, r4 ); + } + /* FOR i=1 */ + { + x0 = CL_shr( inp_data[5], SCALEFACTOR10 ); + x1 = CL_shr( inp_data[1], SCALEFACTOR10 ); + x2 = CL_shr( inp_data[3], SCALEFACTOR10 ); + x3 = CL_shr( inp_data[7], SCALEFACTOR10 ); + x4 = CL_shr( inp_data[9], SCALEFACTOR10 ); + + r1 = CL_add( x1, x4 ); + r4 = CL_sub( x1, x4 ); + r3 = CL_add( x3, x2 ); + r2 = CL_sub( x3, x2 ); + t = CL_scale_t( CL_sub( r1, r3 ), C54 ); + r1 = CL_add( r1, r3 ); + y[1] = CL_add( x0, r1 ); + r1 = CL_add( y[1], ( CL_shl( CL_scale_t( r1, C55 ), 1 ) ) ); + r3 = CL_sub( r1, t ); + r1 = CL_add( r1, t ); + t = CL_scale_t( ( CL_add( r4, r2 ) ), C51 ); + r4 = CL_add( t, CL_shl( CL_scale_t( r4, C52 ), 1 ) ); + r2 = CL_add( t, CL_scale_t( r2, C53 ) ); + + + y[3] = CL_msu_j( r1, r2 ); + y[9] = CL_mac_j( r1, r2 ); + y[5] = CL_mac_j( r3, r4 ); + y[7] = CL_msu_j( r3, r4 ); + } + + /* FOR i=0 */ + { + inp_data[0] = CL_add( y[0], y[1] ); + inp_data[5] = CL_sub( y[0], y[1] ); + } + /* FOR i=2 */ + { + inp_data[2] = CL_add( y[2], y[3] ); + inp_data[7] = CL_sub( y[2], y[3] ); + } + /* FOR i=4 */ + { + inp_data[4] = CL_add( y[4], y[5] ); + inp_data[9] = CL_sub( y[4], y[5] ); + } + /* FOR i=6 */ + { + inp_data[6] = CL_add( y[6], y[7] ); + inp_data[1] = CL_sub( y[6], y[7] ); + } + /* FOR i=8 */ + { + inp_data[8] = CL_add( y[8], y[9] ); + inp_data[3] = CL_sub( y[8], y[9] ); + } + +#if ( WMOPS ) + multiCounter[currCounter].CL_move += 10; +#endif +} + +/** + * \brief Function performs a complex 20-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR20 bits. + * + * WOPS with 32x16 bit multiplications: 432 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +static void fft20_with_cmplx_data( cmplx *inp_data ) +{ + cmplx r1, r2, r3, r4; + cmplx x0, x1, x2, x3, x4; + cmplx t, t0, t1, t2, t3; + cmplx y[20]; + cmplx *y0, *y1, *y2, *y3, *y4; + + y0 = y; + y1 = &y[4]; + y2 = &y[16]; + y3 = &y[8]; + y4 = &y[12]; + + { + x0 = CL_shr( inp_data[0], SCALEFACTOR20 ); + x1 = CL_shr( inp_data[16], SCALEFACTOR20 ); + x2 = CL_shr( inp_data[12], SCALEFACTOR20 ); + x3 = CL_shr( inp_data[8], SCALEFACTOR20 ); + x4 = CL_shr( inp_data[4], SCALEFACTOR20 ); + + r4 = CL_sub( x1, x4 ); + r2 = CL_sub( x2, x3 ); + r1 = CL_add( x1, x4 ); + r3 = CL_add( x2, x3 ); + t = CL_scale_t( CL_sub( r1, r3 ), C54 ); + r1 = CL_add( r1, r3 ); + y0[0] = CL_add( x0, r1 ); + r1 = CL_add( y0[0], ( CL_shl( CL_scale_t( r1, C55 ), 1 ) ) ); + r3 = CL_sub( r1, t ); + r1 = CL_add( r1, t ); + t = CL_scale_t( ( CL_add( r4, r2 ) ), C51 ); + r4 = CL_add( t, CL_shl( CL_scale_t( r4, C52 ), 1 ) ); + r2 = CL_add( t, CL_scale_t( r2, C53 ) ); + + + y1[0] = CL_msu_j( r1, r2 ); + y2[0] = CL_mac_j( r1, r2 ); + y3[0] = CL_mac_j( r3, r4 ); + y4[0] = CL_msu_j( r3, r4 ); + } + { + x0 = CL_shr( inp_data[5], SCALEFACTOR20 ); + x1 = CL_shr( inp_data[1], SCALEFACTOR20 ); + x2 = CL_shr( inp_data[17], SCALEFACTOR20 ); + x3 = CL_shr( inp_data[13], SCALEFACTOR20 ); + x4 = CL_shr( inp_data[9], SCALEFACTOR20 ); + + r4 = CL_sub( x1, x4 ); + r2 = CL_sub( x2, x3 ); + r1 = CL_add( x1, x4 ); + r3 = CL_add( x2, x3 ); + t = CL_scale_t( CL_sub( r1, r3 ), C54 ); + r1 = CL_add( r1, r3 ); + y0[1] = CL_add( x0, r1 ); + r1 = CL_add( y0[1], ( CL_shl( CL_scale_t( r1, C55 ), 1 ) ) ); + r3 = CL_sub( r1, t ); + r1 = CL_add( r1, t ); + t = CL_scale_t( ( CL_add( r4, r2 ) ), C51 ); + r4 = CL_add( t, CL_shl( CL_scale_t( r4, C52 ), 1 ) ); + r2 = CL_add( t, CL_scale_t( r2, C53 ) ); + + + y1[1] = CL_msu_j( r1, r2 ); + y2[1] = CL_mac_j( r1, r2 ); + y3[1] = CL_mac_j( r3, r4 ); + y4[1] = CL_msu_j( r3, r4 ); + } + { + x0 = CL_shr( inp_data[10], SCALEFACTOR20 ); + x1 = CL_shr( inp_data[6], SCALEFACTOR20 ); + x2 = CL_shr( inp_data[2], SCALEFACTOR20 ); + x3 = CL_shr( inp_data[18], SCALEFACTOR20 ); + x4 = CL_shr( inp_data[14], SCALEFACTOR20 ); + + r4 = CL_sub( x1, x4 ); + r2 = CL_sub( x2, x3 ); + r1 = CL_add( x1, x4 ); + r3 = CL_add( x2, x3 ); + t = CL_scale_t( CL_sub( r1, r3 ), C54 ); + r1 = CL_add( r1, r3 ); + y0[2] = CL_add( x0, r1 ); + r1 = CL_add( y0[2], ( CL_shl( CL_scale_t( r1, C55 ), 1 ) ) ); + r3 = CL_sub( r1, t ); + r1 = CL_add( r1, t ); + t = CL_scale_t( ( CL_add( r4, r2 ) ), C51 ); + r4 = CL_add( t, CL_shl( CL_scale_t( r4, C52 ), 1 ) ); + r2 = CL_add( t, CL_scale_t( r2, C53 ) ); + + + y1[2] = CL_msu_j( r1, r2 ); + y2[2] = CL_mac_j( r1, r2 ); + y3[2] = CL_mac_j( r3, r4 ); + y4[2] = CL_msu_j( r3, r4 ); + } + { + x0 = CL_shr( inp_data[15], SCALEFACTOR20 ); + x1 = CL_shr( inp_data[11], SCALEFACTOR20 ); + x2 = CL_shr( inp_data[7], SCALEFACTOR20 ); + x3 = CL_shr( inp_data[3], SCALEFACTOR20 ); + x4 = CL_shr( inp_data[19], SCALEFACTOR20 ); + + r4 = CL_sub( x1, x4 ); + r2 = CL_sub( x2, x3 ); + r1 = CL_add( x1, x4 ); + r3 = CL_add( x2, x3 ); + t = CL_scale_t( CL_sub( r1, r3 ), C54 ); + r1 = CL_add( r1, r3 ); + y0[3] = CL_add( x0, r1 ); + r1 = CL_add( y0[3], ( CL_shl( CL_scale_t( r1, C55 ), 1 ) ) ); + r3 = CL_sub( r1, t ); + r1 = CL_add( r1, t ); + t = CL_scale_t( ( CL_add( r4, r2 ) ), C51 ); + r4 = CL_add( t, CL_shl( CL_scale_t( r4, C52 ), 1 ) ); + r2 = CL_add( t, CL_scale_t( r2, C53 ) ); + + + y1[3] = CL_msu_j( r1, r2 ); + y2[3] = CL_mac_j( r1, r2 ); + y3[3] = CL_mac_j( r3, r4 ); + y4[3] = CL_msu_j( r3, r4 ); + } + + { + cmplx *ptr_y = y; + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add( Cy0, Cy2 ); + t1 = CL_sub( Cy0, Cy2 ); + t2 = CL_add( Cy1, Cy3 ); + t3 = CL_sub( Cy1, Cy3 ); + + + inp_data[0] = CL_add( t0, t2 ); + inp_data[5] = CL_msu_j( t1, t3 ); + inp_data[10] = CL_sub( t0, t2 ); + inp_data[15] = CL_mac_j( t1, t3 ); + } + + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add( Cy0, Cy2 ); + t1 = CL_sub( Cy0, Cy2 ); + t2 = CL_add( Cy1, Cy3 ); + t3 = CL_sub( Cy1, Cy3 ); + + + inp_data[4] = CL_add( t0, t2 ); + inp_data[9] = CL_msu_j( t1, t3 ); + inp_data[14] = CL_sub( t0, t2 ); + inp_data[19] = CL_mac_j( t1, t3 ); + } + + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add( Cy0, Cy2 ); + t1 = CL_sub( Cy0, Cy2 ); + t2 = CL_add( Cy1, Cy3 ); + t3 = CL_sub( Cy1, Cy3 ); + + + inp_data[8] = CL_add( t0, t2 ); + inp_data[13] = CL_msu_j( t1, t3 ); + inp_data[18] = CL_sub( t0, t2 ); + inp_data[3] = CL_mac_j( t1, t3 ); + } + + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add( Cy0, Cy2 ); + t1 = CL_sub( Cy0, Cy2 ); + t2 = CL_add( Cy1, Cy3 ); + t3 = CL_sub( Cy1, Cy3 ); + + inp_data[12] = CL_add( t0, t2 ); + inp_data[17] = CL_msu_j( t1, t3 ); + inp_data[2] = CL_sub( t0, t2 ); + inp_data[7] = CL_mac_j( t1, t3 ); + } + + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add( Cy0, Cy2 ); + t1 = CL_sub( Cy0, Cy2 ); + t2 = CL_add( Cy1, Cy3 ); + t3 = CL_sub( Cy1, Cy3 ); + + + inp_data[16] = CL_add( t0, t2 ); + inp_data[1] = CL_msu_j( t1, t3 ); + inp_data[6] = CL_sub( t0, t2 ); + inp_data[11] = CL_mac_j( t1, t3 ); + } + } +#if ( WMOPS ) + multiCounter[currCounter].CL_move += 20; +#endif +} + + +/** + * \brief Function performs a complex 30-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR30 bits. + * + * WOPS with 32x16 bit multiplications: 828 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +static void fft30_with_cmplx_data( cmplx *inp ) +{ + cmplx *l = &inp[0]; + cmplx *h = &inp[15]; + + cmplx z[30], y[15], x[15], rs1, rs2, rs3, rs4, t; + + /* 1. FFT15 stage */ + + x[0] = CL_shr( inp[0], SCALEFACTOR30_1 ); + x[1] = CL_shr( inp[18], SCALEFACTOR30_1 ); + x[2] = CL_shr( inp[6], SCALEFACTOR30_1 ); + x[3] = CL_shr( inp[24], SCALEFACTOR30_1 ); + x[4] = CL_shr( inp[12], SCALEFACTOR30_1 ); + + x[5] = CL_shr( inp[20], SCALEFACTOR30_1 ); + x[6] = CL_shr( inp[8], SCALEFACTOR30_1 ); + x[7] = CL_shr( inp[26], SCALEFACTOR30_1 ); + x[8] = CL_shr( inp[14], SCALEFACTOR30_1 ); + x[9] = CL_shr( inp[2], SCALEFACTOR30_1 ); + + x[10] = CL_shr( inp[10], SCALEFACTOR30_1 ); + x[11] = CL_shr( inp[28], SCALEFACTOR30_1 ); + x[12] = CL_shr( inp[16], SCALEFACTOR30_1 ); + x[13] = CL_shr( inp[4], SCALEFACTOR30_1 ); + x[14] = CL_shr( inp[22], SCALEFACTOR30_1 ); + + + /* 1. FFT5 stage */ + rs1 = CL_add( x[1], x[4] ); + rs4 = CL_sub( x[1], x[4] ); + rs3 = CL_add( x[2], x[3] ); + rs2 = CL_sub( x[2], x[3] ); + t = CL_scale_t( CL_sub( rs1, rs3 ), C54 ); + rs1 = CL_add( rs1, rs3 ); + y[0] = CL_add( x[0], rs1 ); + rs1 = CL_add( y[0], ( CL_shl( CL_scale_t( rs1, C55 ), 1 ) ) ); + rs3 = CL_sub( rs1, t ); + rs1 = CL_add( rs1, t ); + t = CL_scale_t( CL_add( rs4, rs2 ), C51 ); + rs4 = CL_add( t, CL_shl( CL_scale_t( rs4, C52 ), 1 ) ); + rs2 = CL_add( t, CL_scale_t( rs2, C53 ) ); + + /* combination */ + y[1] = CL_msu_j( rs1, rs2 ); + y[4] = CL_mac_j( rs1, rs2 ); + y[2] = CL_mac_j( rs3, rs4 ); + y[3] = CL_msu_j( rs3, rs4 ); + + + /* 2. FFT5 stage */ + rs1 = CL_add( x[6], x[9] ); + rs4 = CL_sub( x[6], x[9] ); + rs3 = CL_add( x[7], x[8] ); + rs2 = CL_sub( x[7], x[8] ); + t = CL_scale_t( CL_sub( rs1, rs3 ), C54 ); + rs1 = CL_add( rs1, rs3 ); + y[5] = CL_add( x[5], rs1 ); + rs1 = CL_add( y[5], ( CL_shl( CL_scale_t( rs1, C55 ), 1 ) ) ); + rs3 = CL_sub( rs1, t ); + rs1 = CL_add( rs1, t ); + t = CL_scale_t( CL_add( rs4, rs2 ), C51 ); + rs4 = CL_add( t, CL_shl( CL_scale_t( rs4, C52 ), 1 ) ); + rs2 = CL_add( t, CL_scale_t( rs2, C53 ) ); + + /* combination */ + y[6] = CL_msu_j( rs1, rs2 ); + y[9] = CL_mac_j( rs1, rs2 ); + y[7] = CL_mac_j( rs3, rs4 ); + y[8] = CL_msu_j( rs3, rs4 ); + + + /* 3. FFT5 stage */ + rs1 = CL_add( x[11], x[14] ); + rs4 = CL_sub( x[11], x[14] ); + rs3 = CL_add( x[12], x[13] ); + rs2 = CL_sub( x[12], x[13] ); + t = CL_scale_t( CL_sub( rs1, rs3 ), C54 ); + rs1 = CL_add( rs1, rs3 ); + y[10] = CL_add( x[10], rs1 ); + rs1 = CL_add( y[10], ( CL_shl( CL_scale_t( rs1, C55 ), 1 ) ) ); + rs3 = CL_sub( rs1, t ); + rs1 = CL_add( rs1, t ); + t = CL_scale_t( CL_add( rs4, rs2 ), C51 ); + rs4 = CL_add( t, CL_shl( CL_scale_t( rs4, C52 ), 1 ) ); + rs2 = CL_add( t, CL_scale_t( rs2, C53 ) ); + + /* combination */ + y[11] = CL_msu_j( rs1, rs2 ); + y[14] = CL_mac_j( rs1, rs2 ); + y[12] = CL_mac_j( rs3, rs4 ); + y[13] = CL_msu_j( rs3, rs4 ); + /*for (i=10; i<15; i++) + { + printf("%d,\t %d,\t",y[i].re, y[i].im); + } + printf("\n\n");*/ + + + /* 1. FFT3 stage */ + /* real part */ + rs1 = CL_add( y[5], y[10] ); + rs2 = CL_scale_t( CL_sub( y[5], y[10] ), C31 ); + z[0] = CL_add( y[0], rs1 ); + rs1 = CL_sub( y[0], CL_shr( rs1, 1 ) ); + + z[10] = CL_mac_j( rs1, rs2 ); + z[5] = CL_msu_j( rs1, rs2 ); + + /* 2. FFT3 stage */ + rs1 = CL_add( y[6], y[11] ); + rs2 = CL_scale_t( CL_sub( y[6], y[11] ), C31 ); + z[6] = CL_add( y[1], rs1 ); + rs1 = CL_sub( y[1], CL_shr( rs1, 1 ) ); + + z[1] = CL_mac_j( rs1, rs2 ); + z[11] = CL_msu_j( rs1, rs2 ); + + + /* 3. FFT3 stage */ + rs1 = CL_add( y[7], y[12] ); + rs2 = CL_scale_t( CL_sub( y[7], y[12] ), C31 ); + z[12] = CL_add( y[2], rs1 ); + rs1 = CL_sub( y[2], CL_shr( rs1, 1 ) ); + + z[7] = CL_mac_j( rs1, rs2 ); + z[2] = CL_msu_j( rs1, rs2 ); + + + /* 4. FFT3 stage */ + rs1 = CL_add( y[8], y[13] ); + rs2 = CL_scale_t( CL_sub( y[8], y[13] ), C31 ); + z[3] = CL_add( y[3], rs1 ); + rs1 = CL_sub( y[3], CL_shr( rs1, 1 ) ); + + z[13] = CL_mac_j( rs1, rs2 ); + z[8] = CL_msu_j( rs1, rs2 ); + + + /* 5. FFT3 stage */ + rs1 = CL_add( y[9], y[14] ); + rs2 = CL_scale_t( CL_sub( y[9], y[14] ), C31 ); + z[9] = CL_add( y[4], rs1 ); + rs1 = CL_sub( y[4], CL_shr( rs1, 1 ) ); + + z[4] = CL_mac_j( rs1, rs2 ); + z[14] = CL_msu_j( rs1, rs2 ); + + /*for (i=0; i<15; i++) + printf("%d,\t %d,\t",z[i].re, z[i].im); + printf("\n\n");*/ + + + /* 2. FFT15 stage */ + + x[0] = CL_shr( inp[15], SCALEFACTOR30_1 ); + x[1] = CL_shr( inp[3], SCALEFACTOR30_1 ); + x[2] = CL_shr( inp[21], SCALEFACTOR30_1 ); + x[3] = CL_shr( inp[9], SCALEFACTOR30_1 ); + x[4] = CL_shr( inp[27], SCALEFACTOR30_1 ); + + x[5] = CL_shr( inp[5], SCALEFACTOR30_1 ); + x[6] = CL_shr( inp[23], SCALEFACTOR30_1 ); + x[7] = CL_shr( inp[11], SCALEFACTOR30_1 ); + x[8] = CL_shr( inp[29], SCALEFACTOR30_1 ); + x[9] = CL_shr( inp[17], SCALEFACTOR30_1 ); + + x[10] = CL_shr( inp[25], SCALEFACTOR30_1 ); + x[11] = CL_shr( inp[13], SCALEFACTOR30_1 ); + x[12] = CL_shr( inp[1], SCALEFACTOR30_1 ); + x[13] = CL_shr( inp[19], SCALEFACTOR30_1 ); + x[14] = CL_shr( inp[7], SCALEFACTOR30_1 ); + + /* 1. FFT5 stage */ + rs1 = CL_add( x[1], x[4] ); + rs4 = CL_sub( x[1], x[4] ); + rs3 = CL_add( x[2], x[3] ); + rs2 = CL_sub( x[2], x[3] ); + t = CL_scale_t( CL_sub( rs1, rs3 ), C54 ); + rs1 = CL_add( rs1, rs3 ); + y[0] = CL_add( x[0], rs1 ); + rs1 = CL_add( y[0], ( CL_shl( CL_scale_t( rs1, C55 ), 1 ) ) ); + rs3 = CL_sub( rs1, t ); + rs1 = CL_add( rs1, t ); + t = CL_scale_t( CL_add( rs4, rs2 ), C51 ); + rs4 = CL_add( t, CL_shl( CL_scale_t( rs4, C52 ), 1 ) ); + rs2 = CL_add( t, CL_scale_t( rs2, C53 ) ); + + /* combination */ + y[1] = CL_msu_j( rs1, rs2 ); + y[4] = CL_mac_j( rs1, rs2 ); + y[2] = CL_mac_j( rs3, rs4 ); + y[3] = CL_msu_j( rs3, rs4 ); + + + /* 2. FFT5 stage */ + rs1 = CL_add( x[6], x[9] ); + rs4 = CL_sub( x[6], x[9] ); + rs3 = CL_add( x[7], x[8] ); + rs2 = CL_sub( x[7], x[8] ); + t = CL_scale_t( CL_sub( rs1, rs3 ), C54 ); + rs1 = CL_add( rs1, rs3 ); + y[5] = CL_add( x[5], rs1 ); + rs1 = CL_add( y[5], ( CL_shl( CL_scale_t( rs1, C55 ), 1 ) ) ); + rs3 = CL_sub( rs1, t ); + rs1 = CL_add( rs1, t ); + t = CL_scale_t( CL_add( rs4, rs2 ), C51 ); + rs4 = CL_add( t, CL_shl( CL_scale_t( rs4, C52 ), 1 ) ); + rs2 = CL_add( t, CL_scale_t( rs2, C53 ) ); + + /* combination */ + y[6] = CL_msu_j( rs1, rs2 ); + y[9] = CL_mac_j( rs1, rs2 ); + y[7] = CL_mac_j( rs3, rs4 ); + y[8] = CL_msu_j( rs3, rs4 ); + + + /* 3. FFT5 stage */ + rs1 = CL_add( x[11], x[14] ); + rs4 = CL_sub( x[11], x[14] ); + rs3 = CL_add( x[12], x[13] ); + rs2 = CL_sub( x[12], x[13] ); + t = CL_scale_t( CL_sub( rs1, rs3 ), C54 ); + rs1 = CL_add( rs1, rs3 ); + y[10] = CL_add( x[10], rs1 ); + rs1 = CL_add( y[10], ( CL_shl( CL_scale_t( rs1, C55 ), 1 ) ) ); + rs3 = CL_sub( rs1, t ); + rs1 = CL_add( rs1, t ); + t = CL_scale_t( CL_add( rs4, rs2 ), C51 ); + rs4 = CL_add( t, CL_shl( CL_scale_t( rs4, C52 ), 1 ) ); + rs2 = CL_add( t, CL_scale_t( rs2, C53 ) ); + + /* combination */ + y[11] = CL_msu_j( rs1, rs2 ); + y[14] = CL_mac_j( rs1, rs2 ); + y[12] = CL_mac_j( rs3, rs4 ); + y[13] = CL_msu_j( rs3, rs4 ); + /*for (i=10; i<15; i++) + { + printf("%d,\t %d,\t",y[i].re, y[i].im); + } + printf("\n\n");*/ + + + /* 1. FFT3 stage */ + /* real part */ + rs1 = CL_add( y[5], y[10] ); + rs2 = CL_scale_t( CL_sub( y[5], y[10] ), C31 ); + z[15] = CL_add( y[0], rs1 ); + rs1 = CL_sub( y[0], CL_shr( rs1, 1 ) ); + + z[25] = CL_mac_j( rs1, rs2 ); + z[20] = CL_msu_j( rs1, rs2 ); + + /* 2. FFT3 stage */ + rs1 = CL_add( y[6], y[11] ); + rs2 = CL_scale_t( CL_sub( y[6], y[11] ), C31 ); + z[21] = CL_add( y[1], rs1 ); + rs1 = CL_sub( y[1], CL_shr( rs1, 1 ) ); + + z[16] = CL_mac_j( rs1, rs2 ); + z[26] = CL_msu_j( rs1, rs2 ); + + + /* 3. FFT3 stage */ + rs1 = CL_add( y[7], y[12] ); + rs2 = CL_scale_t( CL_sub( y[7], y[12] ), C31 ); + z[27] = CL_add( y[2], rs1 ); + rs1 = CL_sub( y[2], CL_shr( rs1, 1 ) ); + + z[22] = CL_mac_j( rs1, rs2 ); + z[17] = CL_msu_j( rs1, rs2 ); + + + /* 4. FFT3 stage */ + rs1 = CL_add( y[8], y[13] ); + rs2 = CL_scale_t( CL_sub( y[8], y[13] ), C31 ); + z[18] = CL_add( y[3], rs1 ); + rs1 = CL_sub( y[3], CL_shr( rs1, 1 ) ); + + z[28] = CL_mac_j( rs1, rs2 ); + z[23] = CL_msu_j( rs1, rs2 ); + + + /* 5. FFT3 stage */ + rs1 = CL_add( y[9], y[14] ); + rs2 = CL_scale_t( CL_sub( y[9], y[14] ), C31 ); + z[24] = CL_add( y[4], rs1 ); + rs1 = CL_sub( y[4], CL_shr( rs1, 1 ) ); + + z[19] = CL_mac_j( rs1, rs2 ); + z[29] = CL_msu_j( rs1, rs2 ); + + /*for (i=0; i<30; i++) + printf("%d,\t %d,\t",z[i].re, z[i].im); + printf("\n\n");*/ + + + /* 1. FFT2 stage */ + rs1 = CL_shr( z[0], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[15], SCALEFACTOR30_2 ); + *l = CL_add( rs1, rs2 ); + *h = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 2. FFT2 stage */ + rs1 = CL_shr( z[8], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[23], SCALEFACTOR30_2 ); + *h = CL_add( rs1, rs2 ); + *l = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + + /* 3. FFT2 stage */ + rs1 = CL_shr( z[1], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[16], SCALEFACTOR30_2 ); + *l = CL_add( rs1, rs2 ); + *h = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + + /* 4. FFT2 stage */ + rs1 = CL_shr( z[9], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[24], SCALEFACTOR30_2 ); + *h = CL_add( rs1, rs2 ); + *l = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 5. FFT2 stage */ + rs1 = CL_shr( z[2], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[17], SCALEFACTOR30_2 ); + *l = CL_add( rs1, rs2 ); + *h = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 6. FFT2 stage */ + rs1 = CL_shr( z[10], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[25], SCALEFACTOR30_2 ); + *h = CL_add( rs1, rs2 ); + *l = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 7. FFT2 stage */ + rs1 = CL_shr( z[3], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[18], SCALEFACTOR30_2 ); + *l = CL_add( rs1, rs2 ); + *h = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 8. FFT2 stage */ + rs1 = CL_shr( z[11], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[26], SCALEFACTOR30_2 ); + *h = CL_add( rs1, rs2 ); + *l = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 9. FFT2 stage */ + rs1 = CL_shr( z[4], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[19], SCALEFACTOR30_2 ); + *l = CL_add( rs1, rs2 ); + *h = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 10. FFT2 stage */ + rs1 = CL_shr( z[12], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[27], SCALEFACTOR30_2 ); + *h = CL_add( rs1, rs2 ); + *l = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 11. FFT2 stage */ + rs1 = CL_shr( z[5], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[20], SCALEFACTOR30_2 ); + *l = CL_add( rs1, rs2 ); + *h = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 12. FFT2 stage */ + rs1 = CL_shr( z[13], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[28], SCALEFACTOR30_2 ); + *h = CL_add( rs1, rs2 ); + *l = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 13. FFT2 stage */ + rs1 = CL_shr( z[6], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[21], SCALEFACTOR30_2 ); + *l = CL_add( rs1, rs2 ); + *h = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 14. FFT2 stage */ + rs1 = CL_shr( z[14], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[29], SCALEFACTOR30_2 ); + *h = CL_add( rs1, rs2 ); + *l = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + + /* 15. FFT2 stage */ + rs1 = CL_shr( z[7], SCALEFACTOR30_2 ); + rs2 = CL_shr( z[22], SCALEFACTOR30_2 ); + *l = CL_add( rs1, rs2 ); + *h = CL_sub( rs1, rs2 ); + l += 1; + h += 1; + +#if ( WMOPS ) + multiCounter[currCounter].CL_move += 30; +#endif +} + +/*-------------------------------------------------------------------* + * fft_cldfb_fx() + * + * Interface functions FFT subroutines + *--------------------------------------------------------------------*/ +void fft_cldfb_fx( + Word32 *data, /* i/o: input/output vector */ + const Word16 size /* size of fft operation */ +) +{ + + SWITCH( size ) + { + case 5: + fft5_with_cmplx_data( (cmplx *) data ); + BREAK; + case 8: + fft8_with_cmplx_data( (cmplx *) data ); + BREAK; + case 10: + fft10_with_cmplx_data( (cmplx *) data ); + BREAK; + case 16: + fft16_with_cmplx_data( (cmplx *) data, 0 ); + BREAK; + case 20: + fft20_with_cmplx_data( (cmplx *) data ); + BREAK; + case 30: + fft30_with_cmplx_data( (cmplx *) data ); + BREAK; + + default: + assert( 0 ); + BREAK; + } + + return; +} + +void fft16_with_cmplx_data( cmplx *input, Word16 bScale ) +{ + cmplx x0, x1, x2, x3, temp; + cmplx t0, t2, t4, t6, t7; + cmplx y[16]; + + IF( bScale ) + { + { + x0 = CL_shr( input[0], SCALEFACTOR16 ); + x1 = CL_shr( input[4], SCALEFACTOR16 ); + x2 = CL_shr( input[8], SCALEFACTOR16 ); + x3 = CL_shr( input[12], SCALEFACTOR16 ); + t0 = CL_add( x0, x2 ); + t2 = CL_sub( x0, x2 ); + t4 = CL_add( x1, x3 ); + t6 = CL_sub( x1, x3 ); + t6 = CL_mul_j( t6 ); + y[0] = CL_add( t0, t4 ); + y[1] = CL_sub( t2, t6 ); + y[2] = CL_sub( t0, t4 ); + y[3] = CL_add( t2, t6 ); + + + x0 = CL_shr( input[1], SCALEFACTOR16 ); + x1 = CL_shr( input[5], SCALEFACTOR16 ); + x2 = CL_shr( input[9], SCALEFACTOR16 ); + x3 = CL_shr( input[13], SCALEFACTOR16 ); + t0 = CL_add( x0, x2 ); + t2 = CL_sub( x0, x2 ); + t4 = CL_add( x1, x3 ); + t6 = CL_sub( x1, x3 ); + t6 = CL_mul_j( t6 ); + y[4] = CL_add( t0, t4 ); + y[5] = CL_sub( t2, t6 ); + y[6] = CL_sub( t0, t4 ); + y[7] = CL_add( t2, t6 ); + + + x0 = CL_shr( input[2], SCALEFACTOR16 ); + x1 = CL_shr( input[6], SCALEFACTOR16 ); + x2 = CL_shr( input[10], SCALEFACTOR16 ); + x3 = CL_shr( input[14], SCALEFACTOR16 ); + t0 = CL_add( x0, x2 ); + t2 = CL_sub( x0, x2 ); + t4 = CL_add( x1, x3 ); + t6 = CL_sub( x1, x3 ); + t6 = CL_mul_j( t6 ); + y[8] = CL_add( t0, t4 ); + y[9] = CL_sub( t2, t6 ); + y[10] = CL_sub( t4, t0 ); + y[10] = CL_mul_j( y[10] ); + y[11] = CL_add( t2, t6 ); + + + x0 = CL_shr( input[3], SCALEFACTOR16 ); + x1 = CL_shr( input[7], SCALEFACTOR16 ); + x2 = CL_shr( input[11], SCALEFACTOR16 ); + x3 = CL_shr( input[15], SCALEFACTOR16 ); + t0 = CL_add( x0, x2 ); + t2 = CL_sub( x0, x2 ); + t4 = CL_add( x1, x3 ); + t6 = CL_sub( x1, x3 ); + t6 = CL_mul_j( t6 ); + y[12] = CL_add( t0, t4 ); + y[13] = CL_sub( t2, t6 ); + y[14] = CL_sub( t0, t4 ); + y[15] = CL_add( t2, t6 ); + } + } + else + { + { + t0 = CL_add( input[0], input[8] ); + t2 = CL_sub( input[0], input[8] ); + t4 = CL_add( input[4], input[12] ); + t7 = CL_sub( input[4], input[12] ); + + y[0] = CL_add( t0, t4 ); + y[1] = CL_msu_j( t2, t7 ); + y[2] = CL_sub( t0, t4 ); + y[3] = CL_mac_j( t2, t7 ); + } + /* i=1 */ + { + t0 = CL_add( input[1], input[9] ); + t2 = CL_sub( input[1], input[9] ); + t4 = CL_add( input[5], input[13] ); + t7 = CL_sub( input[5], input[13] ); + + y[4] = CL_add( t0, t4 ); + y[5] = CL_msu_j( t2, t7 ); + y[6] = CL_sub( t0, t4 ); + y[7] = CL_mac_j( t2, t7 ); + } + /* i=2 */ + { + t0 = CL_add( input[2], input[10] ); + t2 = CL_sub( input[2], input[10] ); + t4 = CL_add( input[6], input[14] ); + t7 = CL_sub( input[6], input[14] ); + + y[8] = CL_add( t0, t4 ); + y[9] = CL_msu_j( t2, t7 ); + temp = CL_sub( t0, t4 ); + y[10] = CL_negate( CL_mul_j( temp ) ); + y[11] = CL_mac_j( t2, t7 ); + } + /* i=3 */ + { + t0 = CL_add( input[3], input[11] ); + t2 = CL_sub( input[3], input[11] ); + t4 = CL_add( input[7], input[15] ); + t7 = CL_sub( input[7], input[15] ); + + y[12] = CL_add( t0, t4 ); + y[13] = CL_msu_j( t2, t7 ); + y[14] = CL_sub( t0, t4 ); + y[15] = CL_mac_j( t2, t7 ); + } + } + + x0 = CL_scale_t( y[11], C162 ); + y[11] = CL_mac_j( x0, x0 ); + + x0 = CL_scale_t( y[14], C162 ); + y[14] = CL_mac_j( x0, x0 ); + + x0 = CL_scale_t( y[6], C161 ); + y[6] = CL_msu_j( x0, x0 ); + + x0 = CL_scale_t( y[9], C161 ); + y[9] = CL_msu_j( x0, x0 ); + + y[5] = CL_mac_j( CL_scale_t( y[5], C163 ), CL_scale_t( y[5], C166 ) ); + y[7] = CL_mac_j( CL_scale_t( y[7], C165 ), CL_scale_t( y[7], C164 ) ); + y[13] = CL_mac_j( CL_scale_t( y[13], C165 ), CL_scale_t( y[13], C164 ) ); + y[15] = CL_mac_j( CL_scale_t( y[15], C164 ), CL_scale_t( y[15], C165 ) ); + + + /* i=0 */ + { + t0 = CL_add( y[0], y[8] ); + t2 = CL_sub( y[0], y[8] ); + t4 = CL_add( y[4], y[12] ); + t7 = CL_sub( y[4], y[12] ); + + input[0] = CL_add( t0, t4 ); + input[4] = CL_msu_j( t2, t7 ); + input[8] = CL_sub( t0, t4 ); + input[12] = CL_mac_j( t2, t7 ); + } + /* i=1 */ + { + t0 = CL_add( y[1], y[9] ); + t2 = CL_sub( y[1], y[9] ); + t4 = CL_add( y[5], y[13] ); + t7 = CL_sub( y[5], y[13] ); + + input[1] = CL_add( t0, t4 ); + input[5] = CL_msu_j( t2, t7 ); + input[9] = CL_sub( t0, t4 ); + input[13] = CL_mac_j( t2, t7 ); + } + /* i=2 */ + { + t0 = CL_add( y[2], y[10] ); + t2 = CL_sub( y[2], y[10] ); + t4 = CL_add( y[6], y[14] ); + t7 = CL_sub( y[6], y[14] ); + + input[2] = CL_add( t0, t4 ); + input[6] = CL_msu_j( t2, t7 ); + input[10] = CL_sub( t0, t4 ); + input[14] = CL_mac_j( t2, t7 ); + } + /* i=3 */ + { + t0 = CL_add( y[3], y[11] ); + t2 = CL_sub( y[3], y[11] ); + t4 = CL_add( y[7], y[15] ); + t7 = CL_sub( y[7], y[15] ); + + input[3] = CL_add( t0, t4 ); + input[7] = CL_msu_j( t2, t7 ); + input[11] = CL_sub( t0, t4 ); + input[15] = CL_mac_j( t2, t7 ); + } +#if ( WMOPS ) + multiCounter[currCounter].CL_move += 16; +#endif +} diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c new file mode 100644 index 000000000..a0e2e54b2 --- /dev/null +++ b/lib_com/float_to_fix_ops.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include "options.h" +#include "prot.h" +#include "prot_fx2.h" +#include "basop_settings.h" +#include + +Word32 floatToFixed( float f, Word16 Q ) +{ + if ( f == 1.0f && Q == Q15 ) + return MAX16B; + if ( f == 1.0f && Q == Q31 ) + return MAXVAL_WORD32; + if ( Q < 0 ) + return (Word32) ( (float) ( f ) / (float) ( ( (unsigned) 1 ) << ( -Q ) ) + ( f >= 0 ? 0.5 : -0.5 ) ); + else + return (Word32) ( f * (float) ( (unsigned int) 1 << Q ) + ( f >= 0 ? 0.5 : -0.5 ) ); +} + +float fixedToFloat( Word32 i, Word16 Q ) +{ + if ( Q < 0 ) + return ( i * (float) ( ( (unsigned) 1 ) << ( -Q ) ) ); + else + return (float) ( i ) / (float) ( (unsigned int) 1 << Q ); +} +void floatToFixed_arrL( float *f, Word32 *i, Word16 Q, Word16 l ) +{ + for ( int j = 0; j < l; j++ ) + { + Word64 i64_val = floatToFixed( f[j], Q ); + IF( i64_val > MAX_32 ) + { + i64_val = MAX_32; + } + ELSE IF( i64_val < MIN_32 ) + { + i64_val = MIN_32; + } + i[j] = (Word32) i64_val; + } +} +void floatToFixed_arr( float *f, Word16 *i, Word16 Q, Word16 l ) +{ + for ( int j = 0; j < l; j++ ) + { + Word32 i32_val = floatToFixed( f[j], Q ); + IF( i32_val > MAX_16 ) + { + i32_val = MAX_16; + } + ELSE IF( i32_val < MIN_16 ) + { + i32_val = MIN_16; + } + i[j] = (Word16) i32_val; + } +} +void fixedToFloat_arrL( Word32 *i, float *f, Word16 Q, Word16 l ) +{ + for ( int j = 0; j < l; j++ ) + { + f[j] = fixedToFloat( i[j], Q ); + } +} +void fixedToFloat_arr( Word16 *i, float *f, Word16 Q, Word16 l ) +{ + for ( int j = 0; j < l; j++ ) + { + f[j] = fixedToFloat( i[j], Q ); + } +} +Word16 Q_factor( float x ) +{ + Word16 Q = 15; + if ( x >= 1 || x <= -1 ) + Q = norm_s( (Word16) x ); + return Q; +} +Word16 Q_factor_L( float x ) +{ + Word16 Q = 31; + if ( x >= 1 || x <= -1 ) + Q = norm_l( (Word32) fabs( x ) ); + return Q; +} +Word16 Q_factor_arr( float *x, Word16 l ) +{ + Word16 Q = 15; + for ( int i = 0; i < l; i++ ) + { + if ( x[i] >= 1 || x[i] <= -1 ) + Q = s_min( Q, norm_s( (Word16) x[i] ) ); + } + return Q; +} +Word16 Q_factor_arrL( float *x, Word16 l ) +{ + Word16 Q = 31; + for ( int i = 0; i < l; i++ ) + { + if ( x[i] >= 1 || x[i] <= -1 ) + Q = s_min( Q, norm_l( (Word32) fabs( x[i] ) ) ); + } + return Q; +} diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 4c1ada713..0650dbd4b 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -47,6 +47,9 @@ #define PI_OVER_180 ( EVS_PI / 180.0f ) #define _180_OVER_PI ( 180.0f / EVS_PI ) +#define EVS_PI_FX_Q13 25736 /* pi in Q13 */ +#define _180_OVER_PI_FX (Word32) (( 180.0f / EVS_PI ) *1024) + #define SQRT2 1.414213562373095f #define SQRT2_OVER_2 (SQRT2 / 2.0f) diff --git a/lib_com/ivas_limiter.c b/lib_com/ivas_limiter.c index a4cf152df..6cf3d3c7b 100644 --- a/lib_com/ivas_limiter.c +++ b/lib_com/ivas_limiter.c @@ -38,6 +38,215 @@ #include "wmc_auto.h" #include +#define ATTACK_CNST_48k ( 2106670080 ) // Q31 +#define ATTACK_CNST_32k ( 2086555136 ) // Q31 +#define ATTACK_CNST_16k ( 2027355264 ) // Q31 +#define ATTACK_CNST_8k ( 1913946752 ) // Q31 +Word32 release_cnst_table[201] = // Q31 + { + 2106670080, + 2107727232, + 2108757120, + 2109760640, + 2110738432, + 2111691008, + 2112619136, + 2113523328, + 2114404352, + 2115262592, + 2116098816, + 2116913408, + 2117707136, + 2118480256, + 2119233536, + 2119967360, + 2120682240, + 2121378688, + 2122057088, + 2122717952, + 2123361792, + 2123988992, + 2124599936, + 2125195136, + 2125774848, + 2126339584, + 2126889728, + 2127425536, + 2127947520, + 2128456064, + 2128951296, + 2129433856, + 2129903744, + 2130361600, + 2130807424, + 2131241728, + 2131664768, + 2132076928, + 2132478208, + 2132869248, + 2133250048, + 2133620992, + 2133982208, + 2134334080, + 2134676864, + 2135010688, + 2135335936, + 2135652608, + 2135961088, + 2136261504, + 2136554112, + 2136839168, + 2137116800, + 2137387136, + 2137650560, + 2137907072, + 2138156928, + 2138400256, + 2138637184, + 2138867968, + 2139092864, + 2139311744, + 2139524992, + 2139732736, + 2139934976, + 2140131968, + 2140323840, + 2140510720, + 2140692736, + 2140870016, + 2141042688, + 2141210752, + 2141374592, + 2141534080, + 2141689344, + 2141840640, + 2141987968, + 2142131456, + 2142271232, + 2142407424, + 2142539904, + 2142669056, + 2142794752, + 2142917248, + 2143036544, + 2143152640, + 2143265792, + 2143375872, + 2143483264, + 2143587712, + 2143689472, + 2143788544, + 2143885056, + 2143979136, + 2144070656, + 2144159872, + 2144246656, + 2144331264, + 2144413568, + 2144493824, + 2144571904, + 2144647936, + 2144722048, + 2144794240, + 2144864512, + 2144932864, + 2144999552, + 2145064448, + 2145127680, + 2145189248, + 2145249152, + 2145307520, + 2145364480, + 2145419776, + 2145473792, + 2145526272, + 2145577472, + 2145627264, + 2145675776, + 2145723008, + 2145768960, + 2145813760, + 2145857408, + 2145899904, + 2145941376, + 2145981696, + 2146020864, + 2146059136, + 2146096384, + 2146132608, + 2146167936, + 2146202368, + 2146235776, + 2146268416, + 2146300160, + 2146331136, + 2146361216, + 2146390528, + 2146419200, + 2146446976, + 2146474112, + 2146500480, + 2146526208, + 2146551168, + 2146575488, + 2146599296, + 2146622464, + 2146644864, + 2146666880, + 2146688128, + 2146708992, + 2146729216, + 2146748928, + 2146768128, + 2146786816, + 2146805120, + 2146822784, + 2146840064, + 2146856960, + 2146873344, + 2146889216, + 2146904832, + 2146919936, + 2146934656, + 2146948992, + 2146962944, + 2146976640, + 2146989824, + 2147002752, + 2147015296, + 2147027584, + 2147039488, + 2147051136, + 2147062400, + 2147073408, + 2147084160, + 2147094528, + 2147104768, + 2147114624, + 2147124352, + 2147133696, + 2147142912, + 2147151744, + 2147160448, + 2147168896, + 2147177088, + 2147185152, + 2147192960, + 2147200512, + 2147207936, + 2147215104, + 2147222144, + 2147229056, + 2147235712, + 2147242112, + 2147248384, + 2147254656, + 2147260544, + 2147266432, + 2147272064, + 2147277568, + + }; /*-------------------------------------------------------------------* * detect_strong_saturations() @@ -94,6 +303,60 @@ static int16_t detect_strong_saturations( return apply_strong_limiting; } +/*! r: apply_strong_limiting flag */ +static Word16 detect_strong_saturations_fx( + const Word16 BER_detect, /* i : BER detect flag */ + Word16 *strong_saturation_cnt, /* i/o: counter of strong saturations */ + const Word32 max_val, /* i : maximum absolute value */ + Word32 *frame_gain, /* i/o: frame gain value */ + Word16 q_factor /*Q factor of the output samples*/ +) +{ + Word16 apply_strong_limiting; + Word64 compare_max_value_Mul_3, compare_max_value_Mul_10; + + apply_strong_limiting = 0; + compare_max_value_Mul_3 = W_shl( 98187, q_factor ); // 3 * IVAS_LIMITER_THRESHOLD + compare_max_value_Mul_10 = W_shl( 327290, q_factor ); // 10 * IVAS_LIMITER_THRESHOLD + IF( BER_detect ) + { + *strong_saturation_cnt = 50; + apply_strong_limiting = 1; + } + ELSE IF( GT_64( max_val, compare_max_value_Mul_3 ) && GT_16( *strong_saturation_cnt, 0 ) ) + { + apply_strong_limiting = 1; + } + ELSE IF( GT_64( max_val, compare_max_value_Mul_10 ) ) + { + *strong_saturation_cnt += 20; + *strong_saturation_cnt = min( *strong_saturation_cnt, 50 ); + apply_strong_limiting = 1; + } + else + { + ( *strong_saturation_cnt )--; + *strong_saturation_cnt = max( *strong_saturation_cnt, 0 ); + } + + if ( apply_strong_limiting ) + { + IF( LT_32( *frame_gain, 322122547 ) ) // Q30 of 0.3 is compared + { + //*frame_gain /= 3.0f;, + Word16 exp; + Word16 tmp = BASOP_Util_Divide3216_Scale( *frame_gain, 24576, &exp ); + *frame_gain = L_shl( tmp, exp + 14 ); // Q30 + } + ELSE + { + apply_strong_limiting = 0; + } + } + + return apply_strong_limiting; +} + /*-------------------------------------------------------------------* * ivas_limiter_open() * @@ -101,6 +364,70 @@ static int16_t detect_strong_saturations( *-------------------------------------------------------------------*/ /*! r : limiter struct handle */ +ivas_error ivas_limiter_open_splitRend( + IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ + const Word16 max_num_channels, /* i : maximum number of I/O channels to be processed */ + const Word32 sampling_rate /* i : sampling rate for processing */ +) +{ + Word16 i; + IVAS_LIMITER_HANDLE hLimiter; + Word32 attack_cnst_fx = 0; + + IF( max_num_channels <= 0 || sampling_rate <= 0 ) + { + return ( IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Wrong parameters for Limiter\n" ) ); + } + + IF( ( hLimiter = malloc( sizeof( IVAS_LIMITER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Limiter handle\n" ) ); + } + + hLimiter->max_num_channels = max_num_channels; + hLimiter->num_channels = max_num_channels; + + IF( ( hLimiter->channel_ptrs_fx = malloc( max_num_channels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Limiter handle\n" ) ); + } + + hLimiter->sampling_rate = sampling_rate; + hLimiter->gain_fx = ONE_IN_Q30; + hLimiter->release_heuristic_fx = 0; + SWITCH( sampling_rate ) + { + case 48000: + attack_cnst_fx = ATTACK_CNST_48k; + BREAK; + case 32000: + attack_cnst_fx = ATTACK_CNST_32k; + BREAK; + case 16000: + attack_cnst_fx = ATTACK_CNST_16k; + BREAK; + case 8000: + attack_cnst_fx = ATTACK_CNST_8k; + BREAK; + default: + assert( 0 ); + } + hLimiter->attack_constant_fx = attack_cnst_fx; + + hLimiter->strong_saturation_count = 0; +#ifdef DEBUGGING + hLimiter->cnt_frames_limited = 0; +#endif + + FOR( i = 0; i < max_num_channels; ++i ) + { + hLimiter->channel_ptrs_fx[i] = NULL; + } + + *hLimiter_out = hLimiter; + + return IVAS_ERR_OK; +} ivas_error ivas_limiter_open( IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ const int16_t max_num_channels, /* i : maximum number of I/O channels to be processed */ @@ -127,6 +454,7 @@ ivas_error ivas_limiter_open( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Limiter handle\n" ) ); } + hLimiter->sampling_rate = sampling_rate; hLimiter->gain = 1.f; hLimiter->release_heuristic = 0.f; @@ -146,13 +474,26 @@ ivas_error ivas_limiter_open( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ivas_limiter_close() * * Deallocate limiter struct *-------------------------------------------------------------------*/ +void ivas_limiter_close_splitRend( + IVAS_LIMITER_HANDLE *phLimiter /* i/o: pointer to limiter handle, can be NULL */ +) +{ + IF( phLimiter == NULL || *phLimiter == NULL ) + { + return; + } + + free( ( *phLimiter )->channel_ptrs_fx ); + free( *phLimiter ); + *phLimiter = NULL; + return; +} void ivas_limiter_close( IVAS_LIMITER_HANDLE *phLimiter /* i/o: pointer to limiter handle, can be NULL */ ) @@ -217,7 +558,179 @@ void ivas_limiter_dec( * Consider using a wrapper function like ivas_limiter_dec() instead * of calling this directly. *-------------------------------------------------------------------*/ +void limiter_process_fx( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + const Word16 output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ + const Word32 threshold, /* i : signal amplitude above which limiting starts to be applied */ + const Word16 BER_detect, /* i : BER detect flag */ + Word16 *strong_saturation_cnt, /* i/o: counter of strong saturations (can be NULL) */ + Word16 q_factor /*Q factor of output samples*/ +) +{ + Word16 i, c; + Word32 tmp, max_val; + Word32 *sample; + Word32 releaseHeuristic, releaseHeuristic_cnst, releaseHeuristic_cnst_2; + Word16 apply_limiting, apply_strong_limiting; + Word32 **output; + Word16 num_channels, q_fact_gain, scale, result; + Word32 release_constant, compare_value; + Word32 div32, gain, frame_gain, attack_constant; + + /* return early if given nonsensical values */ + IF( hLimiter == NULL || output_frame <= 0 ) + { + return; + } + + apply_limiting = 1; + apply_strong_limiting = 0; + gain = hLimiter->gain_fx; + output = hLimiter->channel_ptrs_fx; + num_channels = hLimiter->num_channels; + // sampling_rate = hLimiter->sampling_rate; + attack_constant = hLimiter->attack_constant_fx; + /*-----------------------------------------------------------------* + * Find highest absolute peak sample value + *-----------------------------------------------------------------*/ + + max_val = 0; + + FOR( i = 0; i < output_frame; i++ ) + { + FOR( c = 0; c < num_channels; c++ ) + { + tmp = L_abs( output[c][i] ); + IF( GT_32( tmp, max_val ) ) + { + max_val = tmp; + } + } + } + + /* Release heuristic + * + * Value ranging from 0.f to 1.f. Increases on each frame that contains + * a sample with a value above threshold and decreases on each frame + * with all sample values below threshold. + * + * Values of 0 and 1 map to the shortest and longest release time, respectively. + * + * The goal of this heuristic is to avoid the "pumping" effect when only + * sharp transients exceed the threshold (use short release time), but also + * keep the gain curve smoother if the threshold is exceeded in many frames + * in a short span of time. + */ + SWITCH( output_frame ) + { + case 960: + case 640: + case 320: + case 160: + releaseHeuristic_cnst = 85899345; + releaseHeuristic_cnst_2 = 21474836; + break; + default: + releaseHeuristic_cnst = 21474836; + releaseHeuristic_cnst_2 = 5368709; + break; + } + releaseHeuristic = hLimiter->release_heuristic_fx; + q_fact_gain = Q30; + + IF( GT_32( max_val, threshold ) ) + { + Word16 exp; + tmp = BASOP_Util_Divide3232_Scale( threshold, max_val, &exp ); + frame_gain = L_shl( tmp, exp + 15 ); // to q30 + releaseHeuristic = min( ONE_IN_Q30, L_add( releaseHeuristic, releaseHeuristic_cnst ) ); // releaseHeuristic_cnst is Q30 of ( 4.f * output_frame / sampling_rate ) + // release_constant = powf( 0.01f, 1.0f / ( 0.005f * powf( 200.f, .08 ) * sampling_rate ) ); + /* Unoptimized code for reference */ + /* releaseHeuristic = min( 1.f, releaseHeuristic + ( (float) 2.f * output_frame / sampling_rate / adaptiveReleaseWindowLengthInSeconds ) ); + * ^ + * React faster when release time should be increased + */ + } + ELSE + { + releaseHeuristic = max( 0, L_sub( releaseHeuristic, releaseHeuristic_cnst_2 ) ); // releaseHeuristic_cnst_2 is Q30 of output_frame / sampling_rate ) + /* Unoptimized code for reference */ + /*releaseHeuristic = max( 0.f, releaseHeuristic - ( (float) 0.5f * output_frame / sampling_rate / adaptiveReleaseWindowLengthInSeconds ) ); + * ^ + * React slower when release time should be decreased + */ + /* No samples above threshold and gain from previous frame is already 1.f, + * therefore gain == 1.f for the entire frame. Skip processing. */ + IF( GE_32( gain, ( L_shl( 1, q_fact_gain ) ) ) ) + { + apply_limiting = 0; + } + /* No samples above threshold but gain from previous frame is not 1.f, + * transition to gain == 1.f */ + frame_gain = L_shl( 1, q_fact_gain ); + } + /* Detection of very strong saturations */ + if ( strong_saturation_cnt != NULL ) + { + apply_strong_limiting = detect_strong_saturations_fx( BER_detect, strong_saturation_cnt, max_val, &frame_gain, q_factor ); + } + compare_value = 107374182; // Q30 of 0.1f + /* Limit gain reduction to 20dB. Any peaks that require gain reduction + * higher than this are most likely due to bit errors during decoding */ + IF( LT_32( frame_gain, compare_value ) && !apply_strong_limiting ) + { + frame_gain = compare_value; + } + + if ( apply_limiting ) + { + /* 99% time constants of the gain curve + * + * The denominator of the second argument determines after how many + * samples the gain curve will reach 99% of its target value + */ + div32 = 5368709; // Q30 of 0.005 which is the lowest values for (output_frame / sampling_rate) + + result = BASOP_Util_Divide3232_Scale( releaseHeuristic, div32, &scale ); + release_constant = release_cnst_table[shr( result, ( 15 - scale ) )]; + /* Unoptimized code for reference */ + /* releaseTimeInSeconds = 0.005f * powf(200.f, releaseHeuristic); <-- Map heuristic value (0; 1) exponentially to range (0.005; 1) + * release_constant = powf( 0.01f, 1.0f / ( releaseTimeInSeconds * sampling_rate ) ); + */ + + /*-----------------------------------------------------------------* + * Apply limiting + *-----------------------------------------------------------------*/ + + FOR( i = 0; i < output_frame; i++ ) + { + /* Update gain */ + IF( LT_32( frame_gain, gain ) ) + { + gain = L_add( Mpy_32_32( attack_constant, ( L_sub( gain, frame_gain ) ) ), frame_gain ); // q30 + } + ELSE + { + gain = L_add( Mpy_32_32( release_constant, ( L_sub( gain, frame_gain ) ) ), frame_gain ); // q30 + } + + FOR( c = 0; c < num_channels; c++ ) + { + sample = &output[c][i]; + + /* Apply gain */ + *sample = Mpy_32_32( L_shl( *sample, 1 ), gain ); // q_factor + } + } + } + + /* Save last gain and release heuristic values for next frame */ + hLimiter->gain_fx = gain; + hLimiter->release_heuristic_fx = releaseHeuristic; + + return; +} void limiter_process( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 36c0e29a5..b4d880e4c 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -46,6 +46,11 @@ #include "ivas_stat_com.h" #include "ivas_error_utils.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "enh64.h" +#include "basop32.h" + /* clang-format off */ /*----------------------------------------------------------------------------------* @@ -5963,6 +5968,12 @@ int16_t ivas_get_num_bands_from_bw_idx( const int16_t bwidth /* i : audio bandwidth */ ); +void Euler2Quat_fx( + const Word32 yaw, /* i : yaw (x) Q22 */ + const Word32 pitch, /* i : pitch (y) Q22 */ + const Word32 roll, /* i : roll (z) Q22 */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +); void Euler2Quat( const float yaw, /* i : yaw (x) */ const float pitch, /* i : pitch (y) */ @@ -5970,6 +5981,10 @@ void Euler2Quat( IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ ); +Word32 deg2rad_fx( + Word32 degrees +); + float deg2rad( float degrees ); @@ -5981,18 +5996,31 @@ void Quat2EulerDegree( float *pitch, /* o : pitch */ float *roll /* o : roll */ ); +void Quat2EulerDegree_fx( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + Word32 *yaw_fx, /* o : yaw */ + Word32 *pitch_fx, /* o : pitch */ + Word32 *roll_fx /* o : roll */ +); #endif /*----------------------------------------------------------------------------------* * Limiter prototypes *----------------------------------------------------------------------------------*/ - +ivas_error ivas_limiter_open_splitRend( + IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ + const Word16 max_num_channels, /* i : maximum number of I/O channels to be processed */ + const Word32 sampling_rate /* i : sampling rate for processing */ +); ivas_error ivas_limiter_open( IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ const int16_t num_channels, /* i : number of I/O channels */ const int32_t sampling_rate /* i : sampling rate for processing */ ); +void ivas_limiter_close_splitRend( + IVAS_LIMITER_HANDLE *phLimiter /* i/o: pointer to limiter handle, can be NULL */ +); void ivas_limiter_close( IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ ); @@ -6006,6 +6034,14 @@ void ivas_limiter_dec const int16_t BER_detect /* i : BER detect flag */ ); +void limiter_process_fx( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + const Word16 output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ + const Word32 threshold, /* i : signal amplitude above which limiting starts to be applied */ + const Word16 BER_detect, /* i : BER detect flag */ + Word16 *strong_saturation_cnt, /* i/o: counter of strong saturations (can be NULL) */ + Word16 q_factor /*Q factor of output samples*/ +); void limiter_process( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ diff --git a/lib_com/ivas_rotation_com.c b/lib_com/ivas_rotation_com.c index eb9eb61c3..9aa772c34 100644 --- a/lib_com/ivas_rotation_com.c +++ b/lib_com/ivas_rotation_com.c @@ -42,13 +42,35 @@ #include "debug.h" #endif #include "wmc_auto.h" - +#include "prot_fx2.h" +#include "basop_mpy.h" +#include "basop_util.h" +#include "enh64.h" /*------------------------------------------------------------------------- * Euler2Quat() * * Calculate corresponding Quaternion from Euler angles in radians *------------------------------------------------------------------------*/ +void Euler2Quat_fx( + const Word32 yaw, /* i : yaw (x) Q22 */ + const Word32 pitch, /* i : pitch (y) Q22 */ + const Word32 roll, /* i : roll (z) Q22 */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +) +{ + Word16 cr = getCosWord16( extract_l( L_shr_r( roll, 10 ) ) ); + Word16 sr = getSinWord16( extract_l( L_shr_r( roll, 10 ) ) ); + Word16 cp = getCosWord16( extract_l( L_shr_r( pitch, 10 ) ) ); + Word16 sp = getSinWord16( extract_l( L_shr_r( pitch, 10 ) ) ); + Word16 cy = getCosWord16( extract_l( L_shr_r( yaw, 10 ) ) ); + Word16 sy = getSinWord16( extract_l( L_shr_r( yaw, 10 ) ) ); + quat->w_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( cr, cp ), cy ), Mpy_32_16_1( L_mult0( sr, sp ), sy ) ), 5 ); + quat->x_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( sr, cp ), cy ), Mpy_32_16_1( L_mult0( cr, sp ), sy ) ), 5 ); + quat->y_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( sr, cp ), sy ), Mpy_32_16_1( L_mult0( cr, sp ), cy ) ), 5 ); + quat->z_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( cr, cp ), sy ), Mpy_32_16_1( L_mult0( sr, sp ), cy ) ), 5 ); + return; +} void Euler2Quat( const float yaw, /* i : yaw (x) */ const float pitch, /* i : pitch (y) */ @@ -77,6 +99,86 @@ void Euler2Quat( * * Quaternion handling: calculate corresponding Euler angles in degrees *------------------------------------------------------------------------*/ +void Quat2EulerDegree_fx( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + Word32 *yaw_fx, /* o : yaw */ + Word32 *pitch_fx, /* o : pitch */ + Word32 *roll_fx /* o : roll */ +) +{ + IF( NE_32( quat.w_fx, L_negate( 12582912 ) /*3.0f in Q22*/ ) ) + { + Word32 tmp1 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.x_fx ), Q22 ) ); // Q22 + Word32 tmp2 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.z_fx ), Q22 ) ); // Q22 + Word32 tmp3 = L_shl( L_add( tmp1, tmp2 ), 1 ); // Q22 + + Word32 tmp4 = W_extract_l( W_shr( W_mult0_32_32( quat.x_fx, quat.x_fx ), Q22 ) ); // Q22 + Word32 tmp5 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.y_fx ), Q22 ) ); // Q22 + Word32 tmp6 = L_shl( L_add( tmp4, tmp5 ), 1 ); + Word32 tmp7 = L_sub( ONE_IN_Q22, tmp6 ); + + IF( tmp3 >= -2 && tmp3 <= 2 ) + { + tmp3 = 0; + } + IF( tmp7 >= -2 && tmp7 <= 2 ) + { + tmp7 = 0; + } + + Word16 yaw_fx_16 = BASOP_util_atan2( tmp3, tmp7, 0 ); // Q13 + *yaw_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, yaw_fx_16 ); + + Word32 p_fx; + Word32 tmp8 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.y_fx ), Q22 ) ); // Q22 + Word32 tmp9 = W_extract_l( W_shr( W_mult0_32_32( quat.z_fx, quat.x_fx ), Q22 ) ); // Q22 + p_fx = L_shl( L_sub( tmp8, tmp9 ), 1 ); + p_fx = max( L_negate( ONE_IN_Q22 ), min( ONE_IN_Q22, p_fx ) ); // Q22 + + Word32 p_fx_sq = W_extract_l( W_shr( W_mult0_32_32( p_fx, p_fx ), Q22 ) ); + Word16 res_exp = 0; + Word32 one_minus_p_fx_sq = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, L_negate( p_fx_sq ), 31 - Q22, &res_exp ); + Word32 sqrt_one_minus_p_fx_sq = Sqrt32( one_minus_p_fx_sq, &res_exp ); + + Word16 pitch_fx_16 = BASOP_util_atan2( p_fx, sqrt_one_minus_p_fx_sq, ( 31 - Q22 ) - res_exp ); + + *pitch_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, pitch_fx_16 ); + + Word32 tmp10 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.z_fx ), Q22 ) ); // Q22 + Word32 tmp11 = W_extract_l( W_shr( W_mult0_32_32( quat.x_fx, quat.y_fx ), Q22 ) ); // Q22 + Word32 tmp12 = L_shl( L_add( tmp10, tmp11 ), 1 ); // Q22 + + Word32 tmp13 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.y_fx ), Q22 ) ); // Q22 + Word32 tmp14 = W_extract_l( W_shr( W_mult0_32_32( quat.z_fx, quat.z_fx ), Q22 ) ); // Q22 + Word32 tmp15 = L_shl( L_add( tmp13, tmp14 ), 1 ); // Q22 + Word32 tmp16 = L_sub( ONE_IN_Q22, tmp15 ); // Q22 + + IF( tmp12 >= -2 && tmp12 <= 2 ) + { + tmp12 = 0; + } + IF( tmp16 >= -2 && tmp16 <= 2 ) + { + tmp16 = 0; + } + Word16 roll_fx_16 = BASOP_util_atan2( tmp12, tmp16, 0 ); // Q13 + *roll_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, roll_fx_16 ); + } + ELSE + { + /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention + * + * yaw: rotate scene counter-clockwise in the horizontal plane + * pitch: rotate scene in the median plane, increase elevation with positive values + * roll: rotate scene from the right ear to the top + */ + *yaw_fx = quat.z_fx; + *pitch_fx = quat.y_fx; + *roll_fx = quat.x_fx; + } + + return; +} void Quat2EulerDegree( const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ @@ -88,11 +190,15 @@ void Quat2EulerDegree( if ( quat.w != -3.0 ) { float p; + *yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) ); + p = 2 * ( quat.w * quat.y - quat.z * quat.x ); p = max( -1.0f, min( 1.0f, p ) ); *pitch = asinf( p ); + *roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) ); + *yaw *= _180_OVER_PI; *pitch *= _180_OVER_PI; *roll *= _180_OVER_PI; @@ -114,13 +220,28 @@ void Quat2EulerDegree( } #endif - /*------------------------------------------------------------------------- * deg2rad() * * Converts degrees to normalized radians *------------------------------------------------------------------------*/ +#define DEGREE_180 ( Word32 )( 180.0 * ONE_IN_Q22 ) +#define DEGREE_360 ( Word32 )( 360.0 * ONE_IN_Q22 ) +#define PI_OVER_180_FX ( Word32 )( ( EVS_PI / 180.0f ) * ONE_IN_Q31 ) +Word32 deg2rad_fx( + Word32 degrees ) +{ + WHILE( degrees >= DEGREE_180 ) + { + degrees = degrees - DEGREE_360; + } + WHILE( degrees <= -DEGREE_180 ) + { + degrees = degrees + DEGREE_360; + } + return Mpy_32_32( PI_OVER_180_FX, degrees ); +} float deg2rad( float degrees ) { diff --git a/lib_com/log2.c b/lib_com/log2.c new file mode 100644 index 000000000..739dd8e5e --- /dev/null +++ b/lib_com/log2.c @@ -0,0 +1,222 @@ +/******************************************************************************** + * + * File : log2.c + * Purpose : Computes log2(L_x) + * + ******************************************************************************** + */ + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "stl.h" +#include "math_op.h" +#include +#include "rom_basic_math.h" +#include "options.h" + +#define LW_SIGN (Word32) 0x80000000 /* sign bit */ +#define LW_MIN (Word32) 0x80000000 +#define LW_MAX (Word32) 0x7fffffff + +#define SW_SIGN (Word16) 0x8000 /* sign bit for Word16 type */ +#define SW_MIN (Word16) 0x8000 /* smallest Ram */ +#define SW_MAX (Word16) 0x7fff /* largest Ram */ + + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ + +/************************************************************************* + * + * FUNCTION: Log2_norm_lc() + * + * PURPOSE: Computes log2(L_x, exp), where L_x is positive and + * normalized, and exp is the normalisation exponent + * If L_x is negative or zero, the result is 0. + * + * DESCRIPTION: + * The function Log2(L_x) is approximated by a table and linear + * interpolation. The following steps are used to compute Log2(L_x) + * + * 1- exponent = 30-norm_exponent + * 2- i = bit25-b31 of L_x; 32<=i<=63 (because of normalization). + * 3- a = bit10-b24 + * 4- i -=32 + * 5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 + * + *************************************************************************/ +Word16 Log2_norm_lc( /* (o) : Fractional part of Log2. (range: 0<=val<1) */ + Word32 L_x /* (i) : input value (normalized) */ +) +{ + Word16 i, a; + Word16 y; + + if ( L_x <= 0 ) + L_x = L_deposit_h( 0x4000 ); + + L_x = L_shr( L_x, 9 ); + a = extract_l( L_x ); /* Extract b10-b24 of fraction */ + a = lshr( a, 1 ); + + i = mac_r( L_x, -32 * 2 - 1, 16384 ); /* Extract b25-b31 minus 32 */ + + y = mac_r( L_table_Log2_norm_lc[i], table_diff_Log2_norm_lc[i], a ); /* table[i] << 16 - diff*a*2 */ + + return y; +} + +Word32 log10_fx( Word32 Linput ) +{ + Word16 n1, frac, p1, p2, q1; + Word32 Ltemp1, Ltemp2; + Word32 L_tmp; + + if ( Linput <= 0 ) + return ( LW_MIN ); + n1 = norm_l( Linput ); + Ltemp1 = (Word32) L_shl( Linput, n1 ); + + Ltemp2 = L_mult( extract_h( Ltemp1 ), 0x40 ); + frac = extract_l( Ltemp2 ); + + p1 = log2_tab[sub( extract_h( Ltemp2 ), 0x20 )]; + p2 = log2_tab[sub( extract_h( Ltemp2 ), 0x1F )]; + Ltemp2 = L_mult( n1, 0x200 ); + n1 = extract_l( Ltemp2 ); + + Ltemp1 = L_add( L_deposit_h( p1 ), 0x8000 ); /* Add rounding bit */ + + IF( frac >= 0 ) + { + Ltemp1 = L_sub( Ltemp1, (Word32) L_mult0( p1, frac ) ); + Ltemp1 = L_add( Ltemp1, (Word32) L_mult0( p2, frac ) ); + } + ELSE + { + L_tmp = L_add( 65536, frac ); + L_tmp = L_tmp * p1; + Ltemp1 = L_sub( Ltemp1, L_tmp ); + + L_tmp = L_add( 65536, frac ); + L_tmp = L_tmp * p2; + Ltemp1 = L_add( Ltemp1, L_tmp ); + } + q1 = extract_h( Ltemp1 ); + Ltemp1 = L_mult( q1, 0x6054 ); + Ltemp1 = L_msu( Ltemp1, 0x6054, n1 ); + return ( L_shr( Ltemp1, 1 ) ); +} + +Word32 pow_10( Word32 x, Word16 *Q ) +{ + Word16 xl, xh, t1, t2, n; + Word32 Ltemp1; + Word32 Lacc; + Word32 L_tmp; + Word16 n1, i; + Word16 count = 0; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + move16(); + ; + + xl = extract_l( x ); + xh = extract_h( x ); + + IF( xl < 0 ) + { + L_tmp = L_add( 65536, xl ); + Ltemp1 = (Word32) ( 0x6a4d * L_tmp ); + } + ELSE + { + Ltemp1 = L_mult0( 0x6a4d, xl ); + } + Ltemp1 = L_add( L_shr( Ltemp1, 16 ), L_shr( L_mult( xh, 0x6a4d ), 1 ) ); + + + Lacc = L_sub( -1L, Ltemp1 ); /* Lacc=~Lacc, 1's complement */ + t1 = extract_l( L_shr( Lacc, 7 ) ); + + Ltemp1 = L_shr( Ltemp1, 7 ); + n1 = extract_h( Ltemp1 ); + n = sub( n1, 14 ); + *Q = 14; + move16(); + IF( t1 < 0 ) + { + L_tmp = L_add( 65536, t1 ); + t2 = extract_h( L_tmp * L_tmp ); + } + ELSE + { + t2 = extract_h( L_mult0( t1, t1 ) ); + } + + Lacc = L_deposit_h( 0x1FEF ); + IF( t2 < 0 ) + { + L_tmp = L_add( 65536, t2 ); + Lacc = L_add( Lacc, (Word32) ( L_tmp * 0x057C ) ); + } + ELSE + { + Lacc = L_add( Lacc, (Word32) L_mult0( t2, 0x057C ) ); + } + + IF( t1 < 0 ) + { + L_tmp = L_add( 65536, t1 ); + Lacc = L_sub( Lacc, (Word32) ( L_tmp * 0x155C ) ); + } + ELSE + { + Lacc = L_sub( Lacc, (Word32) L_mult0( t1, 0x155C ) ); + } + + L_tmp = Lacc; + FOR( i = 1; i <= n; i++ ) + { + Overflow = 0; + move16(); +#ifdef BASOP_NOGLOB /* Critical Overflow */ + L_tmp = L_shl_o( L_tmp, i, &Overflow ); +#else + L_tmp = L_shl( L_tmp, i ); +#endif + IF( Overflow ) + { + count = add( count, 1 ); + } + } + *Q = sub( *Q, count ); + move16(); + + return ( L_shl( Lacc, sub( n, count ) ) ); +} + +Word16 Log2_lc( /* (o) : Fractional part of Log2. (range: 0<=val<1) */ + Word32 L_x, /* (i) : input value */ + Word16 *exponent /* (o) : Integer part of Log2. (range: 0<=val<=30) */ +) +{ + Word16 exp; + + if ( L_x <= 0 ) + L_x = L_deposit_l( 0x1 ); + + exp = norm_l( L_x ); + *exponent = sub( 30, exp ); + move16(); + + return Log2_norm_lc( L_shl( L_x, exp ) ); +} diff --git a/lib_com/log2.h b/lib_com/log2.h new file mode 100644 index 000000000..ade28f994 --- /dev/null +++ b/lib_com/log2.h @@ -0,0 +1,40 @@ +/******************************************************************************** + * + * File : log2.h + * Purpose : Computes log2(L_x) + * + ******************************************************************************** + */ +#ifndef log2_h +#define log2_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "log2.h" + +/* +******************************************************************************** +* DEFINITION OF DATA TYPES +******************************************************************************** +*/ + +/* +******************************************************************************** +* DECLARATION OF PROTOTYPES +******************************************************************************** +*/ +Word16 Log2_norm_lc( /* (o) : Fractional part of Log2. (range: 0<=val<1) */ + Word32 L_x /* (i) : input value (normalized) */ +); + +Word32 log10_fx( Word32 Linput ); +Word32 pow_10( Word32 x, Word16 *Q ); +Word16 Log2_lc( /* (o) : Fractional part of Log2. (range: 0<=val<1) */ + Word32 L_x, /* (i) : input value */ + Word16 *exponent /* (o) : Integer part of Log2. (range: 0<=val<=30) */ +); +#endif diff --git a/lib_com/math_op.c b/lib_com/math_op.c new file mode 100644 index 000000000..e95f8503c --- /dev/null +++ b/lib_com/math_op.c @@ -0,0 +1,24 @@ +/*___________________________________________________________________________ + | | + | This file contains mathematic operations in fixed point. | + | | + | Isqrt() : inverse square root (16 bits precision). | + | Pow2() : 2^x (16 bits precision). | + | Log2() : log2 (16 bits precision). | + | Dot_product() : scalar product of | + | | + | In this file, the values use theses representations: | + | | + | Word32 L_32 : standard signed 32 bits format | + | Word16 hi, lo : L_32 = hi<<16 + lo<<1 (DPF - Double Precision Format) | + | Word32 frac, Word16 exp : L_32 = frac << exp-31 (normalised format) | + | Word16 int, frac : L_32 = int.frac (fractional format) | + |___________________________________________________________________________| +*/ + +#include "stl.h" +#include "math_op.h" +#include "rom_basic_math.h" + +#include +#include diff --git a/lib_com/math_op.h b/lib_com/math_op.h new file mode 100644 index 000000000..48c171baf --- /dev/null +++ b/lib_com/math_op.h @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------* + * MATH_OP.H * + *--------------------------------------------------------------------------* + * Mathematical operations * + *--------------------------------------------------------------------------*/ +#include "oper_32b.h" +#include "log2.h" +#include "options.h" diff --git a/lib_com/move.h b/lib_com/move.h index becc9314d..39878c843 100644 --- a/lib_com/move.h +++ b/lib_com/move.h @@ -36,9 +36,14 @@ #ifndef _MOVE_H #define _MOVE_H - +#include "stl.h" /* BASOP -> FLC brigde: data move counting */ +#if ( WMOPS ) +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif /* ifdef WMOPS */ + static __inline void move16( void ) { #ifdef WMOPS diff --git a/lib_com/oper_32b.c b/lib_com/oper_32b.c new file mode 100644 index 000000000..06a202e65 --- /dev/null +++ b/lib_com/oper_32b.c @@ -0,0 +1,26 @@ +/***************************************************************************** + * $Id: oper_32b.c 1094 2014-02-10 17:12:11Z jdr $ + * + * This file contains operations in double precision. * + * These operations are not standard double precision operations. * + * They are used where single precision is not enough but the full 32 bits * + * precision is not necessary. For example, the function Div_32() has a * + * 24 bits precision which is enough for our purposes. * + * * + * The double precision numbers use a special representation: * + * * + * L_32 = hi<<16 + lo<<1 * + * * + * L_32 is a 32 bit integer. * + * hi and lo are 16 bit signed integers. * + * As the low part also contains the sign, this allows fast multiplication. * + * * + * 0x8000 0000 <= L_32 <= 0x7fff fffe. * + * * + * We will use DPF (Double Precision Format) in this file to specify * + * this special format. * + ***************************************************************************** + */ + +#include "stl.h" +#include "basop32.h" diff --git a/lib_com/oper_32b.h b/lib_com/oper_32b.h new file mode 100644 index 000000000..6a3677595 --- /dev/null +++ b/lib_com/oper_32b.h @@ -0,0 +1,6 @@ +/* Double precision operations */ +/* $Id: oper_32b.h 1094 2014-02-10 17:12:11Z jdr $ */ +#ifndef _OPER_32b_H +#define _OPER_32b_H +#include "options.h" +#endif diff --git a/lib_com/options.h b/lib_com/options.h index 7ca7f7027..e13ea6425 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -50,7 +50,7 @@ #ifndef RELEASE /*#define DEBUGGING*/ /* Activate debugging part of the code */ #endif -/*#define WMOPS*/ /* Activate complexity and memory counters */ +/*#define WMOPS 1 */ /* Activate complexity and memory counters */ /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ /*#define WMOPS_WC_FRAME_ANALYSIS*/ /* Output detailed complexity analysis for the worst-case frame */ @@ -178,10 +178,12 @@ #define BASOP_NOGLOB /* Disable global symbols in BASOPs, Overflow/Carry in BASOPs disabled, additional BASOPs in case of Overflow */ -#define SPLIT_REND_WITH_HEAD_ROT /* Dlb,FhG: Split Rendering contributions 21 and 35 */ -#define ISAR_BITSTREAM_UPDATE_LC3PLUS /* FhG: Multiple improvements to the ISAR bitstream when LC3plus is used. See MR 1456 for details. */ +#define SPLIT_REND_WITH_HEAD_ROT /* Dlb,FhG: Split Rendering contributions 21 and 35 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT #define SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - +#define ISAR_BITSTREAM_UPDATE_LC3PLUS /* FhG: Multiple improvements to the ISAR bitstream when LC3plus is used. See MR 1456 for details. */ +#endif +#define FIX_NORM_UL_LOC /* FhG: move norm_ul() from lib_com/tools.c to lib_com/enhUL32.c */ /* clang-format on */ diff --git a/lib_com/prot.h b/lib_com/prot.h index dec16b630..170b4dd4b 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -147,9 +147,10 @@ float log2_f( const float x /* i : input value of x */ ); +#ifndef FIX_NORM_UL_LOC int16_t norm_ul( uint32_t UL_var1 ); - +#endif /*! r: sum of all vector elements */ int16_t sum_s( const int16_t *vec, /* i : input vector */ @@ -339,6 +340,13 @@ void v_multc( const int16_t N /* i : Vector length */ ); +void v_multc_fixed( + const Word32 x[], /* i : Input vector */ + const Word32 c, /* i : Constant */ + Word32 y[], /* o : Output vector that contains c*x */ + const Word16 N /* i : Vector length */ +); + void v_sub_s( const int16_t x1[], /* i : Input vector 1 */ const int16_t x2[], /* i : Input vector 2 */ @@ -9025,6 +9033,48 @@ void cldfbSynthesis( HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ); +// Word16 find_guarded_bits_fx(Word32 n); + +void fft_cldfb_fx( + Word32 *data, /* i/o: input/output vector */ + const Word16 size /* size of fft operation */ +); + +void cldfbAnalysis_ts_fx( + const Word32 *timeIn_fx, + /* i : time buffer */ // q + Word32 realBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : real value buffer */ // q - 5 + Word32 imagBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : imag value buffer */ // q - 5 + const Word16 samplesToProcess, /* i : samples to process */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word16 *q_cldfb ); + +void cldfbAnalysis_ts_fx_fixed_q( + const Word32 *timeIn_fx, + /* i : time buffer */ // q + Word32 realBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : real value buffer */ // q - 5 + Word32 imagBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : imag value buffer */ // q - 5 + const Word16 samplesToProcess, /* i : samples to process */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word16 *q_cldfb ); + +void cldfbSynthesis_ivas_fx( + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ + HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ +); + +void configureCldfb_splitRenderer( + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ + const Word32 sampling_rate /* i : sampling rate */ +); + void configureCldfb( HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ const int32_t sampling_rate /* i : sampling rate */ @@ -9045,6 +9095,13 @@ ivas_error openCldfb( CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ ); +ivas_error openCldfb_splitRend( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ + CLDFB_TYPE type, /* i : analysis or synthesis */ + const Word32 sampling_rate, /* i : sampling rate */ + CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +); + void resampleCldfb( HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ const int32_t newSamplerate /* i : new samplerate to operate */ @@ -9066,6 +9123,10 @@ void deleteCldfb( HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ ); +void deleteCldfb_splitRend( + HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ +); + void fft_cldfb( float *data, /* i/o: input/output vector */ const int16_t size /* i : size of fft operation */ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h new file mode 100644 index 000000000..2afb24baf --- /dev/null +++ b/lib_com/prot_fx2.h @@ -0,0 +1,125 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef PROT_FX2_H +#define PROT_FX2_H +/*----------------------------------------------------------------------------------* + * Prototypes of RAM counting tool macros + *----------------------------------------------------------------------------------*/ + +#ifdef RAM_COUNTING_TOOL +#define count_malloc( n1 ) MALLOC_FCT_CALL( n1 ) +#define count_calloc( n1, n2 ) CALLOC_FCT_CALL( n1, n2 ) +#define count_free( ptr ) FREE_FCT_CALL( ptr ) +#else +#define count_malloc( n1 ) malloc( n1 ) +#define count_calloc( n1, n2 ) calloc( n1, n2 ) +#define count_free( ptr ) free( ptr ) +#endif + +#define dynamic_malloc( n1 ) malloc( n1 ) +#define dynamic_calloc( n1, n2 ) calloc( n1, n2 ) +#define dynamic_free( n1 ) free( n1 ) + +#include "ivas_cnst.h" +#include "stat_enc.h" +#include "stat_dec.h" +#include "ivas_stat_dec.h" +#include "ivas_error.h" +#include "ivas_error_utils.h" +#define TCX_IMDCT_SCALE 15 +#define TCX_IMDCT_HEADROOM 1 + +/* conversion functions: */ + +// Float to Word32 +Word32 float_to_fix( float number, Word32 Q ); +// Word32 to Float +float fix_to_float( Word32 number, Word32 Q ); +// Float to Word16 +Word16 float_to_fix16( float number, Word16 Q ); +// Word16 to Float +float fix16_to_float( Word16 number, Word16 Q ); + +void floatToFixed_arrL( float *f, Word32 *i, Word16 Q, Word16 l ); +void floatToFixed_arr( float *f, Word16 *i, Word16 Q, Word16 l ); +void fixedToFloat_arrL( Word32 *i, float *f, Word16 Q, Word16 l ); +void fixedToFloat_arr( Word16 *i, float *f, Word16 Q, Word16 l ); +Word16 Q_factor( float x ); +Word16 Q_factor_L( float x ); +Word16 Q_factor_arr( float *x, Word16 l ); +Word16 Q_factor_arrL( float *x, Word16 l ); +// Handles the cases where Q is negative +Word32 floatToFixed( float f, Word16 Q ); +float fixedToFloat( Word32 i, Word16 Q ); + +// Float to 32-bit Mantissa and Exponent using frexp +void f2me( float n, Word32 *mantissa, Word16 *expo ); +// 32-bit Mantissa and Exponent to Float using ldexp +float me2f( Word32 m, Word16 expo ); +// Float to 32-bit Mantissa Array and Exponent +void f2me_buf( const float *x, Word32 *m, Word16 *e, const Word32 n ); +// 32-bit Mantissa Array and Exponent to Float +void me2f_buf( const Word32 *m, const Word16 e, float *out, const Word32 n ); +// Float to 16-bit Mantissa and Exponent using frexp +void f2me_16( float n, Word16 *mantissa, Word16 *expo ); +// 16-bit Mantissa and Exponent to Float using ldexp +float me2f_16( Word16 m, Word16 expo ); +// Float to 16-bit Mantissa Array and Exponent +void f2me_buf_16( const float *x, Word16 *m, Word16 *e, const Word32 n ); +// 16-bit Mantissa Array and Exponent to Float +void me2f_buf_16( const Word16 *m, const Word16 e, float *out, const Word32 n ); + +void Copy32( + const Word32 x[], /* i : input vector */ + Word32 y[], /* o : output vector */ + const Word16 L /* i : vector length */ +); + +void Scale_sig32( + Word32 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); + +void ivas_cmult_fix( Word32 in1_re_fx, Word16 exp_re1, Word32 in1_im_fx, Word16 exp_im1, Word32 in2_re_fx, Word16 exp_re2, Word32 in2_im_fx, Word16 exp_im2, Word32 *out1_re_fx, Word32 *out1_im_fx, Word16 *exp_out1_re, Word16 *exp_out1_im ); + +void ivas_calculate_abs_fx( Word32 re_fx, Word16 exp_re, Word32 im_fx, Word16 exp_im, Word32 *out_fx, Word16 *exp_out ); + +void ivas_calculate_rabs_fx( Word32 re_fx, Word16 exp_re, Word32 *out_fx, Word16 *exp_out ); + +void Copy32( + const Word32 x[], /* i : i vector */ + Word32 y[], /* o : output vector */ + const Word16 L /* i : vector length */ +); +#endif diff --git a/lib_com/rom_basic_math.c b/lib_com/rom_basic_math.c new file mode 100644 index 000000000..ceb89163f --- /dev/null +++ b/lib_com/rom_basic_math.c @@ -0,0 +1,83 @@ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Decoder static structure */ +#include "stl.h" + +/* math_op.c */ +const Word32 L_table_isqrt[48] = { + 2147418112L, 2083389440L, 2024669184L, 1970667520L, + 1920794624L, 1874460672L, 1831403520L, 1791098880L, + 1753415680L, 1717960704L, 1684602880L, 1653145600L, + 1623326720L, 1595080704L, 1568276480L, 1542782976L, + 1518469120L, 1495334912L, 1473183744L, 1451950080L, + 1431633920L, 1412169728L, 1393491968L, 1375469568L, + 1358168064L, 1341521920L, 1325465600L, 1309933568L, + 1294991360L, 1280507904L, 1266548736L, 1252982784L, + 1239875584L, 1227161600L, 1214775296L, 1202847744L, + 1191182336L, 1179910144L, 1168965632L, 1158283264L, + 1147863040L, 1137770496L, 1127940096L, 1118306304L, + 1108934656L, 1099825152L, 1090912256L, 1082261504L +}; + +/* table of table_isqrt[i] - table_isqrt[i+1] */ +const Word16 table_isqrt_diff[48] = { + 977, 896, 824, 761, 707, 657, 615, 575, + 541, 509, 480, 455, 431, 409, 389, 371, + 353, 338, 324, 310, 297, 285, 275, 264, + 254, 245, 237, 228, 221, 213, 207, 200, + 194, 189, 182, 178, 172, 167, 163, 159, + 154, 150, 147, 143, 139, 136, 132, 130 +}; + +const Word16 shift_Isqrt_lc[] = { 9, 10 }; + +const Word16 table_pow2[32] = { + 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911, + 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726, + 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706, + 31379, 32066 +}; + +/* table of table_pow2[i+1] - table_pow2[i] */ +const Word16 table_pow2_diff_x32[32] = { + 11488, 11712, 12000, 12256, 12512, 12800, 13056, 13376, 13664, 13952, + 14240, 14560, 14912, 15200, 15552, 15872, 16256, 16576, 16960, 17344, + 17696, 18080, 18496, 18880, 19328, 19712, 20192, 20576, 21056, 21536, + 21984, 22432 +}; + +const Word16 sqrt_table[49] = { + 16384, 16888, 17378, 17854, 18318, 18770, 19212, + 19644, 20066, 20480, 20886, 21283, 21674, 22058, + 22435, 22806, 23170, 23530, 23884, 24232, 24576, + 24915, 25249, 25580, 25905, 26227, 26545, 26859, + 27170, 27477, 27780, 28081, 28378, 28672, 28963, + 29251, 29537, 29819, 30099, 30377, 30652, 30924, + 31194, 31462, 31727, 31991, 32252, 32511, 32767 +}; + +/* log2.c */ +const Word32 L_table_Log2_norm_lc[32] = { + -32768L, 95322112L, 187793408L, 277577728L, + 364871680L, 449740800L, 532381696L, 612859904L, + 691306496L, 767787008L, 842432512L, 915308544L, + 986546176L, 1056210944L, 1124302848L, 1190887424L, + 1256095744L, 1319993344L, 1382580224L, 1443921920L, + 1504083968L, 1563131904L, 1621000192L, 1677885440L, + 1733722112L, 1788510208L, 1842380800L, 1895399424L, + 1947435008L, 1998618624L, 2049015808L, 2098626560L +}; + +const Word16 table_diff_Log2_norm_lc[32] = { + 1455, 1411, 1370, 1332, 1295, 1261, 1228, 1197, + 1167, 1139, 1112, 1087, 1063, 1039, 1016, 995, + 975, 955, 936, 918, 901, 883, 868, 852, + 836, 822, 809, 794, 781, 769, 757, 744 +}; + +const Word16 log2_tab[33] = { + 0x7800, 0x782D, 0x785A, 0x7884, 0x78AE, 0x78D6, 0x78FE, 0x7924, + 0x794A, 0x796E, 0x7992, 0x79B4, 0x79D6, 0x79F8, 0x7A18, 0x7A38, + 0x7A57, 0x7A75, 0x7A93, 0x7AB1, 0x7ACD, 0x7AE9, 0x7B05, 0x7B20, + 0x7B3B, 0x7B55, 0x7B6F, 0x7B88, 0x7BA1, 0x7BB9, 0x7BD1, 0x7BE9, + 0x7C00 +}; diff --git a/lib_com/rom_basic_math.h b/lib_com/rom_basic_math.h new file mode 100644 index 000000000..0cf6d6dd3 --- /dev/null +++ b/lib_com/rom_basic_math.h @@ -0,0 +1,26 @@ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Decoder static structure */ +#include "stl.h" + + +/* math_op.c */ +extern const Word32 L_table_isqrt[48]; + +/* table of table_isqrt[i] - table_isqrt[i+1] */ +extern const Word16 table_isqrt_diff[48]; + +extern const Word16 shift_Isqrt_lc[]; + +extern const Word16 table_pow2[32]; + +/* table of table_pow2[i+1] - table_pow2[i] */ +extern const Word16 table_pow2_diff_x32[32]; + +extern const Word16 sqrt_table[49]; + +/* log2.c */ +extern const Word32 L_table_Log2_norm_lc[32]; + +extern const Word16 table_diff_Log2_norm_lc[32]; + +extern const Word16 log2_tab[33]; diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index f08f41a1d..4619634f8 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -5474,35 +5474,73 @@ const float rot_vec_syn_re_L10[5] = 0.1117172025f,0.1048929802f,0.0878011021f,0.0621146404f,0.0303479649f, }; +// Q31 +const Word32 rot_vec_syn_re_L10_fx[5] = +{ + 239910864 ,225255952 ,188551424 ,133390176 ,65171760 , +}; + const float rot_vec_syn_im_L10[5] = { -0.0043893808f,-0.0386970634f,-0.0692168078f,-0.0929611287f,-0.1076057667f, }; +/*Q31*/ +const Word32 rot_vec_syn_im_L10_fx[5] = +{ + -9426123 ,-83101312 ,-148641968 ,-199632496 ,-231081632 , +}; + const float rot_vec_syn_re_L16[8] = { 0.1117697258f,0.1090868144f,0.1022117580f,0.0914087610f,0.0770929766f,0.0598145523f, 0.0402374883f,0.0191141202f, }; +/*Q31*/ +const Word32 rot_vec_syn_re_L16_fx[8] = +{ + 240023664 ,234262144 ,219498080 ,196298816 ,165555904 ,128450776 ,86409352 ,41047260 , +}; + const float rot_vec_syn_im_L16[8] = { -0.0027437928f,-0.0244962633f,-0.0453073563f,-0.0643773129f,-0.0809732855f,-0.0944575001f, -0.1043117660f,-0.1101573893f, }; +/*Q31*/ +const Word32 rot_vec_syn_im_L16_fx[8] = +{ + -5892250 ,-52605324 ,-97296808 ,-138249232 ,-173888800 ,-202845936 ,-224007808 ,-236561200 , +}; + + const float rot_vec_syn_re_L20[10] = { 0.1117818477f,0.1100622363f,0.1056325273f,0.0986017949f,0.0891431591f,0.0774895228f, 0.0639278374f,0.0487920364f,0.0324548136f,0.0153184455f, }; +/*Q31*/ +const Word32 rot_vec_syn_re_L20_fx[10] = +{ + 240049696 ,236356848 ,226844128 ,211745744 ,191433472 ,166407488 ,137283984 ,104780104 ,69696184 ,32896112 , +}; + const float rot_vec_syn_im_L20[10] = { -0.0021951135f,-0.0196546216f,-0.0366301676f,-0.0527037574f,-0.0674796057f,-0.0805938822f, -0.0917236698f,-0.1005949163f,-0.1069891821f,-0.1107490191f, }; +/*Q31*/ +const Word32 rot_vec_syn_im_L20_fx[10] = +{ + -4713971 ,-42207980 ,-78662688 ,-113180456 ,-144911344 ,-173074048 ,-196975088 ,-216025936 ,-229757520 ,-237831712 , +}; + + const float rot_vec_syn_re_L30[15] = { 0.1117938204f,0.1110284288f,0.1090465865f,0.1058700070f,0.1015334935f,0.0960845578f, @@ -5510,6 +5548,14 @@ const float rot_vec_syn_re_L30[15] = 0.0331543560f,0.0218117611f,0.0102301920f, }; +/*Q31*/ +const Word32 rot_vec_syn_re_L30_fx[15] = +{ + 240075408 ,238431728 ,234175760 ,227354112 ,218041520 ,206340016 ,192377808 ,176307872 , + 158306272 ,138570240 ,117315992 ,94776408 ,71198440 ,46840400 ,21969170 , +}; + + const float rot_vec_syn_im_L30[15] = { -0.0014634613f,-0.0131410805f,-0.0246747234f,-0.0359380248f,-0.0468075816f,-0.0571643048f, @@ -5517,6 +5563,14 @@ const float rot_vec_syn_im_L30[15] = -0.1067744758f,-0.1096551279f,-0.1113343755f, }; +/*Q31*/ +const Word32 rot_vec_syn_im_L30_fx[15] = +{ + -3142759 ,-28220256 ,-52988564 ,-77176320 ,-100518520 ,-122759408 ,-143655328 ,-162977328 , + -180513712 ,-196072352 ,-209482768 ,-220598064 ,-229296448 ,-235482592 ,-239088752 , +}; + + const float rot_vec_syn_re_L32[16] = { 0.1117949803f,0.1111221774f,0.1093792072f,0.1065828555f,0.1027600526f,0.0979476142f, @@ -5524,6 +5578,12 @@ const float rot_vec_syn_re_L32[16] = 0.0415145243f,0.0311394479f,0.0204644816f,0.0095924311f, }; +const Word32 rot_vec_syn_re_L32_fx[16] = +{ + 240077888 ,238633056 ,234890064 ,228884944 ,220675536 ,210340896 ,197980576 ,183713584 , + 167677328 ,150026240 ,130930336 ,110573488 ,89151760 ,66871456 ,43947140 ,20599588 , +}; + const float rot_vec_syn_im_L32[16] = { -0.0013719997f,-0.0123232174f,-0.0231557558f,-0.0337652916f,-0.0440496492f,-0.0539097846f, @@ -5531,6 +5591,13 @@ const float rot_vec_syn_im_L32[16] = -0.1038101357f,-0.1073793965f,-0.1099145349f,-0.1113911364f, }; +/*Q31*/ +const Word32 rot_vec_syn_im_L32_fx[16] = +{ + -2946347 ,-26463908 ,-49726608 ,-72510408 ,-94595904 ,-115770384 ,-135829936 ,-154581360 , + -171844080 ,-187451856 ,-201254368 ,-213118704 ,-222930576 ,-230595504 ,-236039664 ,-239210640 , +}; + const float rot_vec_syn_re_L40[20] = { 0.1117980110f,0.1113672575f,0.1102498879f,0.1084527911f,0.1059870468f,0.1028678571f, @@ -5539,6 +5606,13 @@ const float rot_vec_syn_re_L40[20] = 0.0164049658f,0.0076773447f, }; +const Word32 rot_vec_syn_re_L40_fx[20] = +{ + 240084400 ,239159360 ,236759824 ,232900592 ,227605456 ,220907040 ,212846672 ,203474016 , + 192846896 ,181030800 ,168098592 ,154130000 ,139211136 ,123434000 ,106895848 ,89698648 , + 71948424 ,53754620 ,35229396 ,16486972 , +}; + const float rot_vec_syn_im_L40[20] = { -0.0010976097f,-0.0098657969f,-0.0185731583f,-0.0271660100f,-0.0355913742f,-0.0437973057f, @@ -5547,6 +5621,14 @@ const float rot_vec_syn_im_L40[20] = -0.1105932959f,-0.1115394925f, }; +/*Q31*/ +const Word32 rot_vec_syn_im_L40_fx[20] = +{ + -2357099 ,-21186638 ,-39885552 ,-58338564 ,-76431896 ,-94054000 ,-111096224 ,-127453512 , + -143025008 ,-157714704 ,-171432032 ,-184092416 ,-195617824 ,-205937184 ,-214986864 ,-222711088 , + -229062224 ,-234001104 ,-237497296 ,-239529232 , +}; + const float rot_vec_syn_re_L60[30] = { 0.1118010042f,0.1116094882f,0.1111120583f,0.1103100780f,0.1092057454f,0.1078020875f, @@ -5556,6 +5638,15 @@ const float rot_vec_syn_re_L60[30] = 0.0338524782f,0.0282294165f,0.0225289799f,0.0167667930f,0.0109586494f,0.0051204690f, }; +/*Q31*/ +const Word32 rot_vec_syn_re_L60_fx[30] = +{ + 240090832 ,239679552 ,238611328 ,236889088 ,234517552 ,231503216 ,227854352 ,223580960 ,218694736 , + 213209088 ,207139056 ,200501264 ,193313904 ,185596688 ,177370784 ,168658704 ,159484336 ,149872832 , + 139850544 ,129444936 ,118684528 ,107598816 ,96218184 ,84573816 ,72697640 ,60622212 ,48380616 , + 36006412 ,23533520 ,10996123 , +}; + const float rot_vec_syn_im_L60[30] = { -0.0007317463f,-0.0065819559f,-0.0124141249f,-0.0182122676f,-0.0239604917f,-0.0296430418f, @@ -5565,6 +5656,16 @@ const float rot_vec_syn_im_L60[30] = -0.1065551956f,-0.1081808673f,-0.1095100227f,-0.1105390187f,-0.1112650350f,-0.1116860815f, }; +/*Q31*/ +const Word32 rot_vec_syn_im_L60_fx[30] = +{ + -1571413 ,-14134643 ,-26659130 ,-39110548 ,-51454764 ,-63657948 ,-75686648 ,-87507896 ,-99089296 , + -110399096 ,-121406296 ,-132080736 ,-142393152 ,-152315264 ,-161819904 ,-170881008 ,-179473744 , + -187574544 ,-195161216 ,-202212960 ,-208710464 ,-214635904 ,-219973040 ,-224707248 ,-228825536 , + -232316640 ,-235170976 ,-237380736 ,-238939840 ,-239844032 , +}; + + const float bpf_weights_16[CLDFB_NO_COL_MAX] = { @@ -5572,6 +5673,335 @@ const float bpf_weights_16[CLDFB_NO_COL_MAX] = 0.000270f, 0.000080f, 0.000030f, 0.000082f, 0.000081f, 0.000052f, 0.000017f, 0.000016f }; + +/* SNR: 109.44, PHASE: 3.500000000000000 */ +const Word16 CLDFB80_10_fx[100] = // q = 15 sf = 17036 qsf = 14 +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7, -2, 0, 0, 0, -1, 0, 0, 0, -8, -31, + -4, 0, 0, -6, 5, 0, 0, -1, 33, -63, -24, 11, 49, 54, 49, 69, 89, 95, 52, -44, -50, 24, 80, 71, 8, + -103, -205, -300, -429, 587, 764, 1010, 1347, 1783, 2309, 2880, 3411, 3810, 4001, 3950, 3582, 2797, + 1568, -98, -2200, -4710, -7582, -10752, -14132, 17583, 20974, 24169, 27024, 29400, 31176, 32302, + 32767, 32696, 32027, 30287, 27571, 24530, 21358, 18039, 14649, 11219, 7832, 4369, 1312 +}; + + +/* SNR: 292.49, PHASE: 2.000000000000000 */ +const Word16 CLDFB80_16_fx[160] = // q = 15 sf = 17051 qsf = 14 +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, + -4, -1, -1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, -2, -13, -38, -16, -5, -3, -1, 0, -1, 1, -7, 1, 0, 1, 1, 1, + 10, 52, -67, -48, -23, -3, 22, 47, 56, 36, 50, 57, 70, 87, 93, 95, 80, 40, -34, -61, -46, 0, 45, 78, + 82, 65, 29, -38, -110, -175, -233, -293, -368, -457, 559, 658, 776, 923, 1104, 1322, 1579, 1873, 2203, + 2556, 2913, 3252, 3551, 3787, 3943, 4005, 3975, 3832, 3542, 3087, 2458, 1656, 683, -459, -1772, -3248, + -4875, -6643, -8536, -10537, -12624, -14766, 16922, 19062, 21161, 23180, 25080, 26833, 28403, 29754, + 30863, 31722, 32320, 32657, 32767, 32685, 32379, 31797, 30709, 29137, 27361, 25471, 23533, 21541, 19486, + 17392, 15275, 13136, 10996, 8882, 6757, 4582, 2509, 876, +}; + +/* SNR: 89.77, PHASE: 1.500000000000000 */ +const Word16 CLDFB80_20_fx[200] = // q = 15 sf = 17050 qsf = 14 +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -9, -6, -1, -2, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, -3, -15, -37, -20, -4, -5, -3, -1, 0, 0, + -4, 8, -15, 4, 0, 1, 1, 1, 2, -4, 10, 57, -62, -58, -27, -19, -1, 19, 39, 52, 57, 24, 52, 53, 60, 75, 87, 92, + 96, 88, 69, 33, -29, -56, -59, -34, 4, 41, 72, 87, 78, 64, 37, -18, -75, -131, -181, -228, -275, -328, -394, + -466, 549, 627, 713, 817, 939, 1085, 1253, 1446, 1664, 1904, 2168, 2449, 2736, 3018, 3284, 3524, 3724, 3876, + 3972, 4006, 3982, 3890, 3707, 3424, 3032, 2528, 1914, 1191, 358, -583, -1633, -2789, -4043, -5392, -6827, -8342, + -9927, -11572, -13263, -14983, 16709, 18424, 20121, 21779, 23377, 24898, 26326, 27645, 28834, 29878, 30765, + 31493, 32056, 32450, 32679, 32767, 32733, 32567, 32235, 31727, 30857, 29634, 28272, 26803, 25281, 23730, 22147, + 20522, 18862, 17182, 15489, 13781, 12065, 10360, 8671, 6973, 5237, 3512, 1961, 735, +}; + + +/* SNR: 89.29, PHASE: 0.833333333333333 */ +const Word16 CLDFB80_30_fx[300] = // q = 15 sf = 17051 qsf = 14 +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, -7, -4, -2, -2, -1, -1, 0, 0, 0, 0, 0, 0, 0, + 0, -1, -1, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, -2, -8, -19, -31, -31, -20, -7, -4, -5, -3, 0, -1, 0, 0, 1, -3, -6, 18, + -23, 5, 3, -3, 0, 1, 2, 0, 1, 2, -1, 0, 11, 33, 61, -57, -63, -54, -33, -24, -16, -4, 11, 23, 36, 49, 54, 56, 54, + 8, 52, 49, 55, 60, 69, 78, 86, 89, 93, 96, 95, 87, 75, 52, 22, -19, -44, -59, -60, -50, -28, -2, 24, 47, 67, 80, + 86, 80, 71, 62, 48, 8, -27, -65, -103, -139, -173, -205, -235, -266, -300, -338, -382, -429, -478, 534, 587, 641, + 698, 763, 836, 917, 1009, 1111, 1223, 1346, 1480, 1626, 1781, 1945, 2122, 2307, 2496, 2688, 2878, 3063, 3241, 3408, + 3560, 3694, 3806, 3896, 3960, 3997, 4003, 3987, 3946, 3866, 3744, 3579, 3366, 3105, 2794, 2434, 2024, 1566, 1060, + 505, -98, -750, -1450, -2198, -2991, -3827, -4706, -5625, -6582, -7575, -8601, -9658, -10742, -11850, -12978, -14119, + -15271, 16422, 17566, 18707, 19838, 20954, 22048, 23114, 24147, 25141, 26094, 26999, 27851, 28644, 29373, 30034, 30626, + 31147, 31596, 31972, 32272, 32496, 32649, 32737, 32767, 32744, 32665, 32521, 32301, 31997, 31636, 31056, 30259, 29415, + 28506, 27545, 26550, 25535, 24507, 23467, 22412, 21338, 20246, 19139, 18023, 16900, 15771, 14635, 13494, 12350, 11209, + 10077, 8952, 7825, 6685, 5527, 4365, 3235, 2198, 1311, 541, +}; + +/* SNR: 85.69, PHASE: 0.750000000000000 */ +const Word16 CLDFB80_32_fx[320] = // q = 15 sf = 17050 qsf = 14 +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, -8, -5, -2, -1, -2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, 0, 1, 0, 0, -1, 0, 0, 0, 0, 1, -1, -3, -9, -20, -31, -32, -20, -10, -2, -5, -4, -2, 0, 0, 0, 0, 0, -3, -5, 18, -24, 4, + 3, -2, 2, 1, 2, 0, 1, 2, 2, -5, 4, 11, 37, 61, -56, -65, -57, -38, -23, -20, -9, 2, 16, 29, 40, 51, 55, 57, 52, 6, 52, 49, 54, + 59, 65, 74, 84, 88, 91, 94, 96, 93, 85, 71, 50, 21, -18, -43, -57, -61, -54, -36, -13, 12, 35, 55, 73, 84, 85, 79, 69, 62, 50, + 11, -21, -56, -93, -127, -159, -190, -219, -248, -278, -310, -348, -389, -433, -480, 532, 582, 632, 685, 744, 810, 883, 965, + 1056, 1156, 1264, 1383, 1511, 1649, 1796, 1951, 2117, 2290, 2467, 2646, 2825, 3000, 3170, 3332, 3482, 3617, 3735, 3834, 3912, + 3968, 4000, 4003, 3988, 3952, 3881, 3775, 3630, 3445, 3217, 2946, 2631, 2273, 1872, 1429, 943, 413, -157, -771, -1428, -2126, + -2864, -3641, -4455, -5305, -6189, -7106, -8052, -9027, -10028, -11053, -12097, -13156, -14228, -15309, 16387, 17461, 18531, + 19594, 20644, 21677, 22687, 23669, 24620, 25536, 26413, 27246, 28032, 28765, 29440, 30056, 30611, 31104, 31534, 31899, 32198, + 32430, 32598, 32706, 32761, 32767, 32727, 32635, 32483, 32262, 31968, 31629, 31085, 30337, 29554, 28712, 27822, 26897, 25951, + 24992, 24023, 23042, 22047, 21034, 20006, 18967, 17919, 16866, 15808, 14744, 13674, 12601, 11530, 10466, 9409, 8355, 7294, 6217, + 5127, 4042, 2998, 2049, 1236, 515, +}; + +/* SNR: 81.55, PHASE: 0.500000000000000 */ +const Word16 CLDFB80_40_fx[400] = // q = 15 sf = 17051 qsf = 14 +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -10, -9, -6, -4, + -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 0, 0, 0, 2, -1, -2, -5, -12, -22, -29, + -37, -24, -18, -9, -2, -6, -4, -3, -2, 0, -1, 0, 0, 0, 1, -2, -6, -2, 20, -24, 0, 5, 2, -2, 2, 0, 2, 2, 0, 1, 2, 2, 2, -6, 3, 11, + 18, 47, 61, -57, -68, -60, -52, -36, -23, -22, -14, -6, 3, 16, 25, 35, 44, 51, 54, 56, 56, 44, 3, 49, 49, 51, 56, 59, 64, 72, 79, + 86, 88, 90, 93, 96, 96, 92, 86, 77, 59, 45, 17, -14, -38, -50, -60, -61, -55, -42, -25, -5, 15, 33, 49, 65, 77, 85, 85, 81, 75, 67, + 62, 54, 22, -4, -31, -60, -90, -117, -144, -169, -193, -216, -239, -262, -287, -313, -344, -377, -411, -447, -485, 527, 569, 606, + 648, 690, 737, 790, 845, 906, 973, 1046, 1125, 1209, 1299, 1395, 1498, 1607, 1722, 1842, 1966, 2099, 2237, 2378, 2520, 2664, 2807, + 2948, 3086, 3219, 3347, 3467, 3578, 3678, 3766, 3843, 3905, 3953, 3987, 4003, 4001, 3989, 3967, 3921, 3853, 3762, 3646, 3505, 3336, + 3140, 2916, 2665, 2385, 2078, 1744, 1382, 993, 577, 133, -337, -835, -1360, -1913, -2490, -3093, -3720, -4372, -5046, -5743, -6460, + -7198, -7956, -8731, -9524, -10332, -11155, -11990, -12836, -13690, -14550, -15416, 16279, 17137, 17995, 18849, 19698, 20538, 21367, + 22183, 22983, 23764, 24524, 25263, 25977, 26665, 27325, 27953, 28548, 29107, 29629, 30112, 30556, 30960, 31324, 31647, 31929, 32168, + 32365, 32519, 32634, 32711, 32755, 32767, 32750, 32702, 32620, 32498, 32333, 32121, 31865, 31595, 31160, 30560, 29950, 29304, 28623, + 27911, 27175, 26424, 25662, 24894, 24118, 23336, 22544, 21743, 20930, 20108, 19278, 18442, 17602, 16759, 15912, 15062, 14208, 13351, + 12493, 11636, 10783, 9936, 9092, 8249, 7400, 6542, 5673, 4799, 3934, 3099, 2320, 1623, 1018, 436, +}; + + +/* SNR: 85.15, PHASE: 0.166666666666667 */ +const Word16 CLDFB80_60_fx[600] = // q = 15 sf = 17051 qsf = 14 +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -11, -9, -9, -6, -6, -4, -3, -1, -1, -1, -2, + -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -2, -3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, -1, + -2, -3, -5, -11, -15, -25, -27, -37, -35, -26, -20, -17, -11, -4, -2, -6, -5, -4, -4, -3, -2, 0, -1, -1, 0, 0, 0, 0, 0, 0, -2, -4, -6, + -3, 8, 18, -21, -15, 2, 6, 4, 2, -2, 0, 2, 0, 1, 2, 2, 1, 0, 0, 1, 2, 2, 2, 1, -4, -4, 5, 10, 10, 23, 42, 57, 61, -58, -62, -67, -60, + -58, -49, -39, -27, -23, -23, -19, -13, -7, -1, 5, 15, 19, 26, 34, 39, 46, 50, 52, 55, 56, 57, 56, 48, 24, 2, 43, 52, 49, 50, 53, 56, + 59, 60, 66, 71, 75, 80, 85, 87, 88, 90, 92, 94, 95, 96, 96, 93, 88, 85, 79, 69, 56, 47, 33, 12, -8, -29, -41, -48, -56, -61, -61, -59, + -54, -45, -34, -22, -9, 4, 18, 30, 41, 52, 62, 72, 78, 83, 87, 85, 82, 78, 73, 68, 64, 62, 58, 37, 17, 0, -18, -36, -55, -75, -94, -112, + -131, -148, -165, -181, -197, -212, -228, -243, -258, -275, -291, -309, -328, -349, -371, -394, -417, -441, -466, -492, 520, 549, 575, 599, + 627, 655, 683, 713, 746, 781, 817, 855, 896, 939, 985, 1033, 1085, 1138, 1194, 1253, 1315, 1379, 1446, 1516, 1588, 1663, 1741, 1822, 1904, + 1987, 2076, 2168, 2261, 2354, 2449, 2544, 2640, 2735, 2830, 2925, 3018, 3109, 3198, 3284, 3368, 3448, 3524, 3595, 3662, 3724, 3780, 3831, + 3876, 3914, 3947, 3972, 3991, 4002, 4005, 3999, 3991, 3981, 3960, 3930, 3890, 3839, 3779, 3707, 3624, 3530, 3424, 3306, 3175, 3032, 2877, + 2709, 2528, 2336, 2131, 1914, 1685, 1444, 1191, 926, 648, 358, 56, -257, -583, -920, -1270, -1633, -2007, -2392, -2789, -3196, -3614, -4043, + -4483, -4932, -5392, -5861, -6339, -6827, -7324, -7828, -8341, -8862, -9391, -9926, -10469, -11017, -11572, -12131, -12695, -13262, -13833, + -14406, -14982, -15561, 16136, 16708, 17280, 17853, 18423, 18991, 19557, 20120, 20678, 21230, 21778, 22318, 22851, 23376, 23892, 24400, 24897, + 25384, 25860, 26325, 26778, 27217, 27644, 28055, 28452, 28833, 29197, 29545, 29876, 30189, 30485, 30764, 31024, 31267, 31492, 31698, 31886, + 32055, 32205, 32336, 32448, 32542, 32618, 32678, 32722, 32751, 32766, 32767, 32756, 32731, 32692, 32637, 32565, 32475, 32364, 32233, 32082, + 31911, 31726, 31551, 31261, 30855, 30461, 30055, 29633, 29194, 28739, 28271, 27790, 27300, 26802, 26298, 25790, 25279, 24765, 24249, 23729, + 23205, 22678, 22145, 21608, 21067, 20521, 19971, 19417, 18861, 18303, 17743, 17181, 16618, 16054, 15488, 14920, 14351, 13780, 13208, 12636, + 12064, 11494, 10925, 10359, 9795, 9233, 8671, 8108, 7542, 6972, 6398, 5818, 5236, 4654, 4077, 3512, 2965, 2445, 1961, 1516, 1114, 735, 325, +}; + + +/* 5ms delay prototype */ +const Word16 LDQMF_10_fx[] = // q = 15 sf = 15388 qsf = 14 +{ + 4, 2, -2, -7, -11, -13, -14, -14, -16, -21, -31, -44, -56, -66, -70, -67, -57, -39, -15, 12, -43, -75, -104, -132, -156, -178, -196, -210, + -221, -229, -238, -248, -262, -281, -306, -332, -353, -359, -340, -281, 168, -11, -267, -606, -1030, -1534, -2105, -2724, -3361, -3979, -4533, + -4973, -5242, -5284, -5046, -4480, -3551, -2234, -523, 1572, -4024, -6784, -9789, -12957, -16197, -19406, -22478, -25307, -27793, -29846, -31391, + -32374, -32768, -32565, -31782, -30462, -28663, -26465, -23956, -21234, 18397, 15542, 12766, 10150, 7762, 5656, 3864, 2396, 1242, 371, -221, + -567, -753, -808, -763, -646, -489, -322, -174, -64, +}; + +const Word16 LDQMF_16_fx[] = // q = 15 sf = 15388 qsf = 14 +{ + 4, 3, 1, 0, -3, -7, -9, -12, -13, -14, -14, -14, -14, -16, -19, -23, -29, -37, -45, -53, -60, -65, -69, -70, -68, -64, -56, -45, -32, -16, 0, 18, + -38, -57, -76, -95, -113, -130, -146, -161, -174, -186, -197, -206, -214, -220, -226, -231, -236, -242, -248, -257, -267, -280, -295, -311, -327, + -342, -353, -359, -357, -342, -312, -264, 194, 98, -24, -178, -364, -583, -835, -1119, -1434, -1777, -2143, -2527, -2922, -3321, -3714, -4089, + -4437, -4743, -4995, -5179, -5282, -5289, -5188, -4966, -4613, -4120, -3480, -2688, -1742, -641, 610, 2006, -3539, -5197, -6965, -8828, -10765, + -12756, -14777, -16804, -18811, -20773, -22663, -24455, -26125, -27649, -29006, -30177, -31143, -31892, -32415, -32708, -32768, -32594, -32193, + -31574, -30747, -29729, -28536, -27189, -25709, -24120, -22444, -20707, 18934, 17143, 15365, 13619, 11927, 10307, 8775, 7345, 6028, 4832, 3762, + 2820, 2002, 1305, 720, 235, -135, -394, -583, -710, -783, -808, -793, -746, -672, -581, -479, -374, -273, -182, -107, -49, +}; + +const Word16 LDQMF_20_fx[] = // q = 15 sf = 15390 qsf = 14 +{ + 4, 4, 3, 1, -1, -3, -6, -8, -10, -12, -13, -13, -14, -14, -14, -14, -15, -17, -20, -23, -28, -34, -41, -47, -53, -59, -64, -67, -70, -70, -69, -65, + -60, -53, -44, -33, -21, -8, 5, 20, -36, -51, -67, -82, -97, -111, -125, -138, -150, -162, -173, -182, -191, -199, -207, -213, -218, -223, -227, + -231, -235, -240, -245, -251, -258, -266, -276, -287, -299, -312, -325, -338, -348, -356, -360, -357, -348, -329, -300, -258, 202, 130, 40, -67, + -195, -344, -513, -704, -916, -1149, -1401, -1671, -1957, -2256, -2566, -2882, -3201, -3518, -3828, -4125, -4403, -4655, -4876, -5057, -5193, -5275, + -5297, -5252, -5134, -4936, -4654, -4283, -3818, -3258, -2600, -1843, -987, -34, 1014, 2153, -3380, -4687, -6068, -7514, -9017, -10567, -12153, -13762, + -15383, -17003, -18609, -20188, -21726, -23209, -24625, -25961, -27205, -28346, -29373, -30279, -31052, -31686, -32178, -32523, -32720, -32768, -32666, + -32417, -32026, -31496, -30835, -30049, -29149, -28143, -27043, -25859, -24603, -23288, -21925, -20528, 19110, 17678, 16249, 14835, 13446, 12092, 10783, + 9528, 8333, 7207, 6153, 5177, 4281, 3466, 2732, 2078, 1502, 999, 565, 191, -105, -324, -497, -627, -719, -777, -805, -805, -782, -739, -680, -609, -530, + -447, -363, -283, -208, -142, -88, -44, +}; + +const Word16 LDQMF_30_fx[] = // q = 15 sf = 15388 qsf = 14 +{ + 3, 4, 4, 3, 2, 0, 0, -2, -4, -5, -7, -8, -10, -11, -12, -13, -13, -13, -14, -14, -14, -14, -14, -14, -15, -16, -17, -19, -21, -24, -27, -31, -35, -40, + -44, -48, -52, -56, -60, -63, -66, -68, -69, -70, -70, -69, -67, -65, -61, -57, -51, -45, -39, -31, -23, -15, -6, 3, 12, 22, -33, -43, -54, -64, -75, + -85, -95, -104, -114, -123, -132, -140, -148, -156, -164, -171, -178, -184, -190, -196, -201, -205, -210, -214, -217, -221, -224, -227, -229, -232, -235, + -238, -241, -244, -248, -252, -257, -262, -268, -274, -281, -289, -297, -306, -314, -323, -332, -339, -347, -353, -357, -359, -359, -356, -350, -340, -325, + -306, -281, -250, 212, 168, 116, 56, -11, -87, -172, -267, -370, -484, -606, -738, -880, -1030, -1190, -1358, -1534, -1718, -1908, -2105, -2307, -2514, + -2724, -2936, -3149, -3361, -3571, -3778, -3979, -4173, -4359, -4533, -4695, -4842, -4973, -5084, -5175, -5242, -5284, -5298, -5284, -5238, -5159, -5046, + -4896, -4708, -4480, -4212, -3903, -3551, -3156, -2717, -2234, -1707, -1137, -523, 133, 832, 1572, 2352, -3170, -4024, -4913, -5833, -6784, -7762, -8765, + -9789, -10831, -11888, -12957, -14034, -15115, -16197, -17275, -18346, -19406, -20451, -21476, -22478, -23453, -24398, -25307, -26179, -27008, -27793, + -28529, -29215, -29846, -30422, -30938, -31391, -31783, -32111, -32374, -32571, -32703, -32768, -32766, -32698, -32565, -32367, -32105, -31782, -31399, + -30958, -30462, -29912, -29311, -28663, -27971, -27237, -26465, -25658, -24821, -23956, -23067, -22159, -21234, -20296, 19352, 18397, 17442, 16489, 15542, + 14603, 13677, 12766, 11872, 10999, 10150, 9326, 8529, 7762, 7027, 6324, 5656, 5023, 4425, 3864, 3338, 2849, 2396, 1977, 1593, 1242, 922, 633, 371, 134, -63, + -221, -356, -471, -567, -645, -707, -753, -784, -802, -808, -803, -788, -763, -730, -691, -646, -597, -544, -489, -433, -377, -322, -270, -220, -174, -132, + -96, -64, -36, +}; + +const Word16 LDQMF_32_fx[] = // q = 15 sf = 15392 qsf = 14 +{ + 3, 4, 4, 3, 2, 1, 0, -1, -3, -4, -6, -7, -9, -10, -11, -12, -13, -13, -13, -14, -14, -14, -14, -14, -14, -15, -15, -16, -18, -19, -22, -24, -27, -31, -35, + -39, -43, -47, -51, -54, -58, -61, -64, -66, -68, -70, -70, -70, -69, -67, -65, -62, -58, -53, -48, -42, -35, -28, -20, -12, -4, 4, 13, 22, -33, -42, -52, + -62, -72, -81, -91, -100, -109, -117, -126, -134, -142, -150, -157, -164, -171, -177, -183, -189, -194, -199, -204, -208, -212, -215, -219, -222, -224, + -227, -230, -232, -235, -237, -240, -243, -246, -250, -254, -259, -264, -270, -277, -283, -291, -298, -306, -315, -323, -331, -338, -345, -351, -356, -359, + -360, -358, -354, -347, -336, -321, -302, -278, -248, 213, 172, 125, 70, 8, -60, -137, -221, -314, -415, -525, -642, -768, -902, -1045, -1195, -1352, -1517, + -1688, -1866, -2049, -2237, -2429, -2625, -2822, -3021, -3221, -3419, -3616, -3809, -3997, -4178, -4352, -4516, -4670, -4811, -4937, -5047, -5139, -5212, -5263, + -5292, -5296, -5273, -5223, -5143, -5032, -4889, -4713, -4502, -4256, -3973, -3653, -3296, -2900, -2465, -1992, -1481, -930, -342, 283, 945, 1644, 2377, -3143, + -3942, -4771, -5628, -6512, -7421, -8353, -9304, -10273, -11256, -12252, -13256, -14267, -15281, -16294, -17305, -18309, -19303, -20284, -21249, -22194, -23116, + -24013, -24880, -25715, -26515, -27277, -27999, -28677, -29310, -29896, -30432, -30916, -31344, -31718, -32037, -32299, -32503, -32650, -32738, -32768, -32739, + -32652, -32508, -32308, -32052, -31742, -31379, -30966, -30504, -29994, -29440, -28844, -28207, -27533, -26825, -26085, -25316, -24521, -23703, -22865, -22010, + -21141, -20262, 19377, 18482, 17587, 16693, 15804, 14921, 14049, 13188, 12342, 11512, 10702, 9913, 9147, 8405, 7690, 7003, 6344, 5716, 5118, 4552, 4017, 3514, + 3043, 2603, 2195, 1817, 1468, 1149, 856, 590, 348, 127, -58, -207, -337, -448, -542, -620, -683, -733, -769, -793, -806, -808, -800, -784, -760, -729, -692, -651, + -605, -556, -505, -452, -400, -348, -297, -249, -203, -162, -124, -91, -62, -35, +}; + +const Word16 LDQMF_40_fx[] = // q = 15 sf = 15391 qsf = 14 +{ + 3, 4, 4, 4, 3, 2, 1, 0, 0, -1, -2, -4, -5, -6, -7, -9, -10, -11, -11, -12, -13, -13, -13, -13, -14, -14, -14, -14, -14, -14, -14, -14, -15, -16, -16, -18, -19, -20, + -22, -24, -27, -30, -33, -36, -39, -42, -46, -49, -52, -55, -58, -60, -63, -65, -67, -68, -69, -70, -70, -70, -69, -68, -66, -64, -61, -58, -55, -51, -46, -41, -36, + -30, -24, -18, -11, -5, 1, 9, 16, 23, -32, -39, -47, -55, -63, -71, -78, -86, -93, -101, -108, -115, -122, -128, -135, -141, -147, -153, -159, -165, -170, -175, -180, + -185, -189, -193, -197, -201, -205, -208, -211, -214, -217, -219, -222, -224, -226, -228, -230, -232, -234, -236, -239, -241, -243, -246, -249, -252, -256, -260, -264, + -268, -273, -279, -284, -290, -296, -302, -309, -315, -322, -328, -335, -340, -346, -350, -354, -357, -359, -360, -358, -356, -351, -344, -335, -323, -308, -291, -270, + -245, 217, 185, 149, 109, 64, 15, -38, -97, -161, -230, -304, -384, -469, -559, -655, -755, -861, -973, -1089, -1210, -1336, -1467, -1602, -1741, -1884, -2030, -2180, + -2333, -2487, -2644, -2802, -2962, -3121, -3281, -3439, -3596, -3751, -3903, -4052, -4196, -4335, -4468, -4595, -4714, -4824, -4925, -5016, -5096, -5163, -5218, -5259, + -5286, -5297, -5292, -5269, -5229, -5170, -5091, -4993, -4873, -4732, -4569, -4384, -4175, -3943, -3687, -3407, -3103, -2774, -2420, -2041, -1638, -1210, -758, -281, + 218, 743, 1290, 1860, 2452, -3065, -3699, -4352, -5025, -5715, -6423, -7146, -7884, -8636, -9400, -10175, -10960, -11753, -12552, -13357, -14166, -14976, -15788, -16598, + -17406, -18209, -19006, -19795, -20575, -21344, -22101, -22842, -23568, -24276, -24965, -25633, -26279, -26901, -27498, -28069, -28612, -29126, -29610, -30062, -30483, + -30870, -31222, -31539, -31820, -32066, -32276, -32448, -32584, -32683, -32744, -32768, -32754, -32703, -32615, -32491, -32330, -32135, -31904, -31639, -31341, -31010, + -30648, -30255, -29833, -29383, -28905, -28402, -27875, -27325, -26753, -26160, -25550, -24921, -24278, -23620, -22950, -22268, -21577, -20879, -20174, 19467, 18751, + 18035, 17319, 16604, 15892, 15185, 14484, 13789, 13103, 12426, 11759, 11105, 10463, 9835, 9222, 8625, 8045, 7481, 6936, 6409, 5901, 5413, 4945, 4497, 4069, 3662, 3275, + 2908, 2561, 2234, 1927, 1639, 1370, 1118, 884, 667, 466, 279, 107, -41, -164, -274, -372, -458, -533, -598, -654, -700, -737, -766, -787, -801, -807, -807, -801, -790, + -773, -751, -726, -696, -664, -628, -590, -551, -510, -468, -426, -384, -343, -302, -263, -226, -191, -158, -127, -100, -76, -54, -32, +}; + +const Word16 LDQMF_60_fx[] = // q = 15 sf = 15391 qsf = 14 +{ + 3, 4, 4, 4, 4, 3, 3, 3, 2, 1, 1, 0, 0, -1, -1, -2, -3, -4, -5, -6, -6, -7, -8, -9, -9, -10, -11, -11, -12, -12, -12, -13, -13, -13, -13, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -15, -15, -16, -16, -17, -18, -19, -20, -21, -22, -23, -25, -26, -28, -30, -32, -34, -36, -39, -41, -43, -45, -47, -49, -51, -53, -55, -57, -59, + -61, -62, -64, -65, -66, -67, -68, -69, -70, -70, -70, -70, -70, -69, -69, -68, -67, -65, -64, -62, -60, -58, -55, -53, -50, -47, -44, -40, -37, -33, -29, -25, -21, -17, -13, + -8, -3, 0, 5, 10, 15, 20, 25, -30, -36, -41, -46, -51, -57, -62, -67, -72, -77, -82, -87, -92, -97, -102, -107, -111, -116, -121, -125, -129, -134, -138, -142, -146, -150, + -154, -158, -162, -166, -169, -173, -176, -179, -182, -186, -189, -191, -194, -197, -199, -202, -204, -207, -209, -211, -213, -215, -216, -218, -220, -221, -223, -224, -226, + -227, -229, -230, -231, -233, -234, -235, -237, -238, -240, -241, -243, -245, -247, -249, -251, -253, -255, -258, -260, -263, -266, -269, -273, -276, -280, -283, -287, -291, + -295, -299, -304, -308, -312, -317, -321, -325, -329, -334, -337, -341, -345, -348, -351, -354, -356, -358, -359, -360, -359, -359, -357, -355, -352, -348, -343, -337, -329, + -321, -311, -300, -287, -273, -258, -241, 222, 202, 180, 156, 130, 102, 72, 40, 6, -29, -67, -107, -150, -195, -242, -292, -344, -398, -454, -513, -575, -638, -704, -773, -843, + -916, -992, -1069, -1149, -1231, -1315, -1401, -1489, -1579, -1671, -1765, -1860, -1957, -2055, -2155, -2256, -2358, -2462, -2566, -2671, -2776, -2882, -2988, -3095, -3201, + -3307, -3413, -3518, -3622, -3726, -3828, -3929, -4028, -4125, -4220, -4313, -4403, -4490, -4574, -4655, -4733, -4806, -4876, -4941, -5002, -5057, -5108, -5153, -5193, -5226, + -5254, -5275, -5289, -5297, -5297, -5289, -5275, -5252, -5221, -5181, -5133, -5077, -5011, -4936, -4851, -4757, -4654, -4540, -4416, -4283, -4138, -3984, -3818, -3642, -3456, + -3258, -3050, -2830, -2600, -2359, -2106, -1843, -1569, -1283, -987, -680, -362, -34, 304, 654, 1013, 1383, 1763, 2153, 2553, -2962, -3380, -3807, -4242, -4687, -5139, -5599, + -6067, -6543, -7025, -7514, -8009, -8510, -9017, -9529, -10046, -10567, -11092, -11620, -12152, -12687, -13223, -13762, -14301, -14842, -15383, -15924, -16464, -17003, -17541, + -18076, -18609, -19139, -19665, -20187, -20705, -21218, -21725, -22226, -22721, -23208, -23688, -24160, -24624, -25079, -25524, -25960, -26386, -26800, -27204, -27596, -27977, + -28345, -28701, -29043, -29373, -29688, -29990, -30278, -30552, -30810, -31052, -31278, -31489, -31685, -31865, -32029, -32177, -32308, -32424, -32522, -32605, -32670, -32719, + -32752, -32768, -32767, -32749, -32715, -32665, -32598, -32515, -32416, -32302, -32171, -32025, -31863, -31687, -31495, -31289, -31068, -30834, -30585, -30324, -30049, -29761, + -29461, -29148, -28824, -28489, -28143, -27786, -27419, -27042, -26656, -26262, -25858, -25447, -25028, -24603, -24170, -23732, -23287, -22838, -22383, -21925, -21462, -20997, + -20528, -20057, 19586, 19110, 18633, 18155, 17677, 17200, 16724, 16248, 15775, 15303, 14834, 14368, 13905, 13445, 12990, 12538, 12092, 11650, 11214, 10783, 10358, 9939, 9527, + 9122, 8724, 8333, 7950, 7574, 7207, 6847, 6496, 6153, 5819, 5493, 5177, 4869, 4570, 4281, 4000, 3728, 3466, 3212, 2968, 2732, 2505, 2287, 2078, 1878, 1686, 1502, 1326, 1159, + 999, 847, 702, 565, 434, 310, 191, 80, -19, -105, -183, -257, -324, -387, -444, -497, -545, -588, -627, -662, -693, -719, -742, -762, -777, -790, -799, -805, -808, -808, -805, + -800, -792, -782, -770, -755, -739, -721, -701, -680, -658, -634, -609, -584, -557, -530, -503, -475, -447, -419, -391, -363, -336, -309, -283, -257, -232, -208, -185, -163, + -142, -123, -104, -88, -72, -57, -44, -28, +}; + +const Word32 rot_vec_delay_re_LDQMF_fx[60] = // q = 31 +{ + -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, + 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, + -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, + 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, + -1518500224, 1518500224, 1518500224, -1518500224 +}; + +const Word32 rot_vec_delay_im_LDQMF_fx[60] = // q = 31 +{ + -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, + 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, + -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, + 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, -1518500224, -1518500224, 1518500224, 1518500224, + -1518500224, -1518500224, 1518500224, 1518500224 +}; + +const Word32 rot_vec_ana_re_L10_fx[5] = // q = 29 +{ + 1517329536, 1424643840, 1192503936, 843633536, 412182400 +}; + +const Word32 rot_vec_ana_im_L10_fx[5] = // q = 29 +{ + -59616040, -525578848, -940094336, -1262586752, -1461488512 +}; + +const Word32 rot_vec_ana_re_L16_fx[8] = // q = 29 +{ + 1200118272, 1171310720, 1097490432, 981494080, 827779520, 642253888, 432046752, 205236304 +}; + +const Word32 rot_vec_ana_im_L16_fx[8] = // q = 29 +{ + -29461250, -263026624, -486484032, -691246144, -869444032, -1014229696, -1120039040, -1182806016 +}; + +const Word32 rot_vec_ana_re_L20_fx[10] = // q = 29 +{ + 1073534848, 1057019968, 1014477760, 946955776, 856116544, 744196864, 613952640, 468590848, 311690784, 147115888 +}; + +const Word32 rot_vec_ana_im_L20_fx[10] = // q = 29 +{ + -21081516, -188759824, -351790240, -506158400, -648063232, -774010624, -880899328, -966097344, -1027506880, -1063615744 +}; + +const Word32 rot_vec_ana_re_L30_fx[15] = // q = 29 +{ + 876631424, 870629568, 855088960, 830179840, 796175040, 753447232, 702464448, 643785344, 578052800, 505986944, 428377440, 346074528, 259979936, 171036960, 80220064 +}; + +const Word32 rot_vec_ana_im_L30_fx[15] = // q = 29 +{ + -11475734, -103045800, -193486880, -281808064, -367041728, -448253984, -524555072, -595109056, -659142848, -715955008, -764922944, -805510272, -837272192, -859860864, -873028672 +}; + +const Word32 rot_vec_ana_re_L32_fx[16] = // q = 29 +{ + 848803520, 843695296, 830461760, 809230464, 780205824, 743667392, 699967040, 649525568, 592828864, 530422880, 462908640, 390936320, 315199072, 236426304, 155376608, 72830544 +}; + +const Word32 rot_vec_ana_im_L32_fx[16] = // q = 29 +{ + -10416909, -93564040, -175810112, -256363024, -334447008, -409310112, -480231328, -546527616, -607560576, -662742400, -711541696, -753488384, -788178560, -815278208, -834526272, -845737344 +}; + +const Word32 rot_vec_ana_re_L40_fx[20] = // q = 29 +{ + 759213504, 756288320, 748700352, 736496320, 719751616, 698569408, 673080256, 643441344, 609835392, 572469632, 531574400, 487401824, 440224256, 390332576, 338034336, + 283652032, 227520896, 169987024, 111405128, 52136384 +}; + +const Word32 rot_vec_ana_im_L40_fx[20] = // q = 29 +{ + -7453801, -66998032, -126129192, -184482736, -241698864, -297424864, -351317120, -403043392, -452284768, -498737664, -542115648, -582151360, -618597888, -651230528, + -679848192, -704274304, -724358336, -739976448, -751032384, -757457984 +}; + +const Word32 rot_vec_ana_re_L60_fx[30] = // q = 29 +{ + 619911872, 618849920, 616091776, 611644992, 605521728, 597738752, 588317440, 577283520, 564667392, 550503488, 534830720, 517692032, 499134368, 479208608, 457969376, 435474880, 411786784, + 386970016, 361092576, 334225408, 306442144, 277818944, 248434272, 218368656, 187704512, 156525872, 124918216, 92968160, 60763288, 28391868 +}; + +const Word32 rot_vec_ana_im_L60_fx[30] = // q = 29 +{ + -4057371, -36495492, -68833576, -100983000, -132855632, -164364112, -195422080, -225944416, -255847456, -285049248, -313469728, -341030976, -367657536, -393276352, -417817216, -441212864, + -463399200, -484315392, -503904096, -522111616, -538888128, -554187520, -567967936, -580191616, -590825024, -599838976, -607208896, -612914432, -616940032, -619274624 +}; + /*-------------------------------------------------------------------* * LP CNG excitation details code book *-------------------------------------------------------------------*/ @@ -22419,6 +22849,33 @@ const float LastCoefPred_1bit[36] = { -0.01554f, -0.02277f, -0.00474f, 0.00468f, 0.01070f, 0.04327f, 0.09857f, 0.26611f, -0.01164f }; +const Word16 f_atan_expand_range[MAXSFTAB - (MINSFTAB - 1)] = +{ + /***************************************************************************** + * + * Table holds fixp_atan() output values which are outside of input range + * of fixp_atan() to improve SNR of fixp_atan2(). + * + * This Table might also be used in fixp_atan() [todo] so there a wider input + * range can be covered, too. + * + * Matlab (generate table): + * for scl = 7:25 % MINSFTAB .. MAXSFTAB + * at=atan(0.5 *(2^scl)); % 0.5 because get in 'middle' area of current scale level 'scl' + * at/2 % div at by ATO_SCALE + * end + * + * Table divided by 2=ATO_SCALE <-- SF=ATO_SF + *****************************************************************************/ + 25480/*7.775862990872099e-001 Q15*/, 25608/*7.814919928673978e-001 Q15*/, 25672/*7.834450483314648e-001 Q15*/, + 25704/*7.844216021392089e-001 Q15*/, 25720/*7.849098823026687e-001 Q15*/, 25728/*7.851540227918509e-001 Q15*/, + 25732/*7.852760930873737e-001 Q15*/, 25734/*7.853371282415015e-001 Q15*/, 25735/*7.853676458193612e-001 Q15*/, + 25735/*7.853829046083906e-001 Q15*/, 25736/*7.853905340029177e-001 Q15*/, 25736/*7.853943487001828e-001 Q15*/, + 25736/*7.853962560488155e-001 Q15*/, 25736/*7.853972097231319e-001 Q15*/, 25736/*7.853976865602901e-001 Q15*/, + 25736/*7.853979249788692e-001 Q15*/, 25736/*7.853980441881587e-001 Q15*/, 25736/*7.853981037928035e-001 Q15*/, + 25736/*7.853981335951259e-001 Q15*/ + /* pi/4 = 0.785398163397448 = pi/2/ATO_SCALE */ +}; const int16_t config_LSF_BWE[] = { 4, 16, 1, /* 21 bits */ 4, 16, 1, /* 20 */ diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index ad234e26d..0a8e5ba51 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -46,7 +46,9 @@ #include "stat_dec.h" #include "stl.h" #include "basop_util.h" - +#define MINSFTAB 7 +#define MAXSFTAB 25 +#define INTERP_EXP 0 typedef struct { int32_t fin; /* input frequency */ @@ -1092,6 +1094,58 @@ extern const float rot_vec_syn_im_L40[20]; extern const float rot_vec_syn_re_L60[30]; extern const float rot_vec_syn_im_L60[30]; + +extern const Word32 rot_vec_syn_re_L10_fx[5]; +extern const Word32 rot_vec_syn_im_L10_fx[5]; +extern const Word32 rot_vec_syn_re_L16_fx[8]; +extern const Word32 rot_vec_syn_im_L16_fx[8]; +extern const Word32 rot_vec_syn_re_L20_fx[10]; +extern const Word32 rot_vec_syn_im_L20_fx[10]; +extern const Word32 rot_vec_syn_re_L30_fx[15]; +extern const Word32 rot_vec_syn_im_L30_fx[15]; +extern const Word32 rot_vec_syn_re_L32_fx[16]; +extern const Word32 rot_vec_syn_im_L32_fx[16]; +extern const Word32 rot_vec_syn_re_L40_fx[20]; +extern const Word32 rot_vec_syn_im_L40_fx[20]; +extern const Word32 rot_vec_syn_re_L60_fx[30]; +extern const Word32 rot_vec_syn_im_L60_fx[30]; + +extern const Word16 CLDFB80_10_fx[100]; +extern const Word16 CLDFB80_16_fx[160]; +extern const Word16 CLDFB80_20_fx[200]; +extern const Word16 CLDFB80_30_fx[300]; +extern const Word16 CLDFB80_32_fx[320]; +extern const Word16 CLDFB80_40_fx[400]; +extern const Word16 CLDFB80_60_fx[600]; + +/*5ms delay*/ +extern const Word16 LDQMF_10_fx[100]; +extern const Word16 LDQMF_16_fx[160]; +extern const Word16 LDQMF_20_fx[200]; +extern const Word16 LDQMF_30_fx[300]; +extern const Word16 LDQMF_32_fx[320]; +extern const Word16 LDQMF_40_fx[400]; +extern const Word16 LDQMF_60_fx[600]; + +extern const Word32 rot_vec_delay_re_LDQMF_fx[60]; +extern const Word32 rot_vec_delay_im_LDQMF_fx[60]; + +extern const Word32 rot_vec_ana_re_L10_fx[5]; +extern const Word32 rot_vec_ana_im_L10_fx[5]; +extern const Word32 rot_vec_ana_re_L16_fx[8]; +extern const Word32 rot_vec_ana_im_L16_fx[8]; +extern const Word32 rot_vec_ana_re_L20_fx[10]; +extern const Word32 rot_vec_ana_im_L20_fx[10]; +extern const Word32 rot_vec_ana_re_L30_fx[15]; +extern const Word32 rot_vec_ana_im_L30_fx[15]; +extern const Word32 rot_vec_ana_re_L32_fx[16]; +extern const Word32 rot_vec_ana_im_L32_fx[16]; +extern const Word32 rot_vec_ana_re_L40_fx[20]; +extern const Word32 rot_vec_ana_im_L40_fx[20]; +extern const Word32 rot_vec_ana_re_L60_fx[30]; +extern const Word32 rot_vec_ana_im_L60_fx[30]; + + extern const float bpf_weights_16[CLDFB_NO_COL_MAX]; extern const float CNG_details_codebook[64][NUM_ENV_CNG]; @@ -1366,5 +1420,5 @@ extern const float *const cb_LSF_BWE[]; extern const float LastCoefPred_0bit[18]; extern const float LastCoefPred_1bit[36]; extern const int16_t config_LSF_BWE[]; - +extern const Word16 f_atan_expand_range[MAXSFTAB - ( MINSFTAB - 1 )]; #endif diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 90203dc47..52ff10150 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -585,30 +585,50 @@ typedef struct cldfb_filter_bank_struct const float *p_filter; + const Word16 *p_filter_fx; /*!< Pointer to filter coefficients */ + Word16 p_filter_sf; + /* rotation vectors */ const float *rot_vec_ana_re; const float *rot_vec_ana_im; const float *rot_vec_syn_re; const float *rot_vec_syn_im; + const Word32 *rot_vec_syn_re_fx; + const Word32 *rot_vec_syn_im_fx; + + const Word32 *rot_vec_syn_delay_re_fx; + const Word32 *rot_vec_syn_delay_im_fx; /* rotation vectors for delay */ const float *rot_vec_ana_delay_re; const float *rot_vec_ana_delay_im; const float *rot_vec_syn_delay_re; const float *rot_vec_syn_delay_im; + const Word32 *rot_vec_ana_re_fx; + const Word32 *rot_vec_ana_im_fx; + + const Word32 *rot_vec_ana_delay_re_fx; + const Word32 *rot_vec_ana_delay_im_fx; + /* memory helper states */ float *memory; uint16_t memory_length; - + Word32 *memory32; /*because cldfb_state_fx is word32 which is used to assign values*/ /* main filter state */ float *cldfb_state; + Word32 *cldfb_state_fx; // Q11 + Word16 cldfb_state_length; + Word16 Q_cldfb_state; + Word16 Q_split; /* other parameters */ int16_t bandsToZero; /* bands not synthesized */ int16_t nab; /* number of active bands */ float scale; /* scaling of frequency domain */ + Word16 scale_fx; + Word16 q_scale; } CLDFB_FILTER_BANK, *HANDLE_CLDFB_FILTER_BANK; diff --git a/lib_com/stl.h b/lib_com/stl.h index be5722630..f4257917b 100644 --- a/lib_com/stl.h +++ b/lib_com/stl.h @@ -57,14 +57,32 @@ #ifndef _STL_H #define _STL_H +#define ENH_U_32_BIT_OPERATOR +#define COMPLEX_OPERATOR +#define CONTROL_CODE_OPS +#define ENH_32_BIT_OPERATOR +#define ENH_64_BIT_OPERATOR +#define BASOP_NOGLOB +#if defined BASOP_NOGLOB && !defined BASOP_NOGLOB_DEV_USE_GLOBALS +#define BASOP_NOGLOB_DECLARE_LOCAL +#endif +//#define EVS_FLOAT + #include "options.h" /* note: needed until BASOP_NOGLOB is accepted */ #include "typedef.h" #include "basop32.h" -#include "wmc_auto.h" +#include "count.h" +//#include "wmc_auto.h" #include "move.h" +#include "control.h" +#include "oper_32b.h" #include "enh1632.h" #include "enh40.h" - +#include "enh64.h" +#include "math_op.h" +#include "enhUL32.h" +#include "enh32.h" +//#include "complex_basop.h" #endif /* ifndef _STL_H */ diff --git a/lib_com/tools.c b/lib_com/tools.c index ecd2fdbfa..89a795049 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -42,7 +42,7 @@ #include #include "prot.h" #include "wmc_auto.h" - +#include "basop_mpy.h" /*------------------------------------------------------------------* * own_random() * @@ -92,6 +92,7 @@ float log2_f( return (float) ( log( x ) / log( 2.0f ) ); } +#ifndef FIX_NORM_UL_LOC int16_t norm_ul( uint32_t UL_var1 ) { int16_t var_out; @@ -111,6 +112,7 @@ int16_t norm_ul( uint32_t UL_var1 ) return ( var_out ); } +#endif /*--------------------------------------------------------------------- @@ -945,7 +947,28 @@ void v_multc( return; } +/*-------------------------------------------------------------------* + * v_multc_fixed() + * + * Multiplication of vector by constant + *-------------------------------------------------------------------*/ + +void v_multc_fixed( + const Word32 x[], /* i : Input vector */ + const Word32 c, /* i : Constant */ + Word32 y[], /* o : Output vector that contains c*x */ + const Word16 N /* i : Vector length */ +) +{ + Word16 i; + FOR( i = 0; i < N; i++ ) + { + y[i] = Mpy_32_32( c, x[i] ); + } + + return; +} /*-------------------------------------------------------------------* * squant() * diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c new file mode 100644 index 000000000..4ee5af46b --- /dev/null +++ b/lib_com/tools_fx.c @@ -0,0 +1,230 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +/*==================================================================================== + 3GPP TS26.258 Aug 24, 2023. IVAS Codec Version IVAS-FL-1.0 + ====================================================================================*/ + +/*==================================================================================== + EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 + ====================================================================================*/ + +#include +#include +#include +#include "options.h" +#include "stl.h" +#include +#include "cnst.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "basop32.h" +#include "wmc_auto.h" + +#define INV_BANDS10 3277 /* 1/10 in Q15 */ +#define INV_BANDS9 3641 /* 1/9 in Q15 */ +#define INV_BANDS3 10923 /* 1/9 in Q15 */ +const Word16 b_hp400_fx[3] = { 3660, -7320, 3660 }; /* Q12 (/4) */ +const Word16 a_hp400_fx[3] = { 16384, 29280, -14160 }; + +// conversion functions: +Word32 float_to_fix( float number, Word32 Q ) +{ + assert( Q >= 0 ); + assert( fabs( number ) < pow( 2, 31 - Q ) ); + Word32 ret = (Word32) ( number * ( (UWord32) 1 << Q ) ); + return ret; +} + +float fix_to_float( Word32 number, Word32 Q ) +{ + assert( Q >= 0 ); + float ret = (float) number / ( (UWord32) 1 << Q ); + return ret; +} + +Word16 float_to_fix16( float number, Word16 Q ) +{ + assert( Q >= 0 ); + if ( number == 1.0f && Q == Q15 ) + return MAX16B; + assert( fabs( number ) < pow( 2, 15 - Q ) ); + Word16 ret = (Word16) ( number * ( (UWord16) 1 << Q ) ); + return ret; +} + +float fix16_to_float( Word16 number, Word16 Q ) +{ + assert( Q >= 0 ); + float ret = (float) number / ( (UWord16) 1 << Q ); + return ret; +} + +// Float to 32-bit Mantissa and Exponent +void f2me( float n, Word32 *mantissa, Word16 *expo ) +{ + Word32 e; + float mf = (float) frexp( n, &e ); + *expo = (Word16) e; + *mantissa = float_to_fix( mf, Q31 ); +} + +// 32-bit Mantissa and Exponent to Float +float me2f( Word32 m, Word16 expo ) +{ + float mf = fix_to_float( m, Q31 ); + return (float) ldexp( mf, expo ); +} + +// Float buffer to 32-bit mantissa buffer and common exponent. +void f2me_buf( const float *x, Word32 *m, Word16 *e, const Word32 n ) +{ + Word16 max_e = -32, tmp_e; + Word32 i; + + for ( i = 0; i < n; i++ ) + { + f2me( x[i], &m[i], &tmp_e ); + max_e = ( max_e > tmp_e ) ? max_e : tmp_e; + } + + for ( i = 0; i < n; i++ ) + { + f2me( x[i], &m[i], &tmp_e ); + m[i] = L_shr( m[i], max_e - tmp_e ); + } + + *e = max_e; +} + +// 32-bit Mantissa buffer and exponent into float buffer. +void me2f_buf( const Word32 *m, const Word16 e, float *out, const Word32 n ) +{ + for ( int i = 0; i < n; i++ ) + { + out[i] = me2f( m[i], e ); + } +} + +// Float to 16-bit Mantissa and Exponent +void f2me_16( float n, Word16 *mantissa, Word16 *expo ) +{ + Word32 e; + float mf = (float) frexp( n, &e ); + *expo = (Word16) e; + *mantissa = float_to_fix16( mf, 15 ); +} + +// 16-bit Mantissa and Exponent to Float +float me2f_16( Word16 m, Word16 expo ) +{ + float mf = fix16_to_float( m, 15 ); + return (float) ldexp( mf, expo ); +} + +// Float buffer to 16-bit mantissa buffer and common exponent. +void f2me_buf_16( const float *x, Word16 *m, Word16 *e, const Word32 n ) +{ + Word16 max_e = -16, tmp_e; + Word32 i; + + for ( i = 0; i < n; i++ ) + { + f2me_16( x[i], &m[i], &tmp_e ); + max_e = ( max_e > tmp_e ) ? max_e : tmp_e; + } + + for ( i = 0; i < n; i++ ) + { + f2me_16( x[i], &m[i], &tmp_e ); + m[i] = shr( m[i], max_e - tmp_e ); + } + + *e = max_e; +} + +// 16-bit Mantissa buffer and exponent into float buffer. +void me2f_buf_16( const Word16 *m, const Word16 e, float *out, const Word32 n ) +{ + for ( int i = 0; i < n; i++ ) + { + out[i] = me2f_16( m[i], e ); + } +} +// void f2fix( float *var_flt, Word32 *var_fix, Word32 expo ) +//{ +// *var_fix = (Word32) ( *var_flt * pow( 2, 31 - expo ) ); +// } +// +// void fix2f( Word32 *var_fix, float *var_flt, Word32 expo ) +//{ +// float mf = fix_to_float( *var_fix, 31 ); +// *var_flt = (float) ldexp( mf, expo ); +// } +// +// void f2fix_16( float *var_flt, Word16 *var_fix, Word32 expo ) +//{ +// *var_fix = (Word16) ( *var_flt * pow( 2, 15 - expo ) ); +// } +// +// void fix2f_16( Word16 *var_fix, float *var_flt, Word32 expo ) +//{ +// float mf = fix16_to_float( *var_fix, 15 ); +// *var_flt = (float) ldexp( mf, expo ); +// } + +/*-------------------------------------------------------------------* + * Scale_sig32 + * + * Up/down scale a 32 bits vector + *-------------------------------------------------------------------*/ +void Scale_sig32( + Word32 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Word16 i; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + FOR( i = 0; i < lg; i++ ) + { +#ifdef BASOP_NOGLOB + x[i] = L_shl_o( x[i], exp0, &Overflow ); +#else + x[i] = L_shl( x[i], exp0 ); +#endif + move32(); /* saturation can occur here */ + } +} diff --git a/lib_com/typedef.h b/lib_com/typedef.h index 9b1ed7bc9..8a4002787 100644 --- a/lib_com/typedef.h +++ b/lib_com/typedef.h @@ -62,7 +62,7 @@ | Basic types. | |_____________________| */ - +#define ENH_64_BIT_OPERATOR #ifndef TYPEDEF_H #define TYPEDEF_H @@ -118,11 +118,19 @@ typedef int Flag; #define TYPEDEF_INITIALIZED #endif + +/* Definition of Word64 */ +//#ifdef ENH_64_BIT_OPERATOR +#define Word64 long long int +//#endif /* #ifdef ENH_64_BIT_OPERATOR */ + typedef float Float32; #ifndef TYPEDEF_INITIALIZED #error types in typedef.h not initialized #endif +typedef int Counter; +#define maxWord32 INT32_MAX #endif /* ifndef _TYPEDEF_H */ diff --git a/lib_debug/tinywaveout_c.h b/lib_debug/tinywaveout_c.h new file mode 100644 index 000000000..9b11e325a --- /dev/null +++ b/lib_debug/tinywaveout_c.h @@ -0,0 +1,634 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef __TINYWAVEOUT_C_H__ +#define __TINYWAVEOUT_C_H__ + +#include +#include +#include + +#if defined( __i386__ ) || defined( _M_IX86 ) || defined( _M_X64 ) || defined( __x86_64__ ) || defined( __arm__ ) || defined( __aarch64__ ) || ( defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) +#define __TWO_LE /* _T_iny _W_ave _O_ut _L_ittle _E_ndian */ +#endif + +#if defined( __POWERPC__ ) || defined( __sparc__ ) || ( defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) +#define __TWO_BE /* _T_iny _W_ave _O_ut _B_ig _E_ndian */ +#endif + +#if !defined( __TWO_LE ) && !defined( __TWO_BE ) +#pragma message( "unknown processor - assuming Little Endian" ) +#define __TWI_LE +#endif + +#define __TWO_SUCCESS ( 0 ) +#define __TWO_ERROR ( -1 ) + +/*--- local types/structs ----------------------------------*/ + +#if defined( _MSC_VER ) +#pragma pack( push, 1 ) +#else +#pragma pack( 1 ) +#endif + +#ifndef TW_INT64 +#if !( defined( WIN32 ) ) +#include +#define TWO_INT64 /* long long */ int64_t +#else +#define TWO_INT64 __int64 +#endif +#endif + +typedef struct __tinyWaveOutHeader +{ + uint32_t riffType; /* 'RIFF' */ + uint32_t riffSize; /* file size */ + + uint32_t waveType; /* 'WAVE' */ +} __tinyWaveOutHeader; + +typedef struct __tinyWaveOutFmtChunk +{ + uint32_t formatType; + uint32_t formatSize; + + uint16_t formatTag; + uint16_t numChannels; + uint32_t sampleRate; + uint32_t bytesPerSecond; + uint16_t blockAlignment; + uint16_t bitsPerSample; + + /* wav fmt ext hdr here */ +} __tinyWaveOutFmtChunk; + +typedef struct __tinyWaveOutDataChunk +{ + uint32_t dataType; + uint32_t dataSize; + +} __tinyWaveOutDataChunk; + +typedef struct __tinyWaveOutHandle +{ + FILE *theFile; + uint32_t dataSize; + TWO_INT64 dataSizeLimit; + uint32_t fmtChunkOffset; + uint32_t dataChunkOffset; + uint32_t bps; + uint32_t clipCount; +} __tinyWaveOutHandle, WAVEFILEOUT; + +/*--- local protos --------------------------------------------------*/ +static __inline uint32_t BigEndian32( char, char, char, char ); +static __inline uint32_t LittleEndian32( uint32_t ); +static __inline uint32_t LittleEndian32s( int32_t ); +static __inline int16_t LittleEndian16( int16_t ); +static __inline int32_t __dataSizeChk( WAVEFILEOUT *self, int32_t newbytes ); + +#if defined( _MSC_VER ) +#pragma pack( pop ) +#else +#pragma pack() +#endif + +static WAVEFILEOUT *CreateBWF( + const char *fileName, + const uint32_t sampleRate, + const uint32_t numChannels, + const uint32_t bps + /* ,const uint32_t writeWaveExt */ ) +{ + WAVEFILEOUT *self; + __tinyWaveOutHeader whdr; + __tinyWaveOutFmtChunk wfch; + __tinyWaveOutDataChunk wdch; + uint32_t blockAlignment = 0; + uint32_t ByteCnt = 0; /* Byte counter for fwrite */ + + self = (WAVEFILEOUT *) calloc( 1, sizeof( WAVEFILEOUT ) ); + if ( !self ) + { + goto bail; /* return NULL; */ + } + + if ( !fileName ) + { + goto bail; + } + if ( sampleRate == 0 ) + { + goto bail; + } + if ( sampleRate > 768000 ) + { + goto bail; + } + if ( numChannels == 0 ) + { + goto bail; + } + if ( numChannels > 64 ) + { + goto bail; + } + if ( bps != 16 && bps != 24 && bps != 32 ) + { + goto bail; + } + + self->theFile = fopen( fileName, "wb+" ); + if ( !self->theFile ) + { + goto bail; + } + + /* WAV-Header */ + whdr.riffType = BigEndian32( 'R', 'I', 'F', 'F' ); + whdr.riffSize = LittleEndian32( 0xffffffff ); /* set to maximum, if fseek() doesn't work later */ + whdr.waveType = BigEndian32( 'W', 'A', 'V', 'E' ); + /* write to file */ + ByteCnt = 0; + ByteCnt += (uint32_t) fwrite( &whdr, 1, sizeof( whdr ), self->theFile ); + + /* FMT-Chunk */ + wfch.formatType = BigEndian32( 'f', 'm', 't', ' ' ); + wfch.formatSize = LittleEndian32( 16 ); + switch ( bps ) + { + case 16: + case 24: + wfch.formatTag = LittleEndian16( 0x0001 ); /* WAVE_FORMAT_PCM */ + break; + case 32: + wfch.formatTag = LittleEndian16( 0x0003 ); /* WAVE_FORMAT_IEEE_FLOAT */ + break; + default: + goto bail; + } + self->bps = bps; + wfch.bitsPerSample = LittleEndian16( (int16_t) bps ); + wfch.numChannels = LittleEndian16( (int16_t) numChannels ); + blockAlignment = numChannels * ( bps >> 3 ); + wfch.blockAlignment = LittleEndian16( (int16_t) blockAlignment ); + wfch.sampleRate = LittleEndian32( sampleRate ); + wfch.bytesPerSecond = LittleEndian32( sampleRate * blockAlignment ); + /* write to file */ + self->fmtChunkOffset = ByteCnt; + ByteCnt += (uint32_t) fwrite( &wfch, 1, sizeof( wfch ), self->theFile ); + + /* DATA-Chunk */ + self->dataChunkOffset = ByteCnt; + wdch.dataType = BigEndian32( 'd', 'a', 't', 'a' ); + wdch.dataSize = LittleEndian32( 0xffffffff - ByteCnt ); /* yet unknown. set to maximum of 4 GB file */ + /* write to file */ + ByteCnt += (uint32_t) fwrite( &wdch, 1, sizeof( wdch ), self->theFile ); + + self->dataSize = 0; + self->dataSizeLimit = LittleEndian32( 0xffffffff - ByteCnt ); /* maximum size for data chunk for 4 GB files */ + /* self->dataSizeLimit = LittleEndian32(0x7fffffff - ByteCnt); */ /* maximum size for data chunk for 2 GB files */ + + self->clipCount = 0; + + return self; + +bail: + free( self ); + return NULL; +} + +static WAVEFILEOUT *CreateWav( + const char *fileName, + const uint32_t sampleRate, + const uint32_t numChannels, + const uint32_t bps + /* const uint32_t writeWaveExt */ +) +{ + return CreateBWF( fileName, sampleRate, numChannels, bps ); +} + +static const int16_t MAX_PCM16 = 32767; +static const int16_t MIN_PCM16 = -32768; +static __inline int32_t CLIP_PCM16( + int32_t sample, + uint32_t *clipcount ) +{ + int32_t tmp = sample; + + if ( sample >= MAX_PCM16 ) + { + tmp = MAX_PCM16; + ( *clipcount )++; + } + else + { + if ( sample <= MIN_PCM16 ) + { + tmp = MIN_PCM16; + ( *clipcount )++; + } + } + + return tmp; +} + +static const int32_t MAX_PCM24 = 8388607; +static const int32_t MIN_PCM24 = -8388608; +static __inline int32_t CLIP_PCM24( + int32_t sample, + uint32_t *clipcount ) +{ + int32_t tmp = sample; + + if ( sample >= MAX_PCM24 ) + { + tmp = MAX_PCM24; + ( *clipcount )++; + } + else + { + if ( sample <= MIN_PCM24 ) + { + tmp = MIN_PCM24; + ( *clipcount )++; + } + } + + return tmp; +} +#define MAX_FLOAT32 ( +1.0f ) +#define MIN_FLOAT32 ( -1.0f ) +static __inline float CLIP_FLOAT32( + float sample, + uint32_t *clipcount ) +{ + float tmp = sample; + + if ( sample >= MAX_FLOAT32 ) + { + tmp = MAX_FLOAT32; + ( *clipcount )++; + } + else + { + if ( sample <= MIN_FLOAT32 ) + { + tmp = MIN_FLOAT32; + ( *clipcount )++; + } + } + + return tmp; +} + +static int32_t __WriteSample16( + WAVEFILEOUT *self, + int32_t sample, + int32_t scale ) +{ + size_t cnt; + int16_t v; + + if ( 16 != scale ) + { + if ( ( scale - 16 ) > 0 ) + { + sample = sample >> ( scale - 16 ); + } + else + { + sample = sample << ( 16 - scale ); + } + } + + v = (int16_t) CLIP_PCM16( sample, &( self->clipCount ) ); +#ifdef __TWO_BE + v = LittleEndian16( v ); +#endif + + cnt = fwrite( &v, sizeof( int16_t ), 1, self->theFile ); + + if ( cnt == 1 ) + { + self->dataSize += 2; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + +static int32_t __WriteSample24( + WAVEFILEOUT *self, + int32_t sample, + int32_t scale ) +{ + size_t cnt; + int32_t v; + + if ( ( scale - 24 ) > 0 ) + { + sample = sample >> ( scale - 24 ); + } + else + { + sample = sample << ( 24 - scale ); + } + + v = (int32_t) CLIP_PCM24( sample, &( self->clipCount ) ); +#ifdef __TWO_BE + v = LittleEndian32s( v ); +#endif + cnt = fwrite( &v, 3, 1, self->theFile ); + + if ( cnt == 1 ) + { + self->dataSize += 3; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + +static int32_t __WriteSample32( + WAVEFILEOUT *self, + float sample ) +{ + size_t cnt; + union fl_int + { + float v_float; + int32_t v_int; + }; + union fl_int v; + +#if CLIP_FLOAT + v.v_float = CLIP_FLOAT32( sample, &( self->clipCount ) ); +#else + v.v_float = sample; + if ( ( sample > 1.0f ) || ( sample < -1.0f ) ) + { + self->clipCount++; + } +#endif + +#ifdef __TWO_BE + v.v_int = LittleEndian32s( v.v_int ); +#endif + cnt = fwrite( &v, 4, 1, self->theFile ); + + if ( cnt == 1 ) + { + self->dataSize += 4; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + +static int32_t __WriteSampleInt( + WAVEFILEOUT *self, + int32_t sample, + int32_t scale ) +{ + int32_t err; + + if ( !self ) + { + return __TWO_ERROR; + } + + switch ( self->bps ) + { + case 16: + err = __WriteSample16( self, sample, scale ); + break; + + case 24: + err = __WriteSample24( self, sample, scale ); + break; + + default: + err = __TWO_ERROR; + break; + } + + return err; +} + +/* this function expects values in the 16 bit range +-32767/8 */ +static int32_t WriteWavShort( + WAVEFILEOUT *self, + int16_t sampleBuffer[], + uint32_t nSamples ) +{ + uint32_t i; + int32_t err = __TWO_SUCCESS; + + if ( !self ) + { + return __TWO_ERROR; + } + if ( !sampleBuffer ) + { + return __TWO_ERROR; + } + if ( __dataSizeChk( self, nSamples * sizeof( int16_t ) ) ) + { + return __TWO_ERROR; + } + + for ( i = 0; i < nSamples; i++ ) + { + if ( self->bps == 32 ) + { + err = __WriteSample32( self, sampleBuffer[i] / 32768.0f ); + } + else + { + err = __WriteSampleInt( self, (int32_t) sampleBuffer[i], 16 ); + } + if ( err != __TWO_SUCCESS ) + { + return err; + } + } + + return __TWO_SUCCESS; +} + +#ifdef DEBUG_JBM +/* this function expects values in the 16 bit range +-32767/8 */ +static int32_t WriteWavFloat( + WAVEFILEOUT *self, + float sampleBuffer[], + uint32_t nSamples ) +{ + uint32_t i; + int32_t err = __TWO_SUCCESS; + + if ( !self ) + { + return __TWO_ERROR; + } + if ( !sampleBuffer ) + { + return __TWO_ERROR; + } + if ( __dataSizeChk( self, nSamples * sizeof( float ) ) ) + { + return __TWO_ERROR; + } + + for ( i = 0; i < nSamples; i++ ) + { + if ( self->bps == 32 ) + { + err = __WriteSample32( self, sampleBuffer[i] / 32768.0f ); + } + else + { + err = __TWO_ERROR; + } + if ( err != __TWO_SUCCESS ) + { + return err; + } + } + + return __TWO_SUCCESS; +} +#endif + +static int32_t CloseWav( + WAVEFILEOUT *self ) +{ + uint32_t riffSize_le = 0; + uint32_t dataSize_le = 0; + + if ( !self ) + { + return __TWO_ERROR; + } + + riffSize_le = LittleEndian32( + self->dataChunkOffset - 8 + 8 + + self->dataSize ); /* sizeof(hdr) - (8 bytes of riff chunk header) + (8 bytes data chunk + header) + sizeof(raw-pcm-data) */ + dataSize_le = LittleEndian32( self->dataSize ); + + /* now overwrite length/size values in header with the actual/real ones */ + /* fseek(self->theFile, 0, SEEK_SET);*/ + + /* seek to riffsize */ + fseek( self->theFile, 4, SEEK_SET ); + fwrite( &riffSize_le, sizeof( riffSize_le ), 1, self->theFile ); + /* seek to datasize */ + fseek( self->theFile, self->dataChunkOffset + 4, SEEK_SET ); + fwrite( &dataSize_le, sizeof( dataSize_le ), 1, self->theFile ); + + fclose( self->theFile ); + free( self ); + + return __TWO_SUCCESS; +} + +/*------------- local subs ----------------*/ + +static __inline uint32_t BigEndian32( + char a, + char b, + char c, + char d ) +{ +#ifdef __TWO_LE + return (uint32_t) d << 24 | (uint32_t) c << 16 | (uint32_t) b << 8 | (uint32_t) a; +#else + return (uint32_t) a << 24 | (uint32_t) b << 16 | (uint32_t) c << 8 | (uint32_t) d; +#endif +} + +static __inline uint32_t LittleEndian32( + uint32_t v ) +{ +#ifdef __TWO_LE + return v; +#else + return ( v & 0x000000FF ) << 24 | ( v & 0x0000FF00 ) << 8 | + ( v & 0x00FF0000 ) >> 8 | ( v & 0xFF000000 ) >> 24; +#endif +} + +/* signed version of the above */ +static __inline uint32_t LittleEndian32s( + int32_t v ) +{ +#ifdef __TWO_LE + return v; +#else + return ( v & 0x000000FF ) << 24 | ( v & 0x0000FF00 ) << 8 | + ( v & 0x00FF0000 ) >> 8 | ( v & 0xFF000000 ) >> 24; +#endif +} + +static __inline int16_t LittleEndian16( + int16_t v ) +{ +#ifdef __TWO_LE + return v; +#else + return ( ( v << 8 ) & 0xFF00 ) | ( ( v >> 8 ) & 0x00FF ); +#endif +} + +static __inline int32_t __dataSizeChk( + WAVEFILEOUT *self, + int32_t newbytes ) +{ + if ( !self ) + { + return __TWO_ERROR; + } + + if ( ( ( (TWO_INT64) self->dataSize ) + ( (TWO_INT64) newbytes ) ) > + self->dataSizeLimit ) + { + return __TWO_ERROR; + } + + return __TWO_SUCCESS; +} + +#endif /* __TINYWAVEOUT_C_H__ */ diff --git a/lib_debug/wmc_auto.c b/lib_debug/wmc_auto.c index 1ab20a2ee..a36021c9f 100644 --- a/lib_debug/wmc_auto.c +++ b/lib_debug/wmc_auto.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #ifndef _MSC_VER @@ -30,16 +29,16 @@ #include "wmc_auto.h" #define WMC_TOOL_SKIP /* Skip the instrumentation of this file, if invoked by accident */ - +#ifndef WMOPS #ifdef WMOPS /*-------------------------------------------------------------------* * Complexity counting tool *--------------------------------------------------------------------*/ -#define MAX_FUNCTION_NAME_LENGTH 200 /* Maximum length of the function name */ -#define MAX_PARAMS_LENGTH 200 /* Maximum length of the function parameter string */ -#define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> might be increased during runtime, if needed */ +#define MAX_FUNCTION_NAME_LENGTH 50 /* Maximum length of the function name */ +#define MAX_PARAMS_LENGTH 50 /* Maximum length of the function parameter string */ +#define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> mightb be increased during runtime, if needed */ #define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of records, increase the number of records by this number */ #define MAX_CALL_TREE_DEPTH 100 /* maximum depth of the function call tree */ #define DOUBLE_MAX 0x80000000 @@ -126,7 +125,7 @@ void reset_wmops( void ) exit( -1 ); } - /* initilize the list of WMOPS records */ + /* initilize the list of wmops records */ /* initilize the BASOP WMOPS counters */ for ( i = 0; i < max_num_wmops_records; i++ ) { @@ -189,84 +188,35 @@ void reset_wmops( void ) return; } -void push_wmops_fct( const char *label, ... ) + +void push_wmops( const char *label ) { int new_flag; - int i, j, index_record; - unsigned int *ptr; - va_list arg; - char func_name[MAX_FUNCTION_NAME_LENGTH] = ""; - - /* concatenate all function name labels into a single string */ - va_start( arg, label ); - while ( label ) - { - strcat( func_name, label ); - label = va_arg( arg, const char * ); - } - va_end( arg ); + int i, j; /* Check, if this is a new function label */ new_flag = 1; for ( i = 0; i < num_wmops_records; i++ ) { - if ( strcmp( wmops[i].label, func_name ) == 0 ) + if ( strcmp( wmops[i].label, label ) == 0 ) { new_flag = 0; break; } } - index_record = i; /* Create a new record in the list */ if ( new_flag ) { if ( num_wmops_records >= max_num_wmops_records ) { - /* There is no room for a new WMOPS record -> reallocate the list */ + /* There is no room for a new wmops record -> reallocate the list */ max_num_wmops_records += MAX_NUM_RECORDS_REALLOC_STEP; wmops = realloc( wmops, max_num_wmops_records * sizeof( wmops_record ) ); multiCounter = realloc( multiCounter, max_num_wmops_records * sizeof( BASIC_OP ) ); - - /* initilize newly created WMOPS records */ - for ( i = num_wmops_records; i < max_num_wmops_records; i++ ) - { - strcpy( &wmops[i].label[0], "\0" ); - wmops[i].call_number = 0; - wmops[i].update_cnt = 0; - for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) - { - wmops[i].call_tree[j] = -1; - } - wmops[i].start_selfcnt = 0.0; - wmops[i].current_selfcnt = 0.0; - wmops[i].max_selfcnt = 0.0; - wmops[i].min_selfcnt = DOUBLE_MAX; - wmops[i].tot_selfcnt = 0.0; - wmops[i].start_cnt = 0.0; - wmops[i].current_cnt = 0.0; - wmops[i].max_cnt = 0.0; - wmops[i].min_cnt = DOUBLE_MAX; - wmops[i].tot_cnt = 0.0; -#ifdef WMOPS_WC_FRAME_ANALYSIS - wmops[i].wc_cnt = 0.0; - wmops[i].wc_selfcnt = 0.0; - wmops[i].current_call_number = 0; - wmops[i].wc_call_number = -1; -#endif - - /* initialize BASOP WMOPS counters */ - ptr = (unsigned int *) &multiCounter[i]; - for ( j = 0; j < (int) ( sizeof( BASIC_OP ) / sizeof( unsigned int ) ); j++ ) - { - *ptr++ = 0; - } - wmops[i].LastWOper = 0; - } - } - strcpy( wmops[index_record].label, func_name ); + strcpy( wmops[i].label, label ); num_wmops_records++; } @@ -288,29 +238,29 @@ void push_wmops_fct( const char *label, ... ) /* update call tree */ for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) { - if ( wmops[index_record].call_tree[j] == current_record ) + if ( wmops[i].call_tree[j] == current_record ) { break; } - else if ( wmops[index_record].call_tree[j] == -1 ) + else if ( wmops[i].call_tree[j] == -1 ) { - wmops[index_record].call_tree[j] = current_record; + wmops[i].call_tree[j] = current_record; break; } } } /* update the current context info */ - current_record = index_record; - wmops[index_record].start_selfcnt = ops_cnt; - wmops[index_record].start_cnt = ops_cnt; - wmops[index_record].call_number++; + current_record = i; + wmops[current_record].start_selfcnt = ops_cnt; + wmops[current_record].start_cnt = ops_cnt; + wmops[current_record].call_number++; #ifdef WMOPS_WC_FRAME_ANALYSIS - wmops[index_record].current_call_number++; + wmops[current_record].current_call_number++; #endif /* set the ID of BASOP functions counters */ - Set_BASOP_WMOPS_counter( index_record ); + Set_BASOP_WMOPS_counter( current_record ); return; } @@ -1147,7 +1097,7 @@ void *mem_alloc( #ifdef MEM_COUNT_DETAILS /* Export heap memory allocation record to the .csv file */ - fprintf( fid_csv_filename, "A,%ld,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); + fprintf( fid_csv_filename, "A,%d,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); #endif if ( ptr_record->frame_allocated != -1 ) @@ -1445,8 +1395,8 @@ allocator_record *get_mem_record( unsigned long *hash, const char *func_name, in /*-------------------------------------------------------------------* * mem_free() * - * This function de-allocates memory blocks and frees physical memory with free(). - * It also updates the actual and average usage of memory blocks. + * This function de-allocatesd the memory block and frees the mphysical memory with free(). + * It also updates actual and average usage of the memory block. * * Note: The record is not removed from the list and may be reused later on in mem_alloc()! *--------------------------------------------------------------------*/ @@ -1487,7 +1437,7 @@ void mem_free( const char *func_name, int func_lineno, void *ptr ) #ifdef MEM_COUNT_DETAILS /* Export heap memory de-allocation record to the .csv file */ - fprintf( fid_csv_filename, "D,%ld,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); + fprintf( fid_csv_filename, "D,%d,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); #endif /* De-Allocate Memory Block */ @@ -1747,7 +1697,7 @@ static void mem_count_summary( void ) allocator_record *ptr_record, *ptr; /* Prepare format string */ - sprintf( format_str, "%%-%d.%ds %%5.5s %%6.6s %%-%d.%ds %%20.20s %%6.6s ", 50, 50, 50, 50 ); + sprintf( format_str, "%%-%ds %%5s %%6s %%-%ds %%20s %%6s ", MAX_FUNCTION_NAME_LENGTH, MAX_PARAMS_LENGTH ); if ( n_items_wc_intra_frame_heap > 0 ) { @@ -2217,5 +2167,1902 @@ void Reset_BASOP_WMOPS_counter( void ) } #endif +#else + +#ifdef WMOPS_FLT +/*-------------------------------------------------------------------* + * Complexity counting tool + *--------------------------------------------------------------------*/ + +#define MAX_RECORDS 1024 +#define MAX_CHAR 64 +#define MAX_STACK 64 +#define DOUBLE_MAX 0x80000000 + +struct wmops_record +{ + char label[MAX_CHAR]; + long call_number; + long update_cnt; + int call_tree[MAX_RECORDS]; + double start_selfcnt; + double current_selfcnt; + double max_selfcnt; + double min_selfcnt; + double tot_selfcnt; + double start_cnt; /* The following take into account the decendants */ + double current_cnt; + double max_cnt; + double min_cnt; + double tot_cnt; +#ifdef WMOPS_WC_FRAME_ANALYSIS + int32_t current_call_number; + double wc_cnt; + double wc_selfcnt; + int32_t wc_call_number; +#endif +}; + +double ops_cnt; +double prom_cnt; +double inst_cnt[NUM_INST]; + +static struct wmops_record wmops[MAX_RECORDS]; +static int stack[MAX_STACK]; +static int sptr; +static int num_records; +static int current_record; +static long update_cnt; +static double start_cnt; +static double max_cnt; +static double min_cnt; +static double inst_cnt_wc[NUM_INST]; +static long fnum_cnt_wc; + +static int *heap_allocation_call_tree = NULL, heap_allocation_call_tree_size = 0, heap_allocation_call_tree_max_size = 0; + + +void reset_wmops( void ) +{ + int i, j; + + for ( i = 0; i < MAX_RECORDS; i++ ) + { + strcpy( &wmops[i].label[0], "\0" ); + wmops[i].call_number = 0; + wmops[i].update_cnt = 0; + for ( j = 0; j < MAX_RECORDS; j++ ) + { + wmops[i].call_tree[j] = -1; + } + wmops[i].start_selfcnt = 0.0; + wmops[i].current_selfcnt = 0.0; + wmops[i].max_selfcnt = 0.0; + wmops[i].min_selfcnt = DOUBLE_MAX; + wmops[i].tot_selfcnt = 0.0; + wmops[i].start_cnt = 0.0; + wmops[i].current_cnt = 0.0; + wmops[i].max_cnt = 0.0; + wmops[i].min_cnt = DOUBLE_MAX; + wmops[i].tot_cnt = 0.0; +#ifdef WMOPS_WC_FRAME_ANALYSIS + wmops[i].wc_cnt = 0.0; + wmops[i].wc_selfcnt = 0.0; + wmops[i].current_call_number = 0; +#endif + } + + for ( i = 0; i < MAX_STACK; i++ ) + { + stack[i] = -1; + } + sptr = 0; + num_records = 0; + current_record = -1; + update_cnt = 0; + + max_cnt = 0.0; + min_cnt = DOUBLE_MAX; + start_cnt = 0.0; + ops_cnt = 0.0; +} + + +void push_wmops( const char *label ) +{ + int new_flag; + int i, j; + + /* Check if new function record label */ + new_flag = 1; + for ( i = 0; i < num_records; i++ ) + { + if ( strcmp( wmops[i].label, label ) == 0 ) + { + new_flag = 0; + break; + } + } + + /* Configure new record */ + if ( new_flag ) + { + if ( num_records >= MAX_RECORDS ) + { + fprintf( stdout, "push_wmops(): exceeded MAX_RECORDS count.\n\n" ); + exit( -1 ); + } + strcpy( wmops[i].label, label ); + num_records++; + } + + /* Push current context onto stack */ + if ( current_record >= 0 ) + { + if ( sptr >= MAX_STACK ) + { + fprintf( stdout, "\r push_wmops(): stack exceeded, try inreasing MAX_STACK\n" ); + exit( -1 ); + } + stack[sptr++] = current_record; + + /* accumulate op counts */ + wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; + + /* update call tree */ + for ( j = 0; j < MAX_RECORDS; j++ ) + { + if ( wmops[i].call_tree[j] == current_record ) + { + break; + } + else if ( wmops[i].call_tree[j] == -1 ) + { + wmops[i].call_tree[j] = current_record; + break; + } + } + } + + /* init current record */ + current_record = i; + wmops[current_record].start_selfcnt = ops_cnt; + wmops[current_record].start_cnt = ops_cnt; + wmops[current_record].call_number++; +#ifdef WMOPS_WC_FRAME_ANALYSIS + wmops[current_record].current_call_number++; +#endif + + return; +} + + +void pop_wmops( void ) +{ + + /* Check for underflow */ + if ( current_record < 0 ) + { + fprintf( stdout, "\r pop_wmops(): stack underflow, too many calls to pop_wmops()\n" ); + exit( -1 ); + } + + /* update count of current record */ + wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; + wmops[current_record].current_cnt += ops_cnt - wmops[current_record].start_cnt; + + /* Get back previous context from stack */ + if ( sptr > 0 ) + { + current_record = stack[--sptr]; + wmops[current_record].start_selfcnt = ops_cnt; + } + else + { + current_record = -1; + } + + return; +} + + +void update_wmops( void ) +{ + int i; + double current_cnt; +#ifdef WMOPS_PER_FRAME + static FILE *fid = NULL; + const char filename[] = "wmops_analysis"; + float tmpF; +#endif + + if ( sptr != 0 ) + { + fprintf( stdout, "update_wmops(): Stack must be empty!\n" ); + exit( -1 ); + } + +#ifdef WMOPS_PER_FRAME + /* Check, if the output file has already been opened */ + if ( fid == NULL ) + { + fid = fopen( filename, "wb" ); + + if ( fid == NULL ) + { + fprintf( stderr, "\nCannot open %s!\n\n", filename ); + exit( -1 ); + } + } + + /* Write current complexity to the external file */ + tmpF = (float) ( FAC * wmops[0].current_cnt ); + fwrite( &tmpF, sizeof( float ), 1, fid ); +#endif + +#ifdef WMOPS_WC_FRAME_ANALYSIS + if ( ops_cnt - start_cnt > max_cnt ) + { + for ( i = 0; i < num_records; i++ ) + { + wmops[i].wc_cnt = wmops[i].current_cnt; + wmops[i].wc_selfcnt = wmops[i].current_selfcnt; + wmops[i].wc_call_number = wmops[i].current_call_number; + } + } +#endif + + for ( i = 0; i < num_records; i++ ) + { + wmops[i].tot_selfcnt += wmops[i].current_selfcnt; + wmops[i].tot_cnt += wmops[i].current_cnt; + + if ( wmops[i].current_selfcnt > 0 ) + { + if ( wmops[i].current_selfcnt > wmops[i].max_selfcnt ) + { + wmops[i].max_selfcnt = wmops[i].current_selfcnt; + } + + if ( wmops[i].current_selfcnt < wmops[i].min_selfcnt ) + { + wmops[i].min_selfcnt = wmops[i].current_selfcnt; + } + } + + wmops[i].current_selfcnt = 0; + + if ( wmops[i].current_cnt > 0 ) + { + if ( wmops[i].current_cnt > wmops[i].max_cnt ) + { + wmops[i].max_cnt = wmops[i].current_cnt; + } + + if ( wmops[i].current_cnt < wmops[i].min_cnt ) + { + wmops[i].min_cnt = wmops[i].current_cnt; + } + + wmops[i].update_cnt++; + } + + wmops[i].current_cnt = 0; +#ifdef WMOPS_WC_FRAME_ANALYSIS + wmops[i].current_call_number = 0; +#endif + } + + current_cnt = ops_cnt - start_cnt; + if ( current_cnt > max_cnt ) + { + max_cnt = current_cnt; + + for ( i = 0; i < NUM_INST; i++ ) + { + inst_cnt_wc[i] = inst_cnt[i]; + } + + fnum_cnt_wc = update_cnt + 1; + } + + if ( current_cnt < min_cnt ) + { + min_cnt = current_cnt; + } + + for ( i = 0; i < NUM_INST; i++ ) + { + inst_cnt[i] = 0.0; + } + + start_cnt = ops_cnt; + + /* increment frame counter */ + update_cnt++; + + return; +} + + +void print_wmops( void ) +{ + int i; + + char *sfmts = "%20s %8s %8s %7s %7s\n"; + char *dfmts = "%20s %8.2f %8.3f %7.3f %7.3f\n"; + char *sfmt = "%20s %8s %8s %7s %7s %7s %7s %7s\n"; + char *dfmt = "%20s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; + +#ifdef WMOPS_WC_FRAME_ANALYSIS + int j, label_len, max_label_len; + char *sfmtt = "%20s %4s %15s\n"; + char *dfmtt = "%20s %4d "; +#endif + + fprintf( stdout, "\n\n --- Complexity analysis [WMOPS] --- \n\n" ); + + fprintf( stdout, "%54s %23s\n", "|------ SELF ------|", "|--- CUMULATIVE ---|" ); + fprintf( stdout, sfmt, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " ); + fprintf( stdout, sfmt, "---------------", "------", "------", "------", "------", "------", "------", "------" ); + + for ( i = 0; i < num_records; i++ ) + { + fprintf( stdout, dfmt, wmops[i].label, update_cnt == 0 ? 0 : (float) wmops[i].call_number / update_cnt, + wmops[i].min_selfcnt == DOUBLE_MAX ? 0 : FAC * wmops[i].min_selfcnt, + FAC * wmops[i].max_selfcnt, + wmops[i].update_cnt == 0 ? 0 : FAC * wmops[i].tot_selfcnt / wmops[i].update_cnt, + wmops[i].min_cnt == DOUBLE_MAX ? 0 : FAC * wmops[i].min_cnt, + FAC * wmops[i].max_cnt, + wmops[i].update_cnt == 0 ? 0 : FAC * wmops[i].tot_cnt / wmops[i].update_cnt ); + } + + fprintf( stdout, sfmts, "---------------", "------", "------", "------", "------" ); + fprintf( stdout, dfmts, "total", (float) update_cnt, update_cnt == 0 ? 0 : FAC * min_cnt, FAC * max_cnt, update_cnt == 0 ? 0 : FAC * ops_cnt / update_cnt ); + fprintf( stdout, "\n" ); + +#ifdef WMOPS_WC_FRAME_ANALYSIS + /* calculate maximum label length for compact prinout */ + max_label_len = 0; + for ( i = 0; i < num_records; i++ ) + { + label_len = strlen( wmops[i].label ); + if ( label_len > max_label_len ) + { + max_label_len = label_len; + } + } + max_label_len += 4; + + fprintf( stdout, "\nComplexity analysis for the worst-case frame %ld:\n", fnum_cnt_wc ); + fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" ); + fprintf( stdout, "%*s %8s %10s %10s\n", max_label_len, "---------------", "------", "------", "----------" ); + + for ( i = 0; i < num_records; i++ ) + { + fprintf( stdout, "%*s %8d %10.3f %12.3f\n", max_label_len, wmops[i].label, wmops[i].wc_call_number, FAC * wmops[i].wc_selfcnt, FAC * wmops[i].wc_cnt ); + } + + fprintf( stdout, "\nCall Tree:\n\n" ); + fprintf( stdout, sfmtt, " function", "num", "called by: " ); + fprintf( stdout, sfmtt, "---------------", "---", "--------------" ); + + for ( i = 0; i < num_records; i++ ) + { + fprintf( stdout, dfmtt, wmops[i].label, i ); + for ( j = 0; wmops[i].call_tree[j] != -1; j++ ) + { + if ( j != 0 ) + { + fprintf( stdout, ", " ); + } + fprintf( stdout, "%d", wmops[i].call_tree[j] ); + } + fprintf( stdout, "\n" ); + } + + fprintf( stdout, sfmtt, "---------------", "---", "--------------" ); + fprintf( stdout, "\n\n" ); + + fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); /* added -- JPA */ + for ( i = 0; i < NUM_INST; i++ ) + { + switch ( (enum instructions) i ) + { + case _ADD: + fprintf( stdout, "\tAdds: %12.1f\n", inst_cnt_wc[i] ); + break; + case _ABS: + fprintf( stdout, "\tAbsolutes: %12.1f\n", inst_cnt_wc[i] ); + break; + case _MULT: + fprintf( stdout, "\tMultiplies: %12.1f\n", inst_cnt_wc[i] ); + break; + case _MAC: + fprintf( stdout, "\tMACs: %12.1f\n", inst_cnt_wc[i] ); + break; + case _MOVE: + fprintf( stdout, "\tMoves: %12.1f\n", inst_cnt_wc[i] ); + break; + case _STORE: + fprintf( stdout, "\tStores: %12.1f\n", inst_cnt_wc[i] ); + break; + case _LOGIC: + fprintf( stdout, "\tLogicals: %12.1f\n", inst_cnt_wc[i] ); + break; + case _SHIFT: + fprintf( stdout, "\tShifts: %12.1f\n", inst_cnt_wc[i] ); + break; + case _BRANCH: + fprintf( stdout, "\tBranches: %12.1f\n", inst_cnt_wc[i] ); + break; + case _DIV: + fprintf( stdout, "\tDivisions: %12.1f\n", inst_cnt_wc[i] ); + break; + case _SQRT: + fprintf( stdout, "\tSquare Root: %12.1f\n", inst_cnt_wc[i] ); + break; + case _TRANS: + fprintf( stdout, "\tTrans: %12.1f\n", inst_cnt_wc[i] ); + break; + case _FUNC: + fprintf( stdout, "\tFunc Call: %12.1f\n", inst_cnt_wc[i] ); + break; + case _LOOP: + fprintf( stdout, "\tLoop Init: %12.1f\n", inst_cnt_wc[i] ); + break; + case _INDIRECT: + fprintf( stdout, "\tIndirect Addr: %12.1f\n", inst_cnt_wc[i] ); + break; + case _PTR_INIT: + fprintf( stdout, "\tPointer Init: %12.1f\n", inst_cnt_wc[i] ); + break; + case _TEST: + fprintf( stdout, "\tExtra condit.: %12.1f\n", inst_cnt_wc[i] ); + break; + case _POWER: + fprintf( stdout, "\tExponential: %12.1f\n", inst_cnt_wc[i] ); + break; + case _LOG: + fprintf( stdout, "\tLogarithm: %12.1f\n", inst_cnt_wc[i] ); + break; + case _MISC: + fprintf( stdout, "\tAll other op.: %12.1f\n", inst_cnt_wc[i] ); + break; + default: + fprintf( stdout, "\tERROR: Invalid instruction type: %d\n\n", i ); + } + } +#endif + + return; +} + + +/*-------------------------------------------------------------------* + * Memory counting tool measuring RAM usage (stack and heap) + * + * Maximum RAM is measured by monitoring the total allocated memory (stack and heap) in each frame. + * + * Maximum stack is measured by monitoring the difference between the 'top' and 'bottom' of the stack. The 'bottom' of the stack is updated in each function + * with a macro 'func_start_' which is inserted automatically to all functions during the instrumentation process. + * + * Maximum heap is measured by summing the sizes of all memory blocks allocated by malloc() or calloc() and deallocated by free(). The maximum heap size is + * updated each time when the macros malloc_() or calloc_() is invoked. The macros 'malloc_ and calloc_' are inserted automatically during the instrumentation process. + * As part of heap measurements, intra-frame heap and inter-frame heap are measured separately. Intra-frame heap refers to heap memory which is allocated and deallocated + * within a single frame. Inter-frame heap, on the contrary, refers to heap memory which is reserved for more than one frame. + * + * In order to run the memory counting tool the function reset_mem(cnt_size) must be called at the beginning of the encoding/decoding process. + * The unit in which memory consumption is reported is set via the parameter 'cnt_size'. It can be set to 0 (bytes), 1 (32b words) or 2 (64b words). + * At the end of the encoding/decoding process, 'print_mem()' function may be called to print basic information about memory consumption. If the macro 'MEM_COUNT_DETAILS' + * is activated, detailed information is printed + * + * The macro 'WMOPS' needs to be activated to enable memory counting. To avoid the instrumentation of malloc()/calloc()/free() calls, use + * #define WMC_TOOL_SKIP ... #undef WMC_TOOL_SKIP macro pair around the malloc(), calloc() and free(). + *--------------------------------------------------------------------*/ + +#define MAX_RECORDABLE_CALLS 100 +#define MAX_FUNCTION_NAME_LENGTH 35 /* Maximum length that the function string will be truncated to */ +#define MAX_PARAMS_LENGTH 50 /* Maximum length that the parameter string will be truncated to */ +#define MAX_NUM_RECORDS 300 /* Initial maximum number of memory records -> mightb be increased during runtime, if needed */ +#define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of memory records, increase the number of records by this number */ + +/* This is the value (in bytes) towards which the block size is rounded. For example, a block of 123 bytes, when using + a 32 bits system, will end up taking 124 bytes since the last unused byte cannot be used for another block. */ +#ifdef MEM_ALIGN_64BITS +#define BLOCK_ROUNDING 8 /* Align on 64 Bits */ +#else +#define BLOCK_ROUNDING 4 /* Align on 32 Bits */ +#endif + +#define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) ) + +#define MAGIC_VALUE_OOB 0x12A534F0 /* Signature value which is inserted before and after each allocated memory block, used to detect out-of-bound access */ +#define MAGIC_VALUE_USED ( ~MAGIC_VALUE_OOB ) /* Value used to pre-fill allocated memory blocks, used to calculate actual memory usage */ +#define OOB_START 0x1 /* Flag indicating out-of-bounds access before memory block */ +#define OOB_END 0x2 /* Flag indicating out-of-bounds access after memory block */ + +#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) ) +#define IS_CALLOC( str ) ( str[0] == 'c' ) + +#ifdef MEM_COUNT_DETAILS +const char *csv_filename = "mem_analysis.csv"; +static FILE *fid_csv_filename = NULL; +#endif + +typedef struct +{ + char function_name[MAX_FUNCTION_NAME_LENGTH + 1]; + int16_t *stack_ptr; +} caller_info; + +caller_info stack_callers[2][MAX_RECORDABLE_CALLS]; + +typedef struct +{ + char name[MAX_FUNCTION_NAME_LENGTH + 1]; /* +1 for NUL */ + char params[1 + MAX_PARAMS_LENGTH + 1]; /* +1 for 'm'/'c' alloc & +1 for NUL */ + unsigned long hash; + int lineno; + void *block_ptr; + int block_size; + unsigned long total_block_size; /* Cumulative sum of the allocated size in the session */ + unsigned long total_used_size; /* Cumulative sum of the used size in the session */ + int wc_heap_size_intra_frame; /* Worst-Case Intra-Frame Heap Size */ + int wc_heap_size_inter_frame; /* Worst-Case Inter-Frame Heap Size */ + int frame_allocated; /* Frame number in which the Memory Block has been allocated (-1 if not allocated at the moment) */ + int OOB_Flag; + int noccurances; /* Number of times that the memory block has been allocated in a frame */ +} allocator_record; + +allocator_record *allocation_list = NULL; + +static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */ +static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */ +static int16_t *ptr_max_stack = 0; /* Pointer to the maximum stack pointer (the farest point from the bottom of stack) */ +static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case stack usage */ +static int32_t wc_ram_size, wc_ram_frame; +static int32_t current_heap_size; +static int current_calls = 0; +static char location_max_stack[256] = "undefined"; +static int Num_Records, Max_Num_Records; +static size_t Stat_Cnt_Size = USE_BYTES; +static const char *Count_Unit[] = { "bytes", "words", "words" }; + +static int *list_wc_intra_frame_heap, n_items_wc_intra_frame_heap, max_items_wc_intra_frame_heap, size_wc_intra_frame_heap, location_wc_intra_frame_heap; +static int *list_current_inter_frame_heap, n_items_current_inter_frame_heap, max_items_current_inter_frame_heap, size_current_inter_frame_heap; +static int *list_wc_inter_frame_heap, n_items_wc_inter_frame_heap, max_items_wc_inter_frame_heap, size_wc_inter_frame_heap, location_wc_inter_frame_heap; + +/* Local Functions */ +static unsigned long malloc_hash( const char *func_name, int func_lineno, char *size_str ); +allocator_record *get_mem_record( unsigned long *hash, const char *func_name, int func_lineno, char *size_str, int *index_record ); +static void *mem_alloc_block( size_t size, const char *size_str ); + +/*-------------------------------------------------------------------* + * reset_mem() + * + * Initialize/reset memory counting tool (stack and heap) + *--------------------------------------------------------------------*/ + +void reset_mem( Counting_Size cnt_size ) +{ + int16_t something; + size_t tmp_size; + + /* initialize stack pointers */ + ptr_base_stack = &something; + ptr_max_stack = ptr_base_stack; + ptr_current_stack = ptr_base_stack; + + Stat_Cnt_Size = cnt_size; + + /* Check, if sizeof(int32_t) is 4 bytes */ + tmp_size = sizeof( int32_t ); + if ( tmp_size != 4 ) + { + fprintf( stderr, "Error: Expecting 'int32_t' to be a 32 Bits Integer!" ); + exit( -1 ); + } + + /* create allocation list for malloc() memory blocks */ + if ( allocation_list == NULL ) + { + allocation_list = malloc( MAX_NUM_RECORDS * sizeof( allocator_record ) ); + } + + if ( allocation_list == NULL ) + { + fprintf( stderr, "Error: Unable to Create List of Memory Blocks!" ); + exit( -1 ); + } + + Num_Records = 0; + Max_Num_Records = MAX_NUM_RECORDS; + + wc_ram_size = 0; + wc_ram_frame = -1; + current_heap_size = 0; + + /* heap allocation tree */ + heap_allocation_call_tree_max_size = MAX_NUM_RECORDS; + if ( heap_allocation_call_tree == NULL ) + { + heap_allocation_call_tree = (int *) malloc( heap_allocation_call_tree_max_size * sizeof( int ) ); + memset( heap_allocation_call_tree, -1, heap_allocation_call_tree_max_size * sizeof( int ) ); + } + heap_allocation_call_tree_size = 0; + + /* wc intra-frame heap */ + max_items_wc_intra_frame_heap = MAX_NUM_RECORDS; + if ( list_wc_intra_frame_heap == NULL ) + { + list_wc_intra_frame_heap = (int *) malloc( max_items_wc_intra_frame_heap * sizeof( int ) ); + memset( list_wc_intra_frame_heap, -1, max_items_wc_intra_frame_heap * sizeof( int ) ); + } + n_items_wc_intra_frame_heap = 0; + size_wc_intra_frame_heap = 0; + location_wc_intra_frame_heap = -1; + + /* current inter-frame heap */ + max_items_current_inter_frame_heap = MAX_NUM_RECORDS; + if ( list_current_inter_frame_heap == NULL ) + { + list_current_inter_frame_heap = (int *) malloc( max_items_current_inter_frame_heap * sizeof( int ) ); + memset( list_current_inter_frame_heap, -1, max_items_current_inter_frame_heap * sizeof( int ) ); + } + n_items_current_inter_frame_heap = 0; + size_current_inter_frame_heap = 0; + + /* wc inter-frame heap */ + max_items_wc_inter_frame_heap = MAX_NUM_RECORDS; + if ( list_wc_inter_frame_heap == NULL ) + { + list_wc_inter_frame_heap = (int *) malloc( max_items_wc_inter_frame_heap * sizeof( int ) ); + memset( list_wc_inter_frame_heap, -1, max_items_wc_inter_frame_heap * sizeof( int ) ); + } + n_items_wc_inter_frame_heap = 0; + size_wc_inter_frame_heap = 0; + location_wc_inter_frame_heap = -1; + +#ifdef MEM_COUNT_DETAILS + /* Check, if the .csv file has already been opened */ + if ( fid_csv_filename == NULL ) + { + fid_csv_filename = fopen( csv_filename, "wb" ); + + if ( fid_csv_filename == NULL ) + { + fprintf( stderr, "\nCannot open %s!\n\n", csv_filename ); + exit( -1 ); + } + } + else + { + /* reset file */ + rewind( fid_csv_filename ); + } +#endif + + return; +} + +/*-------------------------------------------------------------------* + * reset_stack() + * + * Reset stack pointer + *--------------------------------------------------------------------*/ + +void reset_stack( void ) +{ + int16_t something; + + /* initialize/reset stack pointers */ + ptr_base_stack = &something; + ptr_max_stack = ptr_base_stack; + ptr_current_stack = ptr_base_stack; + + return; +} + +/*-------------------------------------------------------------------* + * push_stack() + * + * Check the current stack pointer and update the maximum stack pointer, if new maximum found. + *--------------------------------------------------------------------*/ + +int push_stack( const char *filename, const char *fctname ) +{ + int16_t something; + int32_t current_stack_size; + + ptr_current_stack = &something; + + (void) *filename; /* to avoid compilation warning */ + + /* Is there room to save the caller's information? */ + if ( current_calls >= MAX_RECORDABLE_CALLS ) + { /* No */ + fprintf( stderr, "No more room to store call stack info. Please increase MAX_RECORDABLE_CALLS" ); + exit( -1 ); + } + + /* Valid Function Name? */ + if ( fctname[0] == 0 ) + { /* No */ + fprintf( stderr, "Invalid function name for call stack info." ); + exit( -1 ); + } + + /* Save the Name of the Calling Function in the Table */ + strncpy( stack_callers[0][current_calls].function_name, fctname, MAX_FUNCTION_NAME_LENGTH ); + stack_callers[0][current_calls].function_name[MAX_FUNCTION_NAME_LENGTH] = 0; /* Nul Terminate */ + + /* Save the Stack Pointer */ + stack_callers[0][current_calls].stack_ptr = ptr_current_stack; + + /* Increase Stack Calling Tree Level */ + current_calls++; + + /* Is this the First Time or the Worst Case? */ + if ( ptr_current_stack < ptr_max_stack || ptr_max_stack == NULL ) + { /* Yes */ + /* Save Info about it */ + ptr_max_stack = ptr_current_stack; + + wc_stack_frame = update_cnt; /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */ + strncpy( location_max_stack, fctname, sizeof( location_max_stack ) - 1 ); + location_max_stack[sizeof( location_max_stack ) - 1] = '\0'; + + /* Save Call Tree */ + memmove( stack_callers[1], stack_callers[0], sizeof( caller_info ) * current_calls ); + + /* Terminate the List (Unless Full) */ + if ( current_calls < MAX_RECORDABLE_CALLS ) + { + stack_callers[1][current_calls].function_name[0] = 0; + } + } + + /* Check, if This is the New Worst-Case RAM (stack + heap) */ + current_stack_size = (int32_t) ( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); + + if ( current_stack_size < 0 ) + { + /* prevent negative stack size */ + current_stack_size = 0; + } + + if ( current_stack_size + current_heap_size > wc_ram_size ) + { + wc_ram_size = current_stack_size + current_heap_size; + wc_ram_frame = update_cnt; + } + + return 0 /* for Now */; +} + +/*-------------------------------------------------------------------* + * pop_stack() + * + * Remove stack caller entry from the list + *--------------------------------------------------------------------*/ + +int pop_stack( const char *filename, const char *fctname ) +{ + caller_info *caller_info_ptr; + + (void) *filename; /* to avoid compilation warning */ + + /* Decrease Stack Calling */ + current_calls--; + + /* Get Pointer to Caller Information */ + caller_info_ptr = &stack_callers[0][current_calls]; + + /* Check, if Names Match */ + if ( strncmp( caller_info_ptr->function_name, fctname, MAX_FUNCTION_NAME_LENGTH ) != 0 ) + { + fprintf( stderr, "Invalid usage of pop_stack()" ); + exit( -1 ); + } + + /* Erase Entry */ + caller_info_ptr->function_name[0] = 0; + + /* Retrieve previous stack pointer */ + if ( current_calls == 0 ) + { + ptr_current_stack = ptr_base_stack; + } + else + { + ptr_current_stack = stack_callers[0][current_calls - 1].stack_ptr; + } + + return 0 /* for Now */; +} + +#ifdef MEM_COUNT_DETAILS +/*-------------------------------------------------------------------* + * print_stack_call_tree() + * + * Print detailed information about worst-case stack usage + *--------------------------------------------------------------------*/ + +static void print_stack_call_tree( void ) +{ + caller_info *caller_info_ptr; + int call_level; + char fctname[MAX_FUNCTION_NAME_LENGTH + 1]; + + fprintf( stdout, "\nList of functions when maximum stack size is reached:\n\n" ); + + caller_info_ptr = &stack_callers[1][0]; + for ( call_level = 0; call_level < MAX_RECORDABLE_CALLS; call_level++ ) + { + /* Done? */ + if ( caller_info_ptr->function_name[0] == 0 ) + { + break; + } + + /* Print Name */ + strncpy( fctname, caller_info_ptr->function_name, MAX_FUNCTION_NAME_LENGTH ); + strcat( fctname, "()" ); + fprintf( stdout, "%-42s", fctname ); + + /* Print Stack Usage (Based on Difference) */ + if ( call_level != 0 ) + { + fprintf( stdout, "%lu %s\n", ( ( ( caller_info_ptr - 1 )->stack_ptr - caller_info_ptr->stack_ptr ) * sizeof( int16_t ) ) >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size] ); + } + else + { + fprintf( stdout, "%lu %s\n", ( ( ptr_base_stack - caller_info_ptr->stack_ptr ) * sizeof( int16_t ) ) >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size] ); + } + + /* Advance */ + caller_info_ptr++; + } + + fprintf( stdout, "\n" ); + + return; +} +#endif + + +/*-------------------------------------------------------------------* + * mem_alloc() + * + * Creates new record, stores auxiliary information about which function allocated the memory, line number, parameters, etc. + * Finally, it allocates physical memory using malloc() + * The function also updates worst-case heap size and worst-case RAM size + *--------------------------------------------------------------------*/ + +void *mem_alloc( + const char *func_name, + int func_lineno, + size_t size, + char *size_str /* the first char indicates m-alloc or c-alloc */ ) +{ + int index_record; + int32_t current_stack_size; + unsigned long hash; + allocator_record *ptr_record; + + if ( size == 0 ) + { + fprintf( stderr, "Fct=%s, Ln=%i: %s!\n", func_name, func_lineno, "Size of Zero not Supported" ); + exit( -1 ); + } + + /* Search for an existing record (that has been de-allocated before) */ + index_record = 0; + while ( ( ptr_record = get_mem_record( &hash, func_name, func_lineno, size_str, &index_record ) ) != NULL ) + { + if ( ptr_record->frame_allocated == -1 ) + { + break; + } + else + { + index_record++; + } + } + + /* Create new record */ + if ( ptr_record == NULL ) + { + if ( Num_Records >= Max_Num_Records ) + { + /* There is no room for a new record -> reallocate memory */ + Max_Num_Records += MAX_NUM_RECORDS_REALLOC_STEP; + allocation_list = realloc( allocation_list, Max_Num_Records * sizeof( allocator_record ) ); + } + + ptr_record = &( allocation_list[Num_Records] ); + + /* Initialize new record */ + ptr_record->hash = hash; + ptr_record->noccurances = 0; + ptr_record->total_block_size = 0; + ptr_record->total_used_size = 0; + ptr_record->frame_allocated = -1; + ptr_record->OOB_Flag = 0; + ptr_record->wc_heap_size_intra_frame = -1; + ptr_record->wc_heap_size_inter_frame = -1; + + index_record = Num_Records; + Num_Records++; + } + + /* Allocate memory block for the new record, add signature before the beginning and after the memory block and fill it with magic value */ + ptr_record->block_ptr = mem_alloc_block( size, size_str ); + + if ( ptr_record->block_ptr == NULL ) + { + fprintf( stderr, "Fct=%s, Ln=%i: %s!\n", func_name, func_lineno, "Error: Cannot Allocate Memory!" ); + exit( -1 ); + } + + /* Save all auxiliary information about the memory block */ + strncpy( ptr_record->name, func_name, MAX_FUNCTION_NAME_LENGTH ); + ptr_record->name[MAX_FUNCTION_NAME_LENGTH] = '\0'; + strncpy( ptr_record->params, size_str, MAX_PARAMS_LENGTH ); /* Note: The size string starts with either 'm' or 'c' to indicate 'm'alloc or 'c'alloc */ + ptr_record->params[MAX_PARAMS_LENGTH] = '\0'; + ptr_record->lineno = func_lineno; + ptr_record->block_size = size; + ptr_record->total_block_size += size; + +#ifdef MEM_COUNT_DETAILS + /* Export heap memory allocation record to the .csv file */ + fprintf( fid_csv_filename, "A,%d,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); +#endif + + if ( ptr_record->frame_allocated != -1 ) + { + fprintf( stderr, "Fct=%s, Ln=%i: %s!\n", func_name, func_lineno, "Error: Attempt to Allocate the Same Memory Block with Freeing it First!" ); + exit( -1 ); + } + + ptr_record->frame_allocated = update_cnt; /* Store the current frame number -> later it will be used to determine the total duration */ + + /* Update Heap Size in the current frame */ + current_heap_size += ptr_record->block_size; + + /* Check, if this is the new Worst-Case RAM (stack + heap) */ + current_stack_size = (int32_t) ( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); + if ( current_stack_size + current_heap_size > wc_ram_size ) + { + wc_ram_size = current_stack_size + current_heap_size; + wc_ram_frame = update_cnt; + } + + /* Add new entry to the heap allocation call tree */ + if ( heap_allocation_call_tree == NULL ) + { + fprintf( stderr, "Error: Heap allocation call tree not created!" ); + exit( -1 ); + } + + /* check, if the maximum size of the call tree has been reached -> resize if so */ + if ( heap_allocation_call_tree_size >= heap_allocation_call_tree_max_size ) + { + heap_allocation_call_tree_max_size += MAX_NUM_RECORDS_REALLOC_STEP; + heap_allocation_call_tree = (int *) realloc( heap_allocation_call_tree, heap_allocation_call_tree_max_size * sizeof( int ) ); + } + + /* push new entry (positive number means push op, neagtive number means pop op; zero index must be converted to 0.01 :-) */ + heap_allocation_call_tree[heap_allocation_call_tree_size++] = index_record; + + return ptr_record->block_ptr; +} + +/*-------------------------------------------------------------------* + * mem_alloc_block() + * + * Physical allocation of memory using malloc(). Appends 'signature' before and after the block, + * pre-fills memory block with magic value + *--------------------------------------------------------------------*/ + +static void *mem_alloc_block( size_t size, const char *size_str ) +{ + size_t rounded_size; + void *block_ptr; + char *tmp_ptr; + size_t n, f; + int32_t fill_value; + int32_t *ptr32; + int32_t mask, temp; + + /* Round Up Block Size */ + rounded_size = ROUND_BLOCK_SIZE( size ); + + /* Allocate memory using the standard malloc() by adding room for Signature Values */ + block_ptr = malloc( rounded_size + BLOCK_ROUNDING * 2 ); + + if ( block_ptr == NULL ) + { + return NULL; + } + + /* Add Signature Before the Start of the Block */ + ptr32 = (int32_t *) block_ptr; + n = N_32BITS_BLOCKS; + do + { + *ptr32++ = MAGIC_VALUE_OOB; + } while ( --n ); + + /* Fill Memory Block with Magic Value or 0 */ + fill_value = MAGIC_VALUE_USED; + if ( IS_CALLOC( size_str ) ) + { + fill_value = 0x00000000; + } + n = size / sizeof( int32_t ); + while ( n-- ) + { + *ptr32++ = fill_value; + } + + /* Fill the Reminder of the Memory Block - After Rounding */ + n = rounded_size - size; + f = n % sizeof( int32_t ); + if ( f != 0 ) + { + /* when filling with '0' need to adapt the magic value */ + /* shift by [1->24, 2->16, 3->8] */ + mask = 0xFFFFFFFF << ( ( sizeof( int32_t ) - f ) * 8 ); /* (1) */ + temp = MAGIC_VALUE_OOB & mask; + if ( fill_value != 0x0 ) + { /* for malloc merge fill value */ + temp += ( ~mask ) & MAGIC_VALUE_USED; + } /* for calloc the code in (1) above already introduces zeros */ + *ptr32++ = temp; + } + n /= sizeof( int32_t ); + n += N_32BITS_BLOCKS; + + /* Add Signature After the End of Block */ + do + { + *ptr32++ = MAGIC_VALUE_OOB; + } while ( --n ); + + /* Adjust the Memory Block Pointer (Magic Value Before and After the Memory Block Requested) */ + tmp_ptr = (char *) block_ptr; + tmp_ptr += BLOCK_ROUNDING; + block_ptr = (void *) tmp_ptr; + + return block_ptr; +} + +/*-------------------------------------------------------------------* + * mem_set_usage() + * + * Calculates actual usage of memory block by checking the magic value that was used to pre-fill + * each memory block during its allocation + *--------------------------------------------------------------------*/ + +static int mem_set_usage( allocator_record *record_ptr ) +{ + int total_bytes_used; + + size_t n; + int32_t *ptr32; + char *ptr8; + size_t total_bytes; + int32_t fill_value; + + fill_value = MAGIC_VALUE_USED; + if ( ( record_ptr->params[0] ) == 'c' ) + { + fill_value = 0x00000000; + } + + total_bytes = record_ptr->block_size; + + /* Check 4 bytes at a time */ + ptr32 = (int32_t *) record_ptr->block_ptr; + total_bytes_used = 0; + for ( n = total_bytes / sizeof( int32_t ); n > 0; n-- ) + { + if ( *ptr32++ != fill_value ) + { + total_bytes_used += sizeof( int32_t ); + } + } + + /* Check remaining bytes (If Applicable) 1 byte at a time */ + ptr8 = (char *) ptr32; + for ( n = total_bytes % sizeof( int32_t ); n > 0; n-- ) + { + if ( *ptr8++ != (char) fill_value ) + { + total_bytes_used++; + } + + /* Update Value */ + fill_value >>= 8; + } + + return total_bytes_used; +} + +/*-------------------------------------------------------------------* + * mem_check_OOB() + * + * Checks, if out-of-bounds access has occured. This is done by inspecting the 'signature' value + * taht has been added before and after the memory block during its allocation + *--------------------------------------------------------------------*/ + +static unsigned int mem_check_OOB( allocator_record *record_ptr ) +{ + int32_t *ptr32; + unsigned int OOB_Flag = 0x0; + int32_t mask; + size_t i; + int f; + + ptr32 = (int32_t *) record_ptr->block_ptr - N_32BITS_BLOCKS; + + /* Check the Signature at the Beginning of Memory Block */ + i = N_32BITS_BLOCKS; + do + { + if ( *ptr32++ ^ MAGIC_VALUE_OOB ) + { + OOB_Flag |= OOB_START; + } + } while ( --i ); + + /* Advance to End (Snap to lowest 32 Bits) */ + ptr32 += record_ptr->block_size / sizeof( int32_t ); + + /* Calculate Unused Space That has been added to get to the rounded Block Size */ + i = ROUND_BLOCK_SIZE( record_ptr->block_size ) - record_ptr->block_size; + + /* Partial Check of Signature at the End of Memory Block (for block size that has been rounded) */ + f = i % sizeof( int32_t ); + if ( f != 0 ) + { + mask = 0xFFFFFFFF << ( ( sizeof( int32_t ) - f ) * 8 ); + if ( ( *ptr32++ ^ MAGIC_VALUE_OOB ) & mask ) + { + OOB_Flag |= OOB_END; + } + } + + /* Full Check of Signature at the End of Memory Block, i.e. all 32 Bits (for the remainder after rounding) */ + i /= sizeof( int32_t ); + i += N_32BITS_BLOCKS; + do + { + if ( *ptr32++ ^ MAGIC_VALUE_OOB ) + { + OOB_Flag |= OOB_END; + } + } while ( --i ); + + return OOB_Flag; +} + +/*-------------------------------------------------------------------* + * malloc_hash() + * + * Calculate hash from function name, line number and malloc size + *--------------------------------------------------------------------*/ + +static unsigned long malloc_hash( const char *func_name, int func_lineno, char *size_str ) +{ + unsigned long hash = 5381; + const char *ptr_str; + + ptr_str = func_name; + while ( ptr_str != NULL && *ptr_str != '\0' ) + { + hash = ( ( hash << 5 ) + hash ) + *ptr_str++; /* hash * 33 + char */ + } + + hash = ( ( hash << 5 ) + hash ) + func_lineno; /* hash * 33 + func_lineno */ + + ptr_str = size_str; + while ( ptr_str != NULL && *ptr_str != '\0' ) + { + hash = ( ( hash << 5 ) + hash ) + *ptr_str++; /* hash * 33 + char */ + } + + return hash; +} + +/*-------------------------------------------------------------------* + * get_mem_record() + * + * Search for memory record in the internal list, return NULL if not found + * Start from index_record + *--------------------------------------------------------------------*/ + +allocator_record *get_mem_record( unsigned long *hash, const char *func_name, int func_lineno, char *size_str, int *index_record ) +{ + int i; + + if ( *index_record < 0 || *index_record > Num_Records ) + { + return NULL; + } + + /* calculate hash */ + *hash = malloc_hash( func_name, func_lineno, size_str ); + + for ( i = *index_record; i < Num_Records; i++ ) + { + /* check, if memory block is not allocated at the moment and the hash matches */ + if ( allocation_list[i].block_ptr == NULL && *hash == allocation_list[i].hash ) + { + *index_record = i; + return &( allocation_list[i] ); + } + } + + /* not found */ + *index_record = -1; + return NULL; +} + + +/*-------------------------------------------------------------------* + * mem_free() + * + * This function de-allocatesd the memory block and frees the mphysical memory with free(). + * It also updates actual and average usage of the memory block. + * + * Note: The record is not removed from the list and may be reused later on in mem_alloc()! + *--------------------------------------------------------------------*/ + +void mem_free( const char *func_name, int func_lineno, void *ptr ) +{ + int i, index_record; + char *tmp_ptr; + allocator_record *ptr_record; + + /* Search for the Block Pointer in the List */ + ptr_record = NULL; + index_record = -1; + for ( i = 0; i < Num_Records; i++ ) + { + if ( ptr == allocation_list[i].block_ptr ) + { /* Yes, Found it */ + ptr_record = &( allocation_list[i] ); + index_record = i; + break; + } + } + + if ( ptr_record == NULL ) + { + fprintf( stderr, "Fct=%s, Ln=%i: %s!\n", func_name, func_lineno, "Error: Unable to Find Record Corresponding to the Allocated Memory Block!" ); + exit( -1 ); + } + + /* Update the Heap Size */ + current_heap_size -= ptr_record->block_size; + + /* Calculate the Actual Usage of the Memory Block (Look for Signature) */ + ptr_record->total_used_size += mem_set_usage( ptr_record ); + + /* Check, if Out-Of-Bounds Access has been Detected */ + ptr_record->OOB_Flag = mem_check_OOB( ptr_record ); + +#ifdef MEM_COUNT_DETAILS + /* Export heap memory de-allocation record to the .csv file */ + fprintf( fid_csv_filename, "D,%d,%s,%d,%d\n", update_cnt, ptr_record->name, ptr_record->lineno, ptr_record->block_size ); +#endif + + /* De-Allocate Memory Block */ + tmp_ptr = (char *) ptr; + tmp_ptr -= BLOCK_ROUNDING; + ptr = (void *) tmp_ptr; + free( ptr ); + + /* Add new entry to the heap allocation call tree */ + if ( heap_allocation_call_tree == NULL ) + { + fprintf( stderr, "Error: Heap allocation call tree not created!" ); + exit( -1 ); + } + + /* check, if the maximum size of the call tree has been reached -> resize if so */ + if ( heap_allocation_call_tree_size >= heap_allocation_call_tree_max_size ) + { + heap_allocation_call_tree_max_size += MAX_NUM_RECORDS_REALLOC_STEP; + heap_allocation_call_tree = (int *) realloc( heap_allocation_call_tree, heap_allocation_call_tree_max_size * sizeof( int ) ); + } + + heap_allocation_call_tree[heap_allocation_call_tree_size++] = -index_record; + + /* Reset memory block pointer (this is checked when updating wc intra-frame and inter-frame memory) */ + ptr_record->block_ptr = NULL; + + return; +} + + +/*-------------------------------------------------------------------* + * update_mem() + * + * This function updates the worst-case intra-frame memory and the worst-case inter-frame memory. + *--------------------------------------------------------------------*/ + +void update_mem( void ) +{ + int i, j, flag_alloc = -1, i_record; + int size_current_intra_frame_heap; + int *list_current_intra_frame_heap = NULL, n_items_current_intra_frame_heap; + allocator_record *ptr_record; + + /* process the heap allocation call tree and prepare lists of intra-frame and inter-frame heap memory blocks for this frame */ + n_items_current_intra_frame_heap = 0; + size_current_intra_frame_heap = 0; + for ( i = 0; i < heap_allocation_call_tree_size; i++ ) + { + /* get the record */ + i_record = heap_allocation_call_tree[i]; + + if ( i_record > 0 ) + { + flag_alloc = 1; + } + else if ( i_record < 0 ) + { + flag_alloc = 0; + i_record = -i_record; + } + ptr_record = &( allocation_list[i_record] ); + + if ( ptr_record->frame_allocated == update_cnt && ptr_record->block_ptr == NULL ) + { + /* intra-frame heap memory */ + if ( list_current_intra_frame_heap == NULL ) + { + list_current_intra_frame_heap = (int *) malloc( heap_allocation_call_tree_size * sizeof( int ) ); + memset( list_current_intra_frame_heap, -1, heap_allocation_call_tree_size * sizeof( int ) ); + } + + /* zero index doesn't have sign to determine whether it's allocated or de-allocated -> we need to search the list */ + if ( i_record == 0 ) + { + flag_alloc = 1; + for ( j = 0; j < n_items_current_intra_frame_heap; j++ ) + { + if ( list_current_intra_frame_heap[j] == i_record ) + { + flag_alloc = 0; + break; + } + } + } + + if ( flag_alloc ) + { + /* add to list */ + list_current_intra_frame_heap[n_items_current_intra_frame_heap++] = i_record; + size_current_intra_frame_heap += ptr_record->block_size; + + /* no need to re-size the list -> the initially allocated size should be large enough */ + } + else + { + /* remove from list */ + for ( j = 0; j < n_items_current_intra_frame_heap; j++ ) + { + if ( list_current_intra_frame_heap[j] == i_record ) + { + break; + } + } + memmove( &list_current_intra_frame_heap[j], &list_current_intra_frame_heap[j + 1], ( n_items_current_intra_frame_heap - j ) * sizeof( int ) ); + n_items_current_intra_frame_heap--; + size_current_intra_frame_heap -= ptr_record->block_size; + + /* reset block size */ + ptr_record->frame_allocated = -1; + ptr_record->block_size = 0; + } + } + else + { + /* inter-frame heap memory */ + + /* zero index doesn't have sign to determine whether it's allocated or de-allocated -> we need to search the list */ + if ( i_record == 0 ) + { + flag_alloc = 1; + for ( j = 0; j < n_items_current_inter_frame_heap; j++ ) + { + if ( list_current_inter_frame_heap[j] == i_record ) + { + flag_alloc = 0; + break; + } + } + } + + if ( flag_alloc ) + { + /* add to list */ + if ( n_items_current_inter_frame_heap >= max_items_current_inter_frame_heap ) + { + /* resize list, if needed */ + max_items_current_inter_frame_heap = n_items_current_inter_frame_heap + MAX_NUM_RECORDS_REALLOC_STEP; + list_current_inter_frame_heap = realloc( list_current_inter_frame_heap, max_items_current_inter_frame_heap * sizeof( int ) ); + } + + list_current_inter_frame_heap[n_items_current_inter_frame_heap++] = i_record; + size_current_inter_frame_heap += ptr_record->block_size; + } + else + { + /* remove from list */ + for ( j = 0; j < n_items_current_inter_frame_heap; j++ ) + { + if ( list_current_inter_frame_heap[j] == i_record ) + { + break; + } + } + memmove( &list_current_inter_frame_heap[j], &list_current_inter_frame_heap[j + 1], ( n_items_current_inter_frame_heap - j ) * sizeof( int ) ); + n_items_current_inter_frame_heap--; + size_current_inter_frame_heap -= ptr_record->block_size; + + /* reset block size */ + ptr_record->frame_allocated = -1; + ptr_record->block_size = 0; + } + } + } + + /* check, if this is the new worst-case for intra-frame heap memory */ + if ( size_current_intra_frame_heap > size_wc_intra_frame_heap ) + { + if ( n_items_current_intra_frame_heap >= max_items_wc_intra_frame_heap ) + { + /* resize the list, if needed */ + max_items_wc_intra_frame_heap = n_items_current_intra_frame_heap + MAX_NUM_RECORDS_REALLOC_STEP; + list_wc_intra_frame_heap = realloc( list_wc_intra_frame_heap, max_items_wc_intra_frame_heap * sizeof( int ) ); + } + + /* copy current-frame list to worst-case list */ + memmove( list_wc_intra_frame_heap, list_current_intra_frame_heap, n_items_current_intra_frame_heap * sizeof( int ) ); + n_items_wc_intra_frame_heap = n_items_current_intra_frame_heap; + size_wc_intra_frame_heap = size_current_intra_frame_heap; + location_wc_intra_frame_heap = update_cnt; + + /* update the wc numbers in all individual records */ + for ( i = 0; i < n_items_wc_intra_frame_heap; i++ ) + { + i_record = list_wc_intra_frame_heap[i]; + ptr_record = &( allocation_list[i_record] ); + ptr_record->wc_heap_size_intra_frame = ptr_record->block_size; + } + } + + /* check, if this is the new worst-case for inter-frame heap memory */ + if ( size_current_inter_frame_heap > size_wc_inter_frame_heap ) + { + if ( n_items_current_inter_frame_heap >= max_items_wc_inter_frame_heap ) + { + /* resize list, if needed */ + max_items_wc_inter_frame_heap = n_items_current_inter_frame_heap + MAX_NUM_RECORDS_REALLOC_STEP; + list_wc_inter_frame_heap = realloc( list_wc_inter_frame_heap, max_items_wc_inter_frame_heap * sizeof( int ) ); + } + + /* copy current-frame list to worst-case list */ + memmove( list_wc_inter_frame_heap, list_current_inter_frame_heap, n_items_current_inter_frame_heap * sizeof( int ) ); + n_items_wc_inter_frame_heap = n_items_current_inter_frame_heap; + size_wc_inter_frame_heap = size_current_inter_frame_heap; + location_wc_inter_frame_heap = update_cnt; + + /* update the wc numbers in all individual records */ + for ( i = 0; i < n_items_wc_inter_frame_heap; i++ ) + { + i_record = list_wc_inter_frame_heap[i]; + ptr_record = &( allocation_list[i_record] ); + ptr_record->wc_heap_size_inter_frame = ptr_record->block_size; + } + } + + /* reset heap allocation call tree */ + heap_allocation_call_tree_size = 0; + + /* de-allocate list of intra-frame heap memory blocks in the current fraeme - it's needed only inside this function */ + if ( list_current_intra_frame_heap ) + { + free( list_current_intra_frame_heap ); + } + + return; +} + +#ifdef MEM_COUNT_DETAILS +/*-------------------------------------------------------------------* + * subst() + * + * Substitute character in string + *--------------------------------------------------------------------*/ + +static void subst( char *s, char from, char to ) +{ + while ( *s == from ) + { + *s++ = to; + } + + return; +} + + +/*-------------------------------------------------------------------* + * mem_count_summary() + * + * Print detailed (per-item) information about heap memory usage + *--------------------------------------------------------------------*/ + +static void mem_count_summary( void ) +{ + int i, j, index, index_record; + size_t length; + char buf[300], format_str[50], name_str[MAX_FUNCTION_NAME_LENGTH + 3], parms_str[MAX_PARAMS_LENGTH + 1], type_str[10], usage_str[20], size_str[20], line_str[10]; + allocator_record *ptr_record, *ptr; + + /* Prepare format string */ + sprintf( format_str, "%%-%ds %%5s %%6s %%-%ds %%20s %%6s ", MAX_FUNCTION_NAME_LENGTH, MAX_PARAMS_LENGTH ); + + if ( n_items_wc_intra_frame_heap > 0 ) + { + /* Intra-Frame Heap Size */ + fprintf( stdout, "\nList of memory blocks when maximum intra-frame heap size is reached:\n\n" ); + + /* Find duplicate records (same hash and worst-case heap size) */ + for ( i = 0; i < n_items_wc_intra_frame_heap; i++ ) + { + index_record = list_wc_intra_frame_heap[i]; + if ( index_record == -1 ) + { + continue; + } + + ptr_record = &( allocation_list[index_record] ); + for ( j = i + 1; j < n_items_wc_intra_frame_heap; j++ ) + { + index = list_wc_intra_frame_heap[j]; + if ( index == -1 ) + { + continue; + } + ptr = &( allocation_list[index] ); + + if ( ptr->hash == ptr_record->hash && ptr->wc_heap_size_intra_frame == ptr_record->wc_heap_size_intra_frame ) + { + ptr_record->noccurances++; + list_wc_intra_frame_heap[j] = -1; + } + } + } + + /* Print Header */ + sprintf( buf, format_str, "Function Name", "Line", "Type", "Function Parameters", "Maximum Size", "Usage" ); + puts( buf ); + length = strlen( buf ); + sprintf( buf, "%0*d\n", (int) length - 1, 0 ); + subst( buf, '0', '-' ); + puts( buf ); + + for ( i = 0; i < n_items_wc_intra_frame_heap; i++ ) + { + index_record = list_wc_intra_frame_heap[i]; + + if ( index_record != -1 ) + { + /* get the record */ + ptr_record = &( allocation_list[index_record] ); + + /* prepare information strings */ + strncpy( name_str, ptr_record->name, MAX_FUNCTION_NAME_LENGTH ); + strcat( name_str, "()" ); + name_str[MAX_FUNCTION_NAME_LENGTH] = '\0'; + strncpy( parms_str, &( ptr_record->params[2] ), MAX_PARAMS_LENGTH ); + parms_str[MAX_PARAMS_LENGTH] = '\0'; + + if ( ptr_record->params[0] == 'm' ) + { + strcpy( type_str, "malloc" ); + } + else + { + strcpy( type_str, "calloc" ); + } + + sprintf( line_str, "%d", ptr_record->lineno ); + + /* prepare average usage & memory size strings */ + sprintf( usage_str, "%d%%", (int) ( ( (float) ptr_record->total_used_size / ( ptr_record->total_block_size + 1 ) ) * 100.0f ) ); + + if ( ptr_record->noccurances > 1 ) + { + sprintf( size_str, "%dx%d %s", ptr_record->noccurances, (int) ( ptr_record->wc_heap_size_intra_frame >> Stat_Cnt_Size ), Count_Unit[Stat_Cnt_Size] ); + } + else + { + sprintf( size_str, "%d %s", (int) ( ptr_record->wc_heap_size_intra_frame >> Stat_Cnt_Size ), Count_Unit[Stat_Cnt_Size] ); + } + + sprintf( buf, format_str, name_str, line_str, type_str, parms_str, size_str, usage_str ); + puts( buf ); + } + } + + fprintf( stdout, "\n" ); + } + + if ( n_items_wc_inter_frame_heap > 0 ) + { + /* Inter-Frame Heap Size */ + fprintf( stdout, "\nList of memory blocks when maximum inter-frame heap size is reached:\n\n" ); + + /* Find duplicate records (same hash and worst-case heap size) */ + for ( i = 0; i < n_items_wc_inter_frame_heap; i++ ) + { + index_record = list_wc_inter_frame_heap[i]; + if ( index_record == -1 ) + { + continue; + } + ptr_record = &( allocation_list[index_record] ); + ptr_record->noccurances = 1; /* reset the counter as some blocks may have been both, intra-frame and inter-frame */ + for ( j = i + 1; j < n_items_wc_inter_frame_heap; j++ ) + { + index = list_wc_inter_frame_heap[j]; + if ( index == -1 ) + { + continue; + } + ptr = &( allocation_list[index] ); + + if ( ptr->hash == ptr_record->hash && ptr->wc_heap_size_inter_frame == ptr_record->wc_heap_size_inter_frame ) + { + ptr_record->noccurances++; + list_wc_inter_frame_heap[j] = -1; + } + } + } + + /* Print Header */ + sprintf( buf, format_str, "Function Name", "Line", "Type", "Function Parameters", "Memory Size", "Usage" ); + puts( buf ); + length = strlen( buf ); + sprintf( buf, "%0*d\n", (int) length - 1, 0 ); + subst( buf, '0', '-' ); + puts( buf ); + + for ( i = 0; i < n_items_wc_inter_frame_heap; i++ ) + { + index_record = list_wc_inter_frame_heap[i]; + + if ( index_record != -1 ) + { + /* get the record */ + ptr_record = &( allocation_list[index_record] ); + + /* prepare information strings */ + strncpy( name_str, ptr_record->name, MAX_FUNCTION_NAME_LENGTH ); + strcat( name_str, "()" ); + name_str[MAX_FUNCTION_NAME_LENGTH] = '\0'; + strncpy( parms_str, &( ptr_record->params[2] ), MAX_PARAMS_LENGTH ); + parms_str[MAX_PARAMS_LENGTH] = '\0'; + + if ( ptr_record->params[0] == 'm' ) + { + strcpy( type_str, "malloc" ); + } + else + { + strcpy( type_str, "calloc" ); + } + + sprintf( line_str, "%d", ptr_record->lineno ); + + /* prepare average usage & memory size strings */ + sprintf( usage_str, "%d%%", (int) ( ( (float) ptr_record->total_used_size / ( ptr_record->total_block_size + 0.1f ) ) * 100.0f + 0.5f ) ); + + if ( ptr_record->noccurances > 1 ) + { + sprintf( size_str, "%dx%d %s", ptr_record->noccurances, (int) ( ptr_record->wc_heap_size_inter_frame >> Stat_Cnt_Size ), Count_Unit[Stat_Cnt_Size] ); + } + else + { + sprintf( size_str, "%d %s", (int) ( ptr_record->wc_heap_size_inter_frame >> Stat_Cnt_Size ), Count_Unit[Stat_Cnt_Size] ); + } + + sprintf( buf, format_str, name_str, line_str, type_str, parms_str, size_str, usage_str ); + puts( buf ); + } + } + + fprintf( stdout, "\n" ); + } + + return; +} + +#endif + +/*-------------------------------------------------------------------* + * print_mem() + * + * Print information about ROM and RAM memory usage + *--------------------------------------------------------------------*/ + +void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) +{ + int i, nElem; + + fprintf( stdout, "\n\n --- Memory usage --- \n\n" ); + + if ( Const_Data_PROM_Table != NULL ) + { + nElem = 0; + while ( strcmp( Const_Data_PROM_Table[nElem].file_spec, "" ) != 0 ) + nElem++; + + for ( i = 0; i < nElem; i++ ) + { + fprintf( stdout, "Program ROM size (%s): %d instruction words\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].PROM_size ); + } + + for ( i = 0; i < nElem; i++ ) + { + if ( Const_Data_PROM_Table[i].Get_Const_Data_Size_Func == NULL ) + { + fprintf( stdout, "Error: Cannot retrieve or calculate Table ROM size of (%s)!\n", Const_Data_PROM_Table[i].file_spec ); + } + + fprintf( stdout, "Table ROM (const data) size (%s): %d %s\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].Get_Const_Data_Size_Func() >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size] ); + } + } + else + { + fprintf( stdout, "Program ROM size: not available\n" ); + fprintf( stdout, "Table ROM (const data) size: not available\n" ); + } + + if ( wc_ram_size > 0 ) + { + fprintf( stdout, "Maximum RAM (stack + heap) size: %d %s in frame %d\n", wc_ram_size >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size], wc_ram_frame ); + } + else + { + fprintf( stdout, "Maximum RAM (stack + heap) size: not available\n" ); + } + + /* check, if the stack is empty */ + if ( ptr_current_stack != ptr_base_stack ) + { + fprintf( stderr, "Warning: Stack is not empty.\n" ); + } + + if ( ptr_base_stack - ptr_max_stack > 0 ) + { + fprintf( stdout, "Maximum stack size: %lu %s in frame %d\n", ( ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) ) >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size], + wc_stack_frame ); + } + else + { + fprintf( stdout, "Maximum stack size: not available\n" ); + } + + /* last update of intra-frame memory and inter-frame memory, if needed */ + if ( heap_allocation_call_tree_size > 0 ) + { + update_mem(); + } + + /* check, if all memory blocks have been deallocated (freed) */ + for ( i = 0; i < Num_Records; i++ ) + { + if ( allocation_list[i].block_ptr != NULL ) + { + fprintf( stderr, "Fct=%s, Ln=%i: %s!\n", allocation_list[i].name, allocation_list[i].lineno, "Error: Memory Block has not been De-Allocated with free()!" ); + exit( -1 ); + } + } + + if ( n_items_wc_intra_frame_heap > 0 ) + { + fprintf( stdout, "Maximum intra-frame heap size: %d %s in frame %d\n", size_wc_intra_frame_heap >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size], location_wc_intra_frame_heap ); + } + else + { + fprintf( stdout, "Maximum intra-frame heap size: 0\n" ); + } + + if ( n_items_wc_inter_frame_heap > 0 ) + { + fprintf( stdout, "Maximum inter-frame heap size: %d %s in frame %d\n", size_wc_inter_frame_heap >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size], location_wc_inter_frame_heap ); + } + else + { + fprintf( stdout, "Maximum inter-frame heap size: 0\n" ); + } + +#ifdef MEM_COUNT_DETAILS + /* Print detailed information about worst-case stack usage */ + if ( ptr_base_stack - ptr_max_stack > 0 ) + { + print_stack_call_tree(); + } + + /* Print detailed information about worst-case heap usage */ + mem_count_summary(); +#endif + + if ( Stat_Cnt_Size > 0 ) + { + fprintf( stdout, "\nNote: 1 word = %d bits\n", 8 << Stat_Cnt_Size ); + fprintf( stdout, "This is an optimistic estimate of memory consumption assuming that each variable type is stored with sizeof(type) bits\n" ); + } + + if ( n_items_wc_intra_frame_heap > 0 ) + { + fprintf( stdout, "Intra-frame heap memory is allocated and de-allocated in the same frame\n" ); + } + + /* De-allocate list of heap memory blocks */ + if ( allocation_list != NULL ) + { + free( allocation_list ); + } + + /* De-allocate heap allocation call tree */ + if ( heap_allocation_call_tree != NULL ) + { + free( heap_allocation_call_tree ); + } + + /* De-allocate intra-frame and inter-frame heap lists */ + if ( list_wc_intra_frame_heap != NULL ) + { + free( list_wc_intra_frame_heap ); + } + + if ( list_current_inter_frame_heap != NULL ) + { + free( list_current_inter_frame_heap ); + } + + if ( list_wc_inter_frame_heap != NULL ) + { + free( list_wc_inter_frame_heap ); + } + +#ifdef MEM_COUNT_DETAILS + if ( fid_csv_filename != NULL ) + { + fclose( fid_csv_filename ); + } +#endif + + return; +} + +#endif /* WMOPS */ + +#ifndef WMOPS_FLT +int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */ +double ops_cnt; +#endif + +#endif diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h index 42110465e..b14fad947 100644 --- a/lib_debug/wmc_auto.h +++ b/lib_debug/wmc_auto.h @@ -18,7 +18,7 @@ #ifndef EXIT_FAILURE #include /* stdlib is needed for exit() */ #endif - +#include "control.h" #ifndef EOF #include /* stdio is needed for fprintf() */ #endif @@ -34,9 +34,11 @@ #endif #define FRAMES_PER_SECOND 50.0 +#define FRAMES_PER_SECOND_FX 50 #define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */ - +#ifndef WMOPS #ifdef WMOPS + enum instructions { _ADD, @@ -563,8 +565,7 @@ extern double prom_cnt; extern double inst_cnt[NUM_INST]; void reset_wmops( void ); -#define push_wmops( ... ) push_wmops_fct( __VA_ARGS__, NULL ) -void push_wmops_fct( const char *label, ... ); +void push_wmops( const char *label ); void pop_wmops( void ); void update_wmops( void ); void update_mem( void ); @@ -724,8 +725,8 @@ static int wmc_flag_ = 0; #define frexpf_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexpf ) /* the macros below are instrumented versions of user-defined macros that might be used in the source code -/* representing some well-known and recognized mathematical operations (that are not defined in math.h) */ -/* Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */ + representing some well-known and recognized mathematical operations (that are not defined in math.h) +Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */ #define min_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), min( ( a ), ( b ) ) ) #define max_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), max( ( a ), ( b ) ) ) @@ -745,8 +746,8 @@ static int wmc_flag_ = 0; #define inv_sqrt_( x ) OP_COUNT_WRAPPER1_( SQRT_( 1 ), inv_sqrt( ( x ) ) ) #define inv_sqrtf_( x ) OP_COUNT_WRAPPER1_( SQRT_( 1 ), inv_sqrtf( ( x ) ) ) #define log_base_2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log_base_2( ( x ) ) ) -#define log2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2( ( x ) ) ) -#define log2f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2f( ( x ) ) ) +#define log2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2( ( x ) ) ) +#define log2f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2f( ( x ) ) ) #define log2_f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2_f( ( x ) ) ) #define _round_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, _round( ( x ) ) ) #define round_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, round( ( x ) ) ) @@ -967,21 +968,9 @@ typedef struct ROM_Size_Lookup_Table int ( *Get_Const_Data_Size_Func )( void ); } ROM_Size_Lookup_Table; -/* The WMC tool inserts the following declaration during the innstrumentation process in the .c file where the function print_mem() is located */ -/* and modifies it to print_mem(Const_Data_PROM_Table) */ - -/* #ifdef WMOPS - * ROM_Size_Lookup_Table Const_Data_PROM_Table[] = - * { - * {"../lib_enc/rom_enc.c", 0, NULL}, - * {"../lib_com/*.c", 0, NULL}, - * {"", -1, NULL} - * }; - * #endif - */ -/*#define MEM_ALIGN_64BITS */ /* Define this when using 64 Bits values in the code (ex: double), otherwise it will align on 32 Bits */ -/*#define MEM_COUNT_DETAILS*/ +/*#define MEM_ALIGN_64BITS */ /* Define this when using 64 Bits values in the code (ex: double), otherwise it will align on 32 Bits +#define MEM_COUNT_DETAILS*/ typedef enum { @@ -1020,11 +1009,11 @@ int push_stack( const char *filename, const char *fctname ); int pop_stack( const char *filename, const char *fctname ); #ifdef WMOPS_DETAIL -#define STACK_DEPTH_FCT_CALL ( push_wmops( __func__, "[WMC_AUTO]" ), push_stack( __FILE__, __func__ ) ) /* add push_wmops() in all function calls */ -#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __func__ ) ) /* add pop_wmops() in all function returns */ +#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ " [WMC_AUTO]" ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */ +#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __FUNCTION__ ) ) /* add pop_wmops() in all function returns */ #else #define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ ) -#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __func__ ) +#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __FUNCTION__ ) #endif void reset_stack( void ); @@ -1203,246 +1192,1018 @@ void Reset_BASOP_WMOPS_counter( void ); #endif -/***************************************************************************** - * - * Function Name : FOR - * - * Purpose : - * - * The macro FOR should be used instead of the 'for' C statement. - * The complexity is independent of the number of loop iterations that are - * performed. - * - * Complexity weight : 3 (regardless of number of iterations). - * - *****************************************************************************/ -#ifndef WMOPS -#define FOR( a) for( a) - -#else -#define FOR( a) if( incrFor(), 0); else for( a) - -static __inline void incrFor( void) { - multiCounter[currCounter].For++; -} -#endif - - -/***************************************************************************** - * - * Function Name : WHILE - * - * Purpose : - * - * The macro WHILE should be used instead of the 'while' C statement. - * The complexity is proportional to the number of loop iterations that - * are performed. - * - * Complexity weight : 4 x 'number of loop iterations'. - * - *****************************************************************************/ -#ifndef WMOPS -#define WHILE( a) while( a) - -#else -#define WHILE( a) while( incrWhile(), a) - -static __inline void incrWhile( void) { - multiCounter[currCounter].While++; -} -#endif - - -/***************************************************************************** - * - * Function Name : DO - * - * Purpose : - * - * The macro DO should be used instead of the 'do' C statement. - * - * Complexity weight : 0 (complexity counted by WHILE macro). - * - *****************************************************************************/ -#ifndef WMOPS -#define DO do -#else -#define DO do +#else +#define MILLION_CYCLES 1e6 +#define WMOPS_BOOST_FAC ( 1.0f ) /* scaling factor for equalizing the difference between automatic and manual instrumentation */ +#define FAC ( FRAMES_PER_SECOND / MILLION_CYCLES * WMOPS_BOOST_FAC ) +#define NUM_INST 20 /* Total number of instruction types (in enum below) */ -#endif +#ifdef WMOPS_FLT +enum instructions +{ + _ADD, + _ABS, + _MULT, + _MAC, + _MOVE, + _STORE, + _LOGIC, + _SHIFT, + _BRANCH, + _DIV, + _SQRT, + _TRANS, + _FUNC, + _LOOP, + _INDIRECT, + _PTR_INIT, + _TEST, + _POWER, + _LOG, + _MISC +}; -/***************************************************************************** - * - * Function Name : IF - * - * Purpose : - * - * The macro IF should : - * - * - not be used when : - * - the 'if' structure does not have any 'else if' nor 'else' statement - * - and it conditions only one DSP basic operations. - * - * - be used instead of the 'if' C statement in every other case : - * - when there is an 'else' or 'else if' statement, - * - or when the 'if' conditions several DSP basic operations, - * - or when the 'if' conditions a function call. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define IF( a) if( a) +#define _ADD_C 1 +#define _ABS_C 1 +#define _MULT_C 1 +#define _MAC_C 1 +#define _MOVE_C 1 +#define _STORE_C 1 +#define _LOGIC_C 1 +#define _SHIFT_C 1 +#define _BRANCH_C 4 +#define _DIV_C 18 +#define _SQRT_C 10 +#define _TRANS_C 25 +#define _FUNC_C 2 /* need to add number of arguments */ +#define _LOOP_C 3 +#define _INDIRECT_C 2 +#define _PTR_INIT_C 1 +#define _TEST_C 2 +#define _POWER_C 25 +#define _LOG_C 25 +#define _MISC_C 1 -#else -#define IF( a) if( incrIf(), a) +#define _ADD_P 1 +#define _ABS_P 1 +#define _MULT_P 1 +#define _MAC_P 1 +#define _MOVE_P 1 +#define _STORE_P 0 +#define _LOGIC_P 1 +#define _SHIFT_P 1 +#define _BRANCH_P 2 +#define _DIV_P 2 +#define _SQRT_P 2 +#define _TRANS_P 2 +#define _FUNC_P 2 /* need to add number of arguments */ +#define _LOOP_P 1 +#define _INDIRECT_P 2 +#define _PTR_INIT_P 1 +#define _TEST_P 1 +#define _POWER_P 2 +#define _LOG_P 2 +#define _MISC_P 1 -static __inline void incrIf( void) { - /* Technical note : - * If the "IF" operator comes just after an "ELSE", its counter - * must not be incremented. - */ - if ( ( currCounter != funcId_where_last_call_to_else_occurred ) || ( TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else ) || ( call_occurred == 1 ) ) - { - multiCounter[currCounter].If++; +#define ADD( x ) \ + { \ + { \ + ops_cnt += ( _ADD_C * ( x ) ); \ + inst_cnt[_ADD] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _ADD_P * ( x ) ); \ + } \ + } \ + } \ } - - call_occurred = 0; - funcId_where_last_call_to_else_occurred = INT_MAX; -} -#endif - - -/***************************************************************************** - * - * Function Name : ELSE - * - * Purpose : - * - * The macro ELSE should be used instead of the 'else' C statement. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define ELSE else - -#else -#define ELSE else if( incrElse(), 0) ; else - -static __inline void incrElse( void) { - multiCounter[currCounter].If++; - - /* We keep track of the funcId of the last function - * which used ELSE {...} structure. - */ - funcId_where_last_call_to_else_occurred = currCounter; - - /* We keep track of the number of WMOPS of this funcId - * when the ELSE macro was called. - */ - funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation(); - - /* call_occurred is set to 0, in order to count the next IF (if necessary) - */ - call_occurred = 0; -} -#endif - - -/***************************************************************************** - * - * Function Name : SWITCH - * - * Purpose : - * - * The macro SWITCH should be used instead of the 'switch' C statement. - * - * Complexity weight : 8 - * - *****************************************************************************/ -#ifndef WMOPS -#define SWITCH( a) switch( a) - -#else -#define SWITCH( a) switch( incrSwitch(), a) - -static __inline void incrSwitch( void) { - multiCounter[currCounter].Switch++; -} -#endif - - -/***************************************************************************** - * - * Function Name : CONTINUE - * - * Purpose : - * - * The macro CONTINUE should be used instead of the 'continue' C statement. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define CONTINUE continue - -#else -#define CONTINUE if( incrContinue(), 0); else continue - -static __inline void incrContinue( void) { - multiCounter[currCounter].Continue++; -} -#endif - - -/***************************************************************************** - * - * Function Name : BREAK - * - * Purpose : - * - * The macro BREAK should be used instead of the 'break' C statement. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define BREAK break - -#else -#define BREAK if( incrBreak(), 0) break; else break - -static __inline void incrBreak( void) { - multiCounter[currCounter].Break++; -} -#endif - - -/***************************************************************************** - * - * Function Name : GOTO - * - * Purpose : - * - * The macro GOTO should be used instead of the 'goto' C statement. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define GOTO goto - -#else -#define GOTO if( incrGoto(), 0); else goto - -static __inline void incrGoto( void) { - multiCounter[currCounter].Goto++; -} -#endif - -#endif /* WMOPS_H */ +#define ABS( x ) \ + { \ + { \ + ops_cnt += ( _ABS_C * ( x ) ); \ + inst_cnt[_ABS] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _ABS_P * ( x ) ); \ + } \ + } \ + } \ + } +#define MULT( x ) \ + { \ + { \ + ops_cnt += ( _MULT_C * ( x ) ); \ + inst_cnt[_MULT] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _MULT_P * ( x ) ); \ + } \ + } \ + } \ + } +#define MAC( x ) \ + { \ + { \ + ops_cnt += ( _MAC_C * ( x ) ); \ + inst_cnt[_MAC] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _MAC_P * ( x ) ); \ + } \ + } \ + } \ + } +#define MOVE( x ) \ + { \ + { \ + ops_cnt += ( _MOVE_C * ( x ) ); \ + inst_cnt[_MOVE] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _MOVE_P * ( x ) ); \ + } \ + } \ + } \ + } +#define STORE( x ) \ + { \ + { \ + ops_cnt += ( _STORE_C * ( x ) ); \ + inst_cnt[_STORE] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _STORE_P * ( x ) ); \ + } \ + } \ + } \ + } +#define LOGIC( x ) \ + { \ + { \ + ops_cnt += ( _LOGIC_C * ( x ) ); \ + inst_cnt[_LOGIC] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _LOGIC_P * ( x ) ); \ + } \ + } \ + } \ + } +#define SHIFT( x ) \ + { \ + { \ + ops_cnt += ( _SHIFT_C * ( x ) ); \ + inst_cnt[_SHIFT] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _SHIFT_P * ( x ) ); \ + } \ + } \ + } \ + } +#define BRANCH( x ) \ + { \ + { \ + ops_cnt += ( _BRANCH_C * ( x ) ); \ + inst_cnt[_BRANCH] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _BRANCH_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DIV( x ) \ + { \ + { \ + ops_cnt += ( _DIV_C * ( x ) ); \ + inst_cnt[_DIV] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _DIV_P * ( x ) ); \ + } \ + } \ + } \ + } +#define SQRT( x ) \ + { \ + { \ + ops_cnt += ( _SQRT_C * ( x ) ); \ + inst_cnt[_SQRT] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _SQRT_P * ( x ) ); \ + } \ + } \ + } \ + } +#define TRANS( x ) \ + { \ + { \ + ops_cnt += ( _TRANS_C * ( x ) ); \ + inst_cnt[_TRANS] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _TRANS_P * ( x ) ); \ + } \ + } \ + } \ + } +#define LOOP( x ) \ + { \ + { \ + ops_cnt += ( _LOOP_C * ( x ) ); \ + inst_cnt[_LOOP] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _LOOP_P * ( x ) ); \ + } \ + } \ + } \ + } +#define INDIRECT( x ) \ + { \ + { \ + ops_cnt += ( _INDIRECT_C * ( x ) ); \ + inst_cnt[_INDIRECT] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _INDIRECT_P * ( x ) ); \ + } \ + } \ + } \ + } +#define PTR_INIT( x ) \ + { \ + { \ + ops_cnt += ( _PTR_INIT_C * ( x ) ); \ + inst_cnt[_PTR_INIT] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _PTR_INIT_P * ( x ) ); \ + } \ + } \ + } \ + } +#define TEST( x ) \ + { \ + { \ + ops_cnt += ( _TEST_C * ( x ) ); \ + inst_cnt[_TEST] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _TEST_P * ( x ) ); \ + } \ + } \ + } \ + } +#define POWER( x ) \ + { \ + { \ + ops_cnt += ( _POWER_C * ( x ) ); \ + inst_cnt[_POWER] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _POWER_P * ( x ) ); \ + } \ + } \ + } \ + } +#define LOG( x ) \ + { \ + { \ + ops_cnt += ( _LOG_C * ( x ) ); \ + inst_cnt[_LOG] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _LOG_P * ( x ) ); \ + } \ + } \ + } \ + } +#define MISC( x ) \ + { \ + { \ + ops_cnt += ( _MISC_C * ( x ) ); \ + inst_cnt[_MISC] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _MISC_P * ( x ) ); \ + } \ + } \ + } \ + } + +#define FUNC( x ) \ + { \ + { \ + ops_cnt += ( _FUNC_C + _MOVE_C * ( x ) ); \ + inst_cnt[_FUNC]++; \ + inst_cnt[_MOVE] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _FUNC_P + _MOVE_P * ( x ) ); \ + } \ + } \ + } \ + } + +#define DADD( x ) \ + { \ + { \ + ops_cnt += ( 2 * _ADD_C * ( x ) ); \ + inst_cnt[_ADD] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _ADD_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DMULT( x ) \ + { \ + { \ + ops_cnt += ( 2 * _MULT_C * ( x ) ); \ + inst_cnt[_MULT] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _MULT_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DMAC( x ) \ + { \ + { \ + ops_cnt += ( 2 * _MAC_C * ( x ) ); \ + inst_cnt[_MAC] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _MAC_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DMOVE( x ) \ + { \ + { \ + ops_cnt += ( 2 * _MOVE_C * ( x ) ); \ + inst_cnt[_MOVE] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _MOVE_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DSTORE( x ) \ + { \ + { \ + ops_cnt += ( 2 * _STORE_C * ( x ) ); \ + inst_cnt[_STORE] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _STORE_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DLOGIC( x ) \ + { \ + { \ + ops_cnt += ( 2 * _LOGIC_C * ( x ) ); \ + inst_cnt[_LOGIC] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _LOGIC_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DSHIFT( x ) \ + { \ + { \ + ops_cnt += ( 2 * _SHIFT_C * ( x ) ); \ + inst_cnt[_SHIFT] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _SHIFT_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DDIV( x ) \ + { \ + { \ + ops_cnt += ( 2 * _DIV_C * ( x ) ); \ + inst_cnt[_DIV] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _DIV_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DSQRT( x ) \ + { \ + { \ + ops_cnt += ( 2 * _SQRT_C * ( x ) ); \ + inst_cnt[_SQRT] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _SQRT_P * ( x ) ); \ + } \ + } \ + } \ + } +#define DTRANS( x ) \ + { \ + { \ + ops_cnt += ( 2 * _TRANS_C * ( x ) ); \ + inst_cnt[_TRANS] += ( x ); \ + { \ + static int pcnt; \ + if ( !pcnt ) \ + { \ + pcnt = 1; \ + prom_cnt += ( _TRANS_P * ( x ) ); \ + } \ + } \ + } \ + } + +extern double ops_cnt; +extern double prom_cnt; +extern double inst_cnt[NUM_INST]; +extern int ops_cnt_activ; + +void reset_wmops( void ); +void push_wmops( const char *label ); +void pop_wmops( void ); +void update_wmops( void ); +void update_mem( void ); +void print_wmops( void ); + +#else /* WMOPS_FL counting disabled */ +#if 0 /* -> defined in count.h instead */ +#include +#define reset_wmops() +extern int cntr_push_pop; +#define push_wmops( x ) ( cntr_push_pop++ ) +#define pop_wmops() ( cntr_push_pop-- ) +#define update_wmops() ( assert( cntr_push_pop == 0 ) ) +#define update_mem() +#define print_wmops() +#endif + +#define ADD( x ) +#define ABS( x ) +#define MULT( x ) +#define MAC( x ) +#define MOVE( x ) +#define STORE( x ) +#define LOGIC( x ) +#define SHIFT( x ) +#define BRANCH( x ) +#define DIV( x ) +#define SQRT( x ) +#define TRANS( x ) +#define FUNC( x ) +#define LOOP( x ) +#define INDIRECT( x ) +#define PTR_INIT( x ) +#define TEST( x ) +#define POWER( x ) +#define LOG( x ) +#define MISC( x ) + +#define DADD( x ) +#define DMULT( x ) +#define DMAC( x ) +#define DMOVE( x ) +#define DSTORE( x ) +#define DLOGIC( x ) +#define DSHIFT( x ) +#define DDIV( x ) +#define DSQRT( x ) +#define DTRANS( x ) + +#endif + +/* mac & msu (Non Instrumented Versions) */ +#ifndef mac +#define mac( a, b, c ) ( ( a ) + ( b ) * ( c ) ) +#endif +#ifndef mac +#define msu( a, b, c ) ( ( a ) - ( b ) * ( c ) ) +#endif + +#ifndef WMOPS_FLT +/* DESACTIVATE the Counting Mechanism */ +#define OP_COUNT_( op, n ) + +/* DESACTIVATE Operation Counter Wrappers */ +#define OP_COUNT_WRAPPER1_( op, val ) ( val ) +#define OP_COUNT_WRAPPER2_( expr ) +#define OP_COUNT_WRAPPER3_( op, expr ) expr + +/* DESACTIVATE Logical & Ternary Operators */ +#define __ +#define _ + +#else + +/* '*ops_cnt_ptr' is Used to Avoid: "warning: operation on 'ops_cnt' may be undefined" with Cygwin gcc Compiler */ +static double *ops_cnt_ptr = &ops_cnt; +#define OP_COUNT_( op, x ) ( *ops_cnt_ptr += ( op##_C * ( x ) ), inst_cnt[op] += ( x ) ) + +/******************************************************************/ +/* NOTES: */ +/* The 'wmc_flag_' flag is global to avoid declaration in every */ +/* function and 'static' to avoid clashing with other modules */ +/* that include this header file. */ +/* */ +/* The declarations of 'wmc_flag_' and 'wops_' in this header */ +/* file prevent the addition of a 'C' file to the Project. */ +/******************************************************************/ + +/* General Purpose Global Flag */ +static int wmc_flag_ = 0; + +/* Operation Counter Wrappers */ +#define OP_COUNT_WRAPPER1_( op, val ) ( op, val ) +#define OP_COUNT_WRAPPER2_( expr ) \ + if ( expr, 0 ) \ + ; \ + else +#define OP_COUNT_WRAPPER3_( op, expr ) \ + if ( op, 0 ) \ + ; \ + else \ + expr + +#endif + +/* Define all Macros without '{' & '}' (None of these should be called externally!) */ +#define ABS_( x ) OP_COUNT_( _ABS, ( x ) / WMOPS_BOOST_FAC ) +#define ADD_( x ) OP_COUNT_( _ADD, ( x ) / WMOPS_BOOST_FAC ) +#define MULT_( x ) OP_COUNT_( _MULT, ( x ) / WMOPS_BOOST_FAC ) +#define MAC_( x ) OP_COUNT_( _MAC, ( x ) / WMOPS_BOOST_FAC ) +#define MOVE_( x ) OP_COUNT_( _MOVE, ( x ) / WMOPS_BOOST_FAC ) +#define STORE_( x ) OP_COUNT_( _STORE, ( x ) / WMOPS_BOOST_FAC ) +#define LOGIC_( x ) OP_COUNT_( _LOGIC, ( x ) / WMOPS_BOOST_FAC ) +#define SHIFT_( x ) OP_COUNT_( _SHIFT, ( x ) / WMOPS_BOOST_FAC ) +#define BRANCH_( x ) OP_COUNT_( _BRANCH, ( x ) / WMOPS_BOOST_FAC ) +#define DIV_( x ) OP_COUNT_( _DIV, ( x ) / WMOPS_BOOST_FAC ) +#define SQRT_( x ) OP_COUNT_( _SQRT, ( x ) / WMOPS_BOOST_FAC ) +#define TRANS_( x ) OP_COUNT_( _TRANS, ( x ) / WMOPS_BOOST_FAC ) +#define POWER_( x ) TRANS_( x ) +#define LOG_( x ) TRANS_( x ) +#define LOOP_( x ) OP_COUNT_( _LOOP, ( x ) / WMOPS_BOOST_FAC ) +#define INDIRECT_( x ) OP_COUNT_( _INDIRECT, ( x ) / WMOPS_BOOST_FAC ) +#define PTR_INIT_( x ) OP_COUNT_( _PTR_INIT, ( x ) / WMOPS_BOOST_FAC ) +#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) / WMOPS_BOOST_FAC ), OP_COUNT_( _FUNC, 1 ) ) +#define MISC_( x ) ABS_( x ) + +/* Math Operations */ +#define abs_ OP_COUNT_WRAPPER1_( ABS_( 1 ), abs ) +#define fabs_ OP_COUNT_WRAPPER1_( ABS_( 1 ), fabs ) +#define labs_ OP_COUNT_WRAPPER1_( ABS_( 1 ), labs ) +#define floor_ OP_COUNT_WRAPPER1_( MISC_( 1 ), floor ) +#define sqrt_ OP_COUNT_WRAPPER1_( SQRT_( 1 ), sqrt ) +#define pow_ OP_COUNT_WRAPPER1_( POWER_( 1 ), pow ) +#define exp_ OP_COUNT_WRAPPER1_( POWER_( 1 ), exp ) +#define log_ OP_COUNT_WRAPPER1_( LOG_( 1 ), log ) +#define log10_ OP_COUNT_WRAPPER1_( LOG_( 1 ), log10 ) +#define cos_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), cos ) +#define sin_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), sin ) +#define tan_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), tan ) +#define acos_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), acos ) +#define asin_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), asin ) +#define atan_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), atan ) +#define atan2_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), atan2 ) +#define cosh_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), cosh ) +#define sinh_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), sinh ) +#define tanh_ OP_COUNT_WRAPPER1_( TRANS_( 1 ), tanh ) +#define fmod_ OP_COUNT_WRAPPER1_( DIV_( 1 ), fmod ) +/* these macros use any local macros already defined */ +/* min/max and their Variants */ +#define min_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), min( ( a ), ( b ) ) ) +#define max_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), max( ( a ), ( b ) ) ) +#define MIN_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), MIN( ( a ), ( b ) ) ) +#define MAX_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), MAX( ( a ), ( b ) ) ) +#define Min_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), Min( ( a ), ( b ) ) ) +#define Max_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), Max( ( a ), ( b ) ) ) +/* Square and its Variants */ +#define sqr_( x ) OP_COUNT_WRAPPER1_( MULT_( 1 ), sqr( ( x ) ) ) +#define Sqr_( x ) OP_COUNT_WRAPPER1_( MULT_( 1 ), Sqr( ( x ) ) ) +#define SQR_( x ) OP_COUNT_WRAPPER1_( MULT_( 1 ), SQR( ( x ) ) ) +#define square_( x ) OP_COUNT_WRAPPER1_( MULT_( 1 ), square( ( x ) ) ) +#define Square_( x ) OP_COUNT_WRAPPER1_( MULT_( 1 ), Square( ( x ) ) ) +#define SQUARE_( x ) OP_COUNT_WRAPPER1_( MULT_( 1 ), SQUARE( ( x ) ) ) +/* Sign and its Variants */ +#define sign_( x ) OP_COUNT_WRAPPER1_( MOVE_( 1 ), sign( ( x ) ) ) +#define Sign_( x ) OP_COUNT_WRAPPER1_( MOVE_( 1 ), Sign( ( x ) ) ) +#define SIGN_( x ) OP_COUNT_WRAPPER1_( MOVE_( 1 ), SIGN( ( x ) ) ) +/* Square Root and its Variants */ +#define sqrtf_( x ) OP_COUNT_WRAPPER1_( SQRT_( 1 ), sqrtf( ( x ) ) ) +/* Invert Square Root and its Variants */ +#define inv_sqrt_( x ) OP_COUNT_WRAPPER1_( SQRT_( 1 ), inv_sqrt( ( x ) ) ) +/* Others */ +#define log_base_2_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log_base_2( ( x ) ) ) +#define log2_f_( x ) OP_COUNT_WRAPPER1_( ( LOG_( 1 ), MULT_( 1 ) ), log2_f( ( x ) ) ) +/* The 'wmc_flag_=wmc_flag_' is Used to Avoid: "warning: left-hand operand of comma expression has no effect" + with Cygwin gcc Compiler */ +#define _round_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, _round( ( x ) ) ) +#define round_f_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, round_f( ( x ) ) ) +#define _squant_( x ) OP_COUNT_WRAPPER1_( wmc_flag_ = wmc_flag_, _squant( ( x ) ) ) +/* Set Min/Max */ +#define set_min_( a, b ) OP_COUNT_WRAPPER3_( ( ADD_( 1 ), BRANCH_( 1 ), MOVE_( 1 ) ), set_min( ( a ), ( b ) ) ) +#define set_max_( a, b ) OP_COUNT_WRAPPER3_( ( ADD_( 1 ), BRANCH_( 1 ), MOVE_( 1 ) ), set_max( ( a ), ( b ) ) ) +/* mac & msu (Instrumented Versions) */ +#define mac_( a, b, c ) OP_COUNT_WRAPPER1_( MAC_( 1 ), mac( a, b, c ) ) +#define msu_( a, b, c ) OP_COUNT_WRAPPER1_( MAC_( 1 ), msu( a, b, c ) ) + +/* Functions */ +#define func_( name, x ) OP_COUNT_WRAPPER1_( FUNC_( x ), name ) + +/* Logical Operators */ +#ifndef __ +#define __ ( BRANCH_( 1 ), 1 ) && +#endif + +/* Ternary Operators (? and :) */ +#ifndef _ +#define _ ( BRANCH_( 1 ), 0 ) ? 0: +#endif + +/* Flow Control keywords */ +#define if_ \ + OP_COUNT_WRAPPER2_( BRANCH_( 1 ) ) \ + if +#define for_ OP_COUNT_WRAPPER2_( LOOP_(1)) for +#define while_( c ) \ + while \ + OP_COUNT_WRAPPER1_( BRANCH_( 1 ), ( c ) ) /* needs extra "()" if ',' encountered */ +#define do_ \ + do \ + { +#define _while \ + BRANCH_( 1 ); \ + } \ + while + +#define goto_ \ + OP_COUNT_WRAPPER2_( BRANCH_( 1 ) ) \ + goto +#define break_ \ + OP_COUNT_WRAPPER2_( BRANCH_( 1 ) ) \ + break +#define continue_ \ + OP_COUNT_WRAPPER2_( BRANCH_( 1 ) ) \ + continue +#define return_ \ + OP_COUNT_WRAPPER2_( ( wmc_flag_ = stack_tree_level_, STACK_DEPTH_FCT_RETURN ) ) \ + return + +#define switch_ \ + OP_COUNT_WRAPPER2_( ( BRANCH_( 1 ), wmc_flag_ = 1 ) ) \ + switch +#define cost_( n ) OP_COUNT_WRAPPER2_( wmc_flag_ ? ( ADD_( n ), BRANCH_( n ), wmc_flag_ = 0 ) : 0 ); + +#ifdef WMOPS_FLT + +#define ACC 2 +#define MUL 1 + +/* Counting Function (should not be called externally!) */ +static void wops_( const char *ops ) +{ + char lm = 0; /* lm: Last Operation is Math */ + static char lo = 0; /* Last Operation */ + + void ( *fct )( const char *ops ) = wops_; + +st: + while ( *ops != '\0' ) + { + switch ( *ops++ ) + { + int cnt; + case '-': + for ( cnt = 0; ops[cnt] == '>'; cnt++ ) + ; + if ( cnt & 1 ) + goto ind; + case '+': + lm = 2; + if ( lo & MUL ) + { + MULT_( -1 ); + MAC_( 1 ); + break; + } + lo = ACC << 2; + case 'U': + case 'D': + ADD_( 1 ); + break; + case '*': + lm = 2; + if ( lo & ACC ) + { + ADD_( -1 ); + MAC_( 1 ); + break; + } + lo = MUL << 2; + MULT_( 1 ); + break; + case '/': + case '%': + lm = 2; + DIV_( 1 ); + break; + case '&': + case '|': + case '^': + lm = 2; + case '~': + LOGIC_( 1 ); + break; + case '<': + case '>': + if ( *ops != ops[-1] ) + goto error; + ops++; + case -85: + case -69: + lm = 2; + SHIFT_( 1 ); + break; + case 'L': + case 'G': + if ( *ops == 't' ) + goto comp; + case 'E': + case 'N': + if ( *ops != 'e' ) + goto error; + comp: + ops++; + ADD_( 1 ); + break; + case '!': + MISC_( 2 ); + break; + case 'M': + MOVE_( 1 ); + break; + case 'S': + STORE_( 1 ); + break; + case 'P': + PTR_INIT_( 1 ); + break; + case '[': + case ']': + goto st; + ind: + ops++; + case 'I': + case '.': + INDIRECT_( 1 ); + break; + case '=': + if ( lm ) + goto st; + case '\0': + /* This Shouldn't Happen */ + /* These are Used to Avoid: "warning: 'name' defined but not used" with Cygwin gcc Compiler */ + wmc_flag_ = wmc_flag_; + ops_cnt_ptr = ops_cnt_ptr; + fct( "" ); + error: + default: + fprintf( stderr, "\r wops: Invalid Counting Operation '%s'\n", ops - 1 ); + exit( -1 ); + } + lm >>= 1; + lo >>= 2; + } + + return; +} + +#endif + +/* All Other Operations */ +#define $( str ) OP_COUNT_WRAPPER2_( wops_( str ) ) + + +/*-------------------------------------------------------------------* + * Memory counting tool + *-------------------------------------------------------------------*/ + +/* Enhanced Const Data Size Counting (Rounding Up to the Nearest 'Integer' Size) */ +#define rsize( item ) ( ( sizeof( item ) + sizeof( int ) - 1 ) / sizeof( int ) * sizeof( int ) ) + +#ifdef _MSC_VER +/* Disable "warning C4210: nonstandard extension used : function given file scope" with Visual Studio Compiler */ +#pragma warning( disable : 4210 ) +#endif + +/* Const Data Size and PROM Size Wrapper Functions */ +#define Const_Data_Size_Func( file ) Const_Data_Size_##file( void ) +#define Get_Const_Data_Size( file, val_ptr ) \ + { \ + extern int Const_Data_Size_##file( void ); \ + *( val_ptr ) = Const_Data_Size_##file(); \ + } +#define PROM_Size_Func( file ) PROM_Size_##file( void ) +#define Get_PROM_Size( file, val_ptr ) \ + { \ + int PROM_Size_##file( void ); \ + *( val_ptr ) = PROM_Size_##file(); \ + } + +/* ROM Size Lookup Table - contains information about PROM size and Const Data Size in all source files */ +/* The print_mem() function looks for this table to print the results of Const Data usage and PROM usage */ +typedef struct ROM_Size_Lookup_Table +{ + const char file_spec[255]; + int PROM_size; + int ( *Get_Const_Data_Size_Func )( void ); +} ROM_Size_Lookup_Table; + +/* The WMC tool inserts the following declaration during the innstrumentation process in the .c file where the function print_mem() is located */ +/* and modifies it to print_mem(Const_Data_PROM_Table) */ + +/* #ifdef WMOPS + * ROM_Size_Lookup_Table Const_Data_PROM_Table[] = + * { + * {"../lib_enc/rom_enc.c", 0, NULL}, + * {"../lib_com/*.c", 0, NULL}, + * {"", -1, NULL} + * }; + * #endif + */ + +/*#define MEM_ALIGN_64BITS */ /* Define this when using 64 Bits values in the code (ex: double), otherwise it will align on 32 Bits */ + /*#define MEM_COUNT_DETAILS*/ + +typedef enum +{ + USE_BYTES = 0, + USE_16BITS = 1, + USE_32BITS = 2 +} Counting_Size; + +#if ( defined( _WIN32 ) && ( _MSC_VER <= 1800 ) && ( _MSC_VER >= 1300 ) ) +#define __func__ __FUNCTION__ +#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ < 199901L +#if ( __GNUC__ >= 2 ) +#define __func__ __FUNCTION__ +#else +#define __func__ "" +#endif +#elif defined( __GNUC__ ) +#define __func__ __extension__ __FUNCTION__ +#endif + + +#ifdef WMOPS_FLT + +void *mem_alloc( const char *func_name, int func_lineno, size_t size, char *alloc_str ); +void mem_free( const char *func_name, int func_lineno, void *ptr ); + +#define malloc_( size ) mem_alloc( __func__, __LINE__, size, "m:" #size ) +#define calloc_( n, size ) mem_alloc( __func__, __LINE__, ( n ) * ( size ), "c:" #n ", " #size ) +#define free_( ptr ) mem_free( __func__, __LINE__, ptr ) + +void reset_mem( Counting_Size cnt_size ); +void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ); + +int push_stack( const char *filename, const char *fctname ); +int pop_stack( const char *filename, const char *fctname ); + +#ifdef WMOPS_DETAIL +#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */ +#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __FUNCTION__ ) ) /* add pop_wmops() in all function returns */ +#else +#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ ) +#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __FUNCTION__ ) +#endif + +void reset_stack( void ); +#define func_start_ int stack_tree_level_ = STACK_DEPTH_FCT_CALL; + +#else +#define malloc_( n1 ) malloc( n1 ) +#define calloc_( n1, n2 ) calloc( n1, n2 ) +#define free_( ptr ) free( ptr ) +#define reset_mem( cnt_size ) +#define print_mem( Const_Data_PROM_Table ) + +#define push_stack( file, fct ) +#define pop_stack( file, fct ) +#define reset_stack() +#define func_start_ + +#endif + +#endif /* WMOPS_H */ + +#endif /* WMOPS_H */ + diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index be5d64bbd..0af6fc745 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -49,6 +49,7 @@ #include "debug.h" #endif #include "wmc_auto.h" +#include "prot_fx2.h" /*-------------------------------------------------------------------* @@ -89,8 +90,17 @@ static ivas_error ivas_dec_reconfig_split_rend( cldfb_in_flag = 1; } + Word16 q_factor = Q22; + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + FOR( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + hSplitRendWrapper->multiBinPoseData.relative_head_poses[i][0] = fixedToFloat( hSplitRendWrapper->multiBinPoseData.relative_head_poses_fx[i][0], q_factor ); + hSplitRendWrapper->multiBinPoseData.relative_head_poses[i][1] = fixedToFloat( hSplitRendWrapper->multiBinPoseData.relative_head_poses_fx[i][1], q_factor ); + hSplitRendWrapper->multiBinPoseData.relative_head_poses[i][2] = fixedToFloat( hSplitRendWrapper->multiBinPoseData.relative_head_poses_fx[i][2], q_factor ); + } + isCldfbNeeded = 0; if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || @@ -218,8 +228,17 @@ static ivas_error ivas_dec_init_split_rend( cldfb_in_flag = 1; } + Word16 i, q_factor = Q22; + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + FOR( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + st_ivas->hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses[i][0] = fixedToFloat( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses_fx[i][0], q_factor ); + st_ivas->hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses[i][1] = fixedToFloat( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses_fx[i][1], q_factor ); + st_ivas->hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses[i][2] = fixedToFloat( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses_fx[i][2], q_factor ); + } + if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) { if ( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) @@ -235,7 +254,11 @@ static ivas_error ivas_dec_init_split_rend( mixed_td_cldfb_flag = 1; } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, st_ivas->hDecoderConfig->render_framesize, mixed_td_cldfb_flag ); +#else error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize, mixed_td_cldfb_flag ); +#endif return error; } #endif diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 400fd1b52..b5e853ae4 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -283,7 +283,27 @@ static ivas_error isar_set_split_rend_setup( if ( hCombinedOrientationData != NULL ) { - isar_set_split_rend_ht_setup( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat ); + for ( int i = 0; i < 4; i++ ) + { + for ( int j = 0; j < 3; j++ ) + { + for ( int k = 0; k < 3; k++ ) + { + hCombinedOrientationData->Rmat_fx[i][j][k] = (Word32) ( hCombinedOrientationData->Rmat[i][j][k] * ONE_IN_Q30 ); + } + } + } + isar_set_split_rend_ht_setup_fx( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat_fx ); + for ( int i = 0; i < 4; i++ ) + { + for ( int j = 0; j < 3; j++ ) + { + for ( int k = 0; k < 3; k++ ) + { + hCombinedOrientationData->Rmat[i][j][k] = (float) hCombinedOrientationData->Rmat_fx[i][j][k] / ONE_IN_Q30; + } + } + } } return IVAS_ERR_OK; @@ -946,9 +966,32 @@ ivas_error IVAS_DEC_GetSamples( * Binaural split rendering setup *----------------------------------------------------------------*/ - if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL && ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + if ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - isar_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend->splitrend, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions, hIvasDec->st_ivas->hCombinedOrientationData->Rmat ); + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + { + for ( int i = 0; i < 4; i++ ) + { + for ( int j = 0; j < 3; j++ ) + { + for ( int k = 0; k < 3; k++ ) + { + hIvasDec->st_ivas->hCombinedOrientationData->Rmat_fx[i][j][k] = (Word32) ( hIvasDec->st_ivas->hCombinedOrientationData->Rmat[i][j][k] * ONE_IN_Q30 ); + } + } + } + isar_set_split_rend_ht_setup_fx( &hIvasDec->st_ivas->hSplitBinRend->splitrend, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions, hIvasDec->st_ivas->hCombinedOrientationData->Rmat_fx ); + for ( int i = 0; i < 4; i++ ) + { + for ( int j = 0; j < 3; j++ ) + { + for ( int k = 0; k < 3; k++ ) + { + hIvasDec->st_ivas->hCombinedOrientationData->Rmat[i][j][k] = (float) hIvasDec->st_ivas->hCombinedOrientationData->Rmat_fx[i][j][k] / ONE_IN_Q30; + } + } + } + } } #endif @@ -1109,6 +1152,17 @@ IVAS_DEC_GetSplitBinauralBitstream( float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + for ( int i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + for ( int j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + for ( int k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + Cldfb_RealBuffer_Binaural[i][j][k] = 0; + Cldfb_ImagBuffer_Binaural[i][j][k] = 0; + } + } + } int16_t numSamplesPerChannelToDecode; int16_t i, j; ivas_error error; @@ -1129,12 +1183,45 @@ IVAS_DEC_GetSplitBinauralBitstream( *needNewFrame = false; hSplitBinRend = st_ivas->hSplitBinRend; - + for ( i = 0; i < 4; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + for ( int k = 0; k < 3; k++ ) + { + st_ivas->hCombinedOrientationData->Rmat_fx[i][j][k] = (Word32) ( st_ivas->hCombinedOrientationData->Rmat[i][j][k] * ONE_IN_Q30 ); + } + } + } if ( ( error = isar_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) { return error; } - + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + set_f( hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[i][j], 0, CLDFB_NO_CHANNELS_MAX ); + set_f( hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[i][j], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + Word16 q_factor = Q22; + FOR( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses[i][0] = fixedToFloat( hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses_fx[i][0], q_factor ); + hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses[i][1] = fixedToFloat( hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses_fx[i][1], q_factor ); + hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses[i][2] = fixedToFloat( hSplitBinRend->splitrend.multiBinPoseData.relative_head_poses_fx[i][2], q_factor ); + } + for ( i = 0; i < 4; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + for ( int k = 0; k < 3; k++ ) + { + st_ivas->hCombinedOrientationData->Rmat[i][j][k] = (float) st_ivas->hCombinedOrientationData->Rmat_fx[i][j][k] / ONE_IN_Q30; + } + } + } numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS && @@ -1237,6 +1324,71 @@ IVAS_DEC_GetSplitBinauralBitstream( Quaternion.y = 0.0f; Quaternion.z = 0.0f; } + Word16 q, q1 = 31, q2 = 31, Q_buff; + Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 *pOutput_fx[CLDFB_NO_COL_MAX]; + Word32 output_fx[CLDFB_NO_COL_MAX][L_FRAME48k]; + Word16 Q_out[CLDFB_NO_COL_MAX]; + Q_out[0] = 31; + Word16 num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + pOutput_fx[i] = &( output_fx[i][0] ); + } + for ( i = 0; i < 16; i++ ) + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + q = Q_factor_arrL( Cldfb_RealBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX ); + q1 = s_min( q1, q ); + q = Q_factor_arrL( Cldfb_ImagBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX ); + q2 = s_min( q2, q ); + } + } + Q_buff = s_min( q1, q2 ); + for ( i = 0; i < 16; i++ ) + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + floatToFixed_arrL( Cldfb_RealBuffer_Binaural[i][j], Cldfb_RealBuffer_Binaural_fx[i][j], Q_buff, CLDFB_NO_CHANNELS_MAX ); + floatToFixed_arrL( Cldfb_ImagBuffer_Binaural[i][j], Cldfb_ImagBuffer_Binaural_fx[i][j], Q_buff, CLDFB_NO_CHANNELS_MAX ); + } + } + IF( EQ_16( !td_input, 0 ) ) + { + /*TD input*/ + /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ + /* local float2fix, to be removed */ + num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + if ( hSplitBinRend->splitrend.hLc3plusEnc != NULL ) + { + Word16 frame_size_lc3 = (Word16) ( ( hSplitBinRend->splitrend.hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND ) + hSplitBinRend->splitrend.lc3plusDelaySamples ); + + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + Q_out[0] = s_min( Q_out[0], Q_factor_arrL( hSplitBinRend->splitrend.lc3plusDelayBuffers[i], frame_size_lc3 ) ); + } + } + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + Q_out[0] = s_min( Q_out[0], Q_factor_arrL( output[i], L_FRAME48k ) ); + } + // printf("%d\n", Q_sig); + if ( hSplitBinRend->splitrend.hLc3plusEnc != NULL ) + { + Word16 frame_size_lc3 = (Word16) ( ( hSplitBinRend->splitrend.hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND ) + hSplitBinRend->splitrend.lc3plusDelaySamples ); + + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + floatToFixed_arrL( hSplitBinRend->splitrend.lc3plusDelayBuffers[i], hSplitBinRend->splitrend.lc3plusDelayBuffers_fx[i], Q_out[0], frame_size_lc3 ); + } + } + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + floatToFixed_arrL( output[i], pOutput_fx[i], Q_out[0], L_FRAME48k ); + } + } if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend, Quaternion, st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, @@ -1246,14 +1398,46 @@ IVAS_DEC_GetSplitBinauralBitstream( #endif st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, splitRendBits, - Cldfb_RealBuffer_Binaural, - Cldfb_ImagBuffer_Binaural, - max_band, pOutput, 1, !td_input, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) + Cldfb_RealBuffer_Binaural_fx, + Cldfb_ImagBuffer_Binaural_fx, + max_band, pOutput, pOutput_fx, 1, !td_input, pcm_out_flag, ro_md_flag, Q_buff, &Q_out[0] ) ) != IVAS_ERR_OK ) { return error; } + IF( EQ_16( !td_input, 0 ) ) + { + if ( hSplitBinRend->splitrend.hLc3plusEnc != NULL ) + { + Word16 frame_size_lc3 = (Word16) ( ( hSplitBinRend->splitrend.hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND ) + hSplitBinRend->splitrend.lc3plusDelaySamples ); + +#ifdef DUMP_LC3_DELAY_OUT + FILE *fp = fopen( "ref_lc3delay.txt", "ab" ); +#endif + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + fixedToFloat_arrL( hSplitBinRend->splitrend.lc3plusDelayBuffers_fx[i], hSplitBinRend->splitrend.lc3plusDelayBuffers[i], Q_out[0], frame_size_lc3 ); +#ifdef DUMP_LC3_DELAY_OUT + for ( Word16 j = 0; j < frame_size_lc3; j++ ) + { + fprintf( fp, "%f\n", hSplitBin->lc3plusDelayBuffers[i][j] ); + } +#endif + } +#ifdef DUMP_LC3_DELAY_OUT + fclose( fp ); +#endif + } + } + IF( NE_16( pcm_out_flag, 0 ) && NE_16( !td_input, 0 ) ) + { + FOR( Word16 ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + fixedToFloat_arrL( pOutput_fx[ch], output[ch], Q_out[ch], hSplitBinRend->splitrend.hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX ); + fixedToFloat_arrL( hSplitBinRend->splitrend.hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBinRend->splitrend.hCldfbHandles->cldfbSyn[ch]->cldfb_state, hSplitBinRend->splitrend.hCldfbHandles->cldfbSyn[ch]->Q_split, hSplitBinRend->splitrend.hCldfbHandles->cldfbSyn[ch]->p_filter_length ); + } + } /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */ if ( pcm_out_flag ) { @@ -1778,6 +1962,10 @@ ivas_error IVAS_DEC_FeedHeadTrackData( { return error; } + hHeadTrackData->Quaternions[subframe_idx].w_fx = floatToFixed( hHeadTrackData->Quaternions[subframe_idx].w, Q22 ); + hHeadTrackData->Quaternions[subframe_idx].x_fx = floatToFixed( hHeadTrackData->Quaternions[subframe_idx].x, Q22 ); + hHeadTrackData->Quaternions[subframe_idx].y_fx = floatToFixed( hHeadTrackData->Quaternions[subframe_idx].y, Q22 ); + hHeadTrackData->Quaternions[subframe_idx].z_fx = floatToFixed( hHeadTrackData->Quaternions[subframe_idx].z, Q22 ); hHeadTrackData->Pos[subframe_idx].x = Pos.x; hHeadTrackData->Pos[subframe_idx].y = Pos.y; @@ -2076,8 +2264,6 @@ static ivas_error copyRendererConfigStruct( mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); #ifdef SPLIT_REND_WITH_HEAD_ROT - /* TODO: This seems wrong. Why set default instead of copying from hRCin? - * Currently seems to work because we only ever copy from a default-initialized handle anyway */ hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; hRCout->split_rend_config.dof = 3; hRCout->split_rend_config.hq_mode = 0; diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 62ea6dceb..be81be7e4 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -2049,37 +2049,6 @@ static ivas_error sanitizeBandwidth( if ( hEncoderConfig->ivas_format == MONO_FORMAT ) { -#if 0 // IVAS_fmToDo: temporary disabled to keep EVS bit-exactness -> to be verified - if ( max_bwidth_tmp == FB && hEncoderConfig->ivas_total_brate < ACELP_16k40 ) - { - if ( hEncoderConfig->ivas_total_brate < ACELP_9k60 ) - { - max_bwidth_tmp = WB; - } - else - { - max_bwidth_tmp = SWB; - } - } - - if ( max_bwidth_tmp == SWB && hEncoderConfig->ivas_total_brate < ACELP_9k60 ) - { - max_bwidth_tmp = WB; - } - - /* in case of 8kHz input sampling or "-max_band NB", require the total bitrate to be below 24.40 kbps */ - if ( ( max_bwidth_tmp == NB || hEncoderConfig->input_Fs == 8000 ) && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) - { - if ( hEncoderConfig->input_Fs >= 16000 ) - { - max_bwidth_tmp = WB; - } - else - { - return IVAS_ERR_INVALID_BITRATE; - } - } -#endif } else { diff --git a/lib_isar/isar_MSPred.c b/lib_isar/isar_MSPred.c index 76debae57..4dea48a9b 100644 --- a/lib_isar/isar_MSPred.c +++ b/lib_isar/isar_MSPred.c @@ -33,11 +33,13 @@ #include "options.h" #include #ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_rom_tables.h" #include "isar_lcld_prot.h" #include "isar_prot.h" #include "wmc_auto.h" - - +#include "basop_util.h" +#include "enh64.h" +#include /*-------------------------------------------------------------------* * Function _round() * @@ -57,6 +59,21 @@ static int32_t _round( * *-------------------------------------------------------------------*/ +Word32 quantPhase_fx( + Word32 phase, + Word16 exp ) // i:31? +{ + Word32 phaseQ; + + // phaseQ = _round(phase * PHASE_QUANT_FACTOR); + phaseQ = L_shr_r( Mpy_32_32( phase, PHASE_QUANT_FACTOR_FX_Q29 ), 29 - exp ); // Q60 + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } + return phaseQ; +} + int32_t quantPhase( float phase ) { @@ -72,16 +89,28 @@ int32_t quantPhase( /*-------------------------------------------------------------------* - * Function cplxmult_lcld() + * Function cplxmult() * * *-------------------------------------------------------------------*/ +void cplxmult_fx( + Word32 *pr1, + Word32 *pi1, + Word32 r2, + Word32 i2 ) +{ + Word32 r1 = *pr1, i1 = *pi1; + + *pr1 = L_sub( Mpy_32_32( r1, r2 ), Mpy_32_32( i1, i2 ) ); + *pi1 = L_add( Mpy_32_32( r1, i2 ), Mpy_32_32( i1, r2 ) ); -void cplxmult_lcld( + return; +} +void cplxmult( float *pr1, float *pi1, - const float r2, - const float i2 ) + float r2, + float i2 ) { float r1 = *pr1, i1 = *pi1; @@ -90,32 +119,31 @@ void cplxmult_lcld( return; } - - /*-------------------------------------------------------------------* * Function requantPhase() * * *-------------------------------------------------------------------*/ -int32_t requantPhase( - int32_t phaseQ ) +Word32 requantPhase( + Word32 phaseQ ) { - if ( phaseQ >= PHASE_MAX_VAL ) + IF( GE_32( phaseQ, PHASE_MAX_VAL ) ) { - phaseQ += PHASE_MAX_VAL; - phaseQ %= ( 2 * PHASE_MAX_VAL ); - phaseQ -= PHASE_MAX_VAL; + phaseQ = L_add( phaseQ, PHASE_MAX_VAL ); + phaseQ %= ( L_shl( PHASE_MAX_VAL, 1 ) ); + phaseQ = L_sub( phaseQ, PHASE_MAX_VAL ); } - else if ( phaseQ < PHASE_MIN_VAL ) + ELSE IF( LT_32( phaseQ, PHASE_MIN_VAL ) ) { - phaseQ -= PHASE_MAX_VAL; - phaseQ %= ( 2 * PHASE_MAX_VAL ); - phaseQ += PHASE_MAX_VAL; - if ( phaseQ == PHASE_MAX_VAL ) + phaseQ = L_sub( phaseQ, PHASE_MAX_VAL ); + phaseQ %= ( L_shl( PHASE_MAX_VAL, 1 ) ); + phaseQ = L_add( phaseQ, PHASE_MAX_VAL ); + IF( EQ_32( phaseQ, PHASE_MAX_VAL ) ) { phaseQ = PHASE_MIN_VAL; + move32(); } } @@ -129,6 +157,17 @@ int32_t requantPhase( * *-------------------------------------------------------------------*/ +Word32 quantPred_fx( + const Word32 pred, + Word16 exp ) // i:Q31 +{ + // int32_t predQ = _round(pred * PRED_QUANT_FACTOR); + Word32 predQ = W_round32_s( W_shl( W_mult_32_32( pred, (Word32) PRED_QUANT_FACTOR ), exp ) ); + predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ; + predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ; + + return predQ; +} int32_t quantPred( const float pred ) { @@ -158,7 +197,22 @@ float dequantPhase( * * *-------------------------------------------------------------------*/ - +Word32 dequantPred_fx( Word32 predQ ) +{ + if ( predQ == 12 ) + { + return MAX_32; + } + Word16 tmp_e; + Word32 tmp, value; + if ( predQ == 0 ) + { + return predQ; + } + tmp = BASOP_Util_Divide3216_Scale( predQ, PRED_QUANT_FACTOR_FX, &tmp_e ); + value = L_shl( tmp, sub( 31, negate( add( 1, tmp_e ) ) ) ); // Q31 + return value; +} float dequantPred( int32_t predQ ) { return (float) predQ / PRED_QUANT_FACTOR; @@ -171,24 +225,28 @@ float dequantPred( int32_t predQ ) * *-------------------------------------------------------------------*/ -int32_t PrepEncode( - int32_t *piQuant, - const int32_t *piMSFlags, - const int32_t numBands ) +Word32 PrepEncode( + Word32 *piQuant, + const Word32 *piMSFlags, + const Word32 numBands ) { - int32_t b, numMSBands = 0; + Word32 b, numMSBands; + numMSBands = 0; + move32(); - for ( b = 0; b < numBands; b++ ) + FOR( b = 0; b < numBands; b++ ) { - if ( piMSFlags[b] ) + IF( piMSFlags[b] ) { piQuant[numMSBands++] = piQuant[b]; + move32(); } } - for ( b = numMSBands; b < numBands; b++ ) + FOR( b = numMSBands; b < numBands; b++ ) { piQuant[b] = 0; + move32(); } return numMSBands; @@ -202,36 +260,42 @@ int32_t PrepEncode( *-------------------------------------------------------------------*/ void EncodePhase( - int32_t *phaseQuant, - const int32_t numMSBands, - const int32_t diffDim ) + Word32 *phaseQuant, + const Word32 numMSBands, + const Word32 diffDim ) { - int32_t b; + Word32 b; - if ( diffDim > 0 ) + IF( GT_32( diffDim, 0 ) ) { - int32_t tmp1, tmp2; + Word32 tmp1, tmp2; tmp1 = phaseQuant[0]; - for ( b = 1; b < numMSBands; b++ ) + move32(); + FOR( b = 1; b < numMSBands; b++ ) { tmp2 = phaseQuant[b]; - phaseQuant[b] -= tmp1; + move32(); + phaseQuant[b] = L_sub( phaseQuant[b], tmp1 ); tmp1 = tmp2; + move32(); } } - if ( diffDim > 1 ) + IF( GT_32( diffDim, 1 ) ) { - int32_t tmp1, tmp2; + Word32 tmp1, tmp2; tmp1 = phaseQuant[1]; - for ( b = 2; b < numMSBands; b++ ) + move32(); + FOR( b = 2; b < numMSBands; b++ ) { tmp2 = phaseQuant[b]; - phaseQuant[b] -= tmp1; + move32(); + phaseQuant[b] = L_sub( phaseQuant[b], tmp1 ); tmp1 = tmp2; + move32(); } } - for ( b = 1; b < numMSBands; b++ ) + FOR( b = 1; b < numMSBands; b++ ) { phaseQuant[b] = requantPhase( phaseQuant[b] ); } @@ -247,31 +311,34 @@ void EncodePhase( *-------------------------------------------------------------------*/ void DecodePhase( - int32_t *phaseQuant, - const int32_t numMSBands, - const int32_t diffDim ) + Word32 *phaseQuant, + const Word32 numMSBands, + const Word32 diffDim ) { - int32_t b; + Word32 b; - if ( diffDim > 1 ) + IF( GT_32( diffDim, 1 ) ) { - for ( b = 2; b < numMSBands; b++ ) + FOR( b = 2; b < numMSBands; b++ ) { - phaseQuant[b] += phaseQuant[b - 1]; + phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] ); + move32(); } } - if ( diffDim > 0 ) + IF( GT_32( diffDim, 0 ) ) { - for ( b = 1; b < numMSBands; b++ ) + FOR( b = 1; b < numMSBands; b++ ) { - phaseQuant[b] += phaseQuant[b - 1]; + phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] ); + move32(); } } - for ( b = 1; b < numMSBands; b++ ) + FOR( b = 1; b < numMSBands; b++ ) { phaseQuant[b] = requantPhase( phaseQuant[b] ); + move32(); } return; @@ -284,18 +351,21 @@ void DecodePhase( * *-------------------------------------------------------------------*/ -int32_t EncodePredCoef( - int32_t *predQuant, - const int32_t numMSBands ) +Word32 EncodePredCoef( + Word32 *predQuant, + const Word32 numMSBands ) { - int32_t b, tmp1, tmp2; + Word32 b, tmp1, tmp2; tmp1 = predQuant[0]; - for ( b = 1; b < numMSBands; b++ ) + move32(); + FOR( b = 1; b < numMSBands; b++ ) { tmp2 = predQuant[b]; - predQuant[b] -= tmp1; + move32(); + predQuant[b] = L_sub( predQuant[b], tmp1 ); tmp1 = tmp2; + move32(); } return numMSBands; @@ -309,14 +379,14 @@ int32_t EncodePredCoef( *-------------------------------------------------------------------*/ void DecodePredCoef( - int32_t *phaseQuant, - const int32_t numMSBands ) + Word32 *phaseQuant, + const Word32 numMSBands ) { - int32_t b; + Word32 b; - for ( b = 1; b < numMSBands; b++ ) + FOR( b = 1; b < numMSBands; b++ ) { - phaseQuant[b] += phaseQuant[b - 1]; + phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] ); } return; @@ -329,52 +399,58 @@ void DecodePredCoef( * *-------------------------------------------------------------------*/ -int32_t CountMSBits( - int32_t iNumBands, - const int32_t iMSMode, - const int32_t *piMSFlags, - const int32_t *piLRPhaseDiff, - const int32_t *piMSPredCoef ) +Word32 CountMSBits( + Word32 iNumBands, + const Word32 iMSMode, + const Word32 *piMSFlags, + const Word32 *piLRPhaseDiff, + const Word32 *piMSPredCoef ) { - int32_t iBitsWritten = 0; - int32_t b; - int32_t anyNonZero; - int32_t iNumMSBands = 0; - int32_t piPhaseCopy[MAX_BANDS_48]; - int32_t piPredCopy[MAX_BANDS_48]; - - for ( b = 0; b < MAX_BANDS_48; b++ ) + Word32 iBitsWritten = 0; + move32(); + Word32 b; + Word32 anyNonZero; + Word32 iNumMSBands = 0; + move32(); + Word32 piPhaseCopy[MAX_BANDS_48]; + Word32 piPredCopy[MAX_BANDS_48]; + + FOR( b = 0; b < MAX_BANDS_48; b++ ) { piPhaseCopy[b] = 0; + move32(); piPredCopy[b] = 0; + move32(); } - iBitsWritten += 2; /* iMSMode */ - for ( b = 0; b < iNumBands; b++ ) + iBitsWritten = L_add( iBitsWritten, 2 ); /* iMSMode */ + FOR( b = 0; b < iNumBands; b++ ) { - iNumMSBands += ( piMSFlags[b] != 0 ); + iNumMSBands = L_add( iNumMSBands, NE_32( piMSFlags[b], 0 ) ); } - if ( iNumMSBands == 0 ) + IF( EQ_32( iNumMSBands, 0 ) ) { return iBitsWritten; } - if ( iNumMSBands < iNumBands ) + IF( LT_32( iNumMSBands, iNumBands ) ) { - iBitsWritten += iNumBands; /* piMSFlags */ + iBitsWritten = L_add( iBitsWritten, iNumBands ); /* piMSFlags */ } - if ( iMSMode < 3 ) + IF( LT_32( iMSMode, 3 ) ) { return iBitsWritten; } /* prepare arrays for coding evaluation */ - for ( b = 0; b < iNumBands; b++ ) + FOR( b = 0; b < iNumBands; b++ ) { piPhaseCopy[b] = piLRPhaseDiff[b]; + move32(); piPredCopy[b] = piMSPredCoef[b]; + move32(); } /* Differential Coding of Phase Data*/ @@ -383,44 +459,48 @@ int32_t CountMSBits( EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM ); EncodePredCoef( piPredCopy, iNumMSBands ); - iBitsWritten += 1; /* iMSPredAll */ - anyNonZero = 0; /* phase */ - for ( b = 0; b < iNumMSBands; b++ ) + iBitsWritten = L_add( iBitsWritten, 1 ); /* iMSPredAll */ + anyNonZero = 0; /* phase */ + move32(); + FOR( b = 0; b < iNumMSBands; b++ ) { - if ( piPhaseCopy[b] != 0 ) + IF( NE_32( piPhaseCopy[b], 0 ) ) { anyNonZero = 1; - break; + move32(); + BREAK; } } - iBitsWritten++; /*anyNonZero Phase*/ - if ( anyNonZero ) + iBitsWritten = L_add( iBitsWritten, 1 ); /*anyNonZero Phase*/ + IF( anyNonZero ) { - iBitsWritten += PHASE_BAND0_BITS; - for ( b = 1; b < iNumMSBands; b++ ) + iBitsWritten = L_add( iBitsWritten, PHASE_BAND0_BITS ); + FOR( b = 1; b < iNumMSBands; b++ ) { - int32_t tabIdx = piPhaseCopy[b] - ENV_DELTA_MIN; - iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + Word32 tabIdx = L_sub( piPhaseCopy[b], ENV_DELTA_MIN ); + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] ); } } anyNonZero = 0; /* prediction */ - for ( b = 0; b < iNumMSBands; b++ ) + move32(); + FOR( b = 0; b < iNumMSBands; b++ ) { - if ( piPredCopy[b] != 0 ) + IF( NE_32( piPredCopy[b], 0 ) ) { anyNonZero = 1; + move32(); break; } } - iBitsWritten++; /* any nonZero Pred */ - if ( anyNonZero ) + iBitsWritten = L_add( iBitsWritten, 1 ); /* any nonZero Pred */ + IF( anyNonZero ) { - iBitsWritten += PRED_BAND0_BITS; - for ( b = 1; b < iNumMSBands; b++ ) + iBitsWritten = L_add( iBitsWritten, PRED_BAND0_BITS ); + FOR( b = 1; b < iNumMSBands; b++ ) { - int32_t tabIdx = piPredCopy[b] - ENV_DELTA_MIN; - iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + Word32 tabIdx = L_sub( piPredCopy[b], ENV_DELTA_MIN ); + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] ); } } diff --git a/lib_isar/isar_NoiseGen.c b/lib_isar/isar_NoiseGen.c index f7dd512b6..a61f26fc2 100644 --- a/lib_isar/isar_NoiseGen.c +++ b/lib_isar/isar_NoiseGen.c @@ -54,4 +54,5 @@ void DeleteNoiseGen( NoiseGen *psNoiseGen ) } extern float GetNoise( NoiseGen *psNoiseGen ); +extern Word32 GetNoise_fx( NoiseGen *psNoiseGen ); #endif diff --git a/lib_isar/isar_PerceptualModel.c b/lib_isar/isar_PerceptualModel.c index 1a88a2943..85864ae0d 100644 --- a/lib_isar/isar_PerceptualModel.c +++ b/lib_isar/isar_PerceptualModel.c @@ -35,7 +35,7 @@ #ifdef SPLIT_REND_WITH_HEAD_ROT #include "isar_lcld_prot.h" #include "prot.h" -#include "isar_rom_lcld_tables.h" +#include "isar_lcld_rom_tables.h" #include #include "wmc_auto.h" @@ -43,13 +43,46 @@ /*------------------------------------------------------------------------------------------* * Local constants *------------------------------------------------------------------------------------------*/ - +#define PERCEPTUAL_MODEL_SCALE_SHIFT ( 6 ) #define PERCEPTUAL_MODEL_SCALE ( 64 ) +#define PERCEPTUAL_MODEL_SCALE_SHIFT ( 6 ) #define PERCEPTUAL_MODEL_ALPHA_SCALE ( 614 ) #define PERCEPTUAL_MODEL_ALPHA_INV_SCALE ( 6827 ) #define PERCEPTUAL_MODEL_ALPHA_SHIFT ( 11 ) +/*------------------------------------------------------------------------------------------* + * Function LogAdd() + * + * + *------------------------------------------------------------------------------------------*/ + +static inline Word16 LogAdd_fx( + const Word16 iVal1, + const Word16 iVal2 ) +{ + Word16 iRetVal; + IF( iVal1 > iVal2 ) + { + iRetVal = sub( iVal1, iVal2 ); + move16(); + iRetVal = ( iRetVal < sub( LOG_ADD_TABLE_LENGTH, 1 ) ) ? iRetVal : sub( LOG_ADD_TABLE_LENGTH, 1 ); + move16(); + iRetVal = add( iVal1, c_aiLogAddTable_fx[iRetVal] ); + move16(); + } + ELSE + { + iRetVal = sub( iVal2, iVal1 ); + move16(); + iRetVal = ( iRetVal < sub( LOG_ADD_TABLE_LENGTH, 1 ) ) ? iRetVal : sub( LOG_ADD_TABLE_LENGTH, 1 ); + move16(); + iRetVal = add( iVal2, c_aiLogAddTable_fx[iRetVal] ); + move16(); + } + + return iRetVal; +} /*------------------------------------------------------------------------------------------* * Function LogAdd() * @@ -77,8 +110,68 @@ static inline int32_t LogAdd( return iRetVal; } +/*------------------------------------------------------------------------------------------* + * Function PerceptualModel() + * + * + *------------------------------------------------------------------------------------------*/ + +void PerceptualModel_fx( + const Word32 iMaxQuantBands, + const Word32 *piRMSEnvelope, + Word32 *piExcitation, + Word32 *piSMR ) +{ + Word16 n; + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 iSLOffset; + piExcitation[n] = shl( add( extract_l( piRMSEnvelope[n] ), c_aiBandwidthAdjust48_fx[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ); // shift instead of multiplying by PERCEPTUAL_MODEL_SCALE + move16(); + /* Calculate sensation level offset */ + iSLOffset = (Word16) extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) ); + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + move16(); + /* Offset envelope by sensation level offset */ + piExcitation[n] = sub( extract_l( piExcitation[n] ), iSLOffset ); + move16(); + /* Convert to loudness domain (x^0.3) */ + piExcitation[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + } + /* Spread excitation function */ + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 k; + const Word16 *piSpread; + + piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48]; + move16(); + piSMR[n] = add( extract_l( piExcitation[n] ), piSpread[n] ); + move16(); + FOR( k = 0; k < iMaxQuantBands; k++ ) + { + IF( NE_16( k, n ) ) + { + piSMR[n] = L_deposit_l( LogAdd_fx( extract_l( piSMR[n] ), add( extract_l( piExcitation[k] ), piSpread[k] ) ) ); + move16(); + } + } + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + piSMR[n] = shl( sub( add( extract_l( piRMSEnvelope[n] ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR[n] ) ), PERCEPTUAL_MODEL_SCALE_SHIFT ); + move16(); + } + + return; +} /*------------------------------------------------------------------------------------------* * Function PerceptualModel() * @@ -101,6 +194,7 @@ void PerceptualModel( /* Calculate sensation level offset */ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; /* Offset envelope by sensation level offset */ piExcitation[n] -= iSLOffset; @@ -134,8 +228,6 @@ void PerceptualModel( return; } - - /*------------------------------------------------------------------------------------------* * Function PerceptualModelStereo() * @@ -165,6 +257,7 @@ void PerceptualModelStereo( /* Calculate sensation level offset */ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation0[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; /* Offset envelope by sensation level offset */ piExcitation0[n] -= iSLOffset; @@ -201,6 +294,7 @@ void PerceptualModelStereo( /* Calculate sensation level offset */ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation1[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; /* Offset envelope by sensation level offset */ piExcitation1[n] -= iSLOffset; @@ -249,4 +343,127 @@ void PerceptualModelStereo( return; } +void PerceptualModelStereo_fx( + const Word32 iMaxQuantBands, + const Word32 *piMSFlags, + const Word32 *piRMSEnvelope0, + const Word32 *piRMSEnvelope1, + Word32 *piExcitation0, + Word32 *piExcitation1, + Word32 *piSMR0, + Word32 *piSMR1 ) +{ + Word16 n; + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 iMaxRMSEnv; + Word16 iSLOffset; + + iMaxRMSEnv = extract_l( piRMSEnvelope0[n] ); + move16(); + piExcitation0[n] = add( shl( iMaxRMSEnv, PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ); /* piRMSEnvelope0[n] */ + move16(); + /* Calculate sensation level offset */ + iSLOffset = extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation0[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) ); + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + move16(); + /* Offset envelope by sensation level offset */ + piExcitation0[n] = sub( extract_l( piExcitation0[n] ), iSLOffset ); + move16(); + /* Convert to loudness domain (x^0.3) */ + piExcitation0[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation0[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 k; + const Word16 *piSpread; + + piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48]; + move16(); + piSMR0[n] = add( extract_l( piExcitation0[n] ), piSpread[n] ); + move16(); + FOR( k = 0; k < iMaxQuantBands; k++ ) + { + IF( NE_16( k, n ) ) + { + piSMR0[n] = L_deposit_l( LogAdd_fx( extract_l( piSMR0[n] ), add( extract_l( piExcitation0[k] ), piSpread[k] ) ) ); + move16(); + } + } + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 iMaxRMSEnv; + Word16 iSLOffset; + + iMaxRMSEnv = extract_l( piRMSEnvelope1[n] ); + move16(); + piExcitation1[n] = add( shl( iMaxRMSEnv, PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ); /* piRMSEnvelope1[n] */ + move16(); + /* Calculate sensation level offset */ + iSLOffset = extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation1[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) ); + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + move16(); + /* Offset envelope by sensation level offset */ + piExcitation1[n] = sub( extract_l( piExcitation1[n] ), iSLOffset ); + move16(); + /* Convert to loudness domain (x^0.3) */ + piExcitation1[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation1[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + } + + /* Spread excitation function */ + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 k; + const Word16 *piSpread; + + piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48]; + move16(); + piSMR1[n] = add( extract_l( piExcitation1[n] ), piSpread[n] ); + move16(); + FOR( k = 0; k < iMaxQuantBands; k++ ) + { + IF( NE_16( k, n ) ) + { + piSMR1[n] = LogAdd_fx( extract_l( piSMR1[n] ), add( extract_l( piExcitation1[k] ), piSpread[k] ) ); + move16(); + } + } + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + IF( EQ_16( extract_l( piMSFlags[n] ), 1 ) ) + { + piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n]; + move16(); + piSMR1[n] = piSMR0[n]; + move16(); + } + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR0[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR0[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + piSMR0[n] = sub( add( shl( extract_l( piRMSEnvelope0[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR0[n] ) ); + move16(); + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR1[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR1[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + piSMR1[n] = sub( add( shl( extract_l( piRMSEnvelope1[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR1[n] ) ); + move16(); + } + + return; +} #endif diff --git a/lib_isar/isar_PredDecoder.c b/lib_isar/isar_PredDecoder.c index 423f45c07..3fa9ec877 100644 --- a/lib_isar/isar_PredDecoder.c +++ b/lib_isar/isar_PredDecoder.c @@ -37,8 +37,9 @@ #include "prot.h" #include "isar_prot.h" #include "isar_lcld_prot.h" -#include "isar_rom_lcld_tables.h" +#include "isar_lcld_rom_tables.h" #include "wmc_auto.h" +#include "basop_mpy.h" /*-------------------------------------------------------------------* * Function CreatePredictionDecoder() @@ -46,149 +47,159 @@ * *-------------------------------------------------------------------*/ -ivas_error CreatePredictionDecoder( +ivas_error CreatePredictionDecoder_fx( PredictionDecoder **psPredictionDecoder_out, - const int32_t iChannels, - const int32_t iNumBlocks ) + const Word32 iChannels, + const Word32 iNumBlocks ) { - int16_t n; - int16_t m; + Word16 n; + Word16 m; PredictionDecoder *psPredictionDecoder = NULL; - if ( ( psPredictionDecoder = (PredictionDecoder *) malloc( sizeof( PredictionDecoder ) ) ) == NULL ) + IF( ( psPredictionDecoder = (PredictionDecoder *) malloc( sizeof( PredictionDecoder ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } psPredictionDecoder->iChannels = iChannels; + move32(); psPredictionDecoder->iNumBlocks = iNumBlocks; + move32(); psPredictionDecoder->iNumSubSets = LCLD_BLOCKS_PER_FRAME / psPredictionDecoder->iNumBlocks; + move32(); psPredictionDecoder->iSubSetId = 0; + move32(); /* PLC_IMPROVEMENT */ - if ( ( psPredictionDecoder->ppiDecodingFailedPrev = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppiDecodingFailedPrev = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiDecodingFailed = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppiDecodingFailed = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiDecodingUnresolved = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppiDecodingUnresolved = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - for ( n = 0; n < iChannels; n++ ) + FOR( n = 0; n < iChannels; n++ ) { - int32_t k; - if ( ( psPredictionDecoder->ppiDecodingUnresolved[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + Word32 k; + IF( ( psPredictionDecoder->ppiDecodingUnresolved[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiDecodingFailed[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + IF( ( psPredictionDecoder->ppiDecodingFailed[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiDecodingFailedPrev[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + IF( ( psPredictionDecoder->ppiDecodingFailedPrev[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - for ( k = 0; k < LCLD_MAX_NUM_PRED_SUBSETS; k++ ) + FOR( k = 0; k < LCLD_MAX_NUM_PRED_SUBSETS; k++ ) { psPredictionDecoder->ppiDecodingUnresolved[n][k] = 0; + move32(); psPredictionDecoder->ppiDecodingFailed[n][k] = 0; + move32(); psPredictionDecoder->ppiDecodingFailedPrev[n][k] = 0; + move32(); } } - if ( ( psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->piPredChanEnable = (Word32 *) malloc( sizeof( Word32 ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppiPredBandEnable = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppfA1Real_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppfA1Imag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppiA1Mag = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppiA1Phase = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppfPredStateReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppfPredStateReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppfPredStateImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + IF( ( psPredictionDecoder->ppfPredStateImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) + FOR( n = 0; n < psPredictionDecoder->iChannels; n++ ) { psPredictionDecoder->piPredChanEnable[n] = 0; - if ( ( psPredictionDecoder->ppiPredBandEnable[n] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + move32(); + IF( ( psPredictionDecoder->ppiPredBandEnable[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( m = 0; m < LCLD_BANDS; m++ ) + FOR( m = 0; m < LCLD_BANDS; m++ ) { psPredictionDecoder->ppiPredBandEnable[n][m] = 0; + move32(); } - if ( ( psPredictionDecoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + IF( ( psPredictionDecoder->ppfA1Real_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + IF( ( psPredictionDecoder->ppfA1Imag_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + IF( ( psPredictionDecoder->ppiA1Mag[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + IF( ( psPredictionDecoder->ppiA1Phase[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppfPredStateReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + IF( ( psPredictionDecoder->ppfPredStateReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppfPredStateImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + IF( ( psPredictionDecoder->ppfPredStateImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) ); } - for ( m = 0; m < LCLD_BANDS; m++ ) + FOR( m = 0; m < LCLD_BANDS; m++ ) { - psPredictionDecoder->ppfPredStateReal[n][m] = 0; - psPredictionDecoder->ppfPredStateImag[n][m] = 0; + psPredictionDecoder->ppfPredStateReal_fx[n][m] = 0; + move32(); + psPredictionDecoder->ppfPredStateImag_fx[n][m] = 0; + move32(); } } /* pre-define these tables? */ - for ( n = 0; n < ( 1 << PRED_QUNAT_FILTER_MAG_BITS ); n++ ) + + FOR( n = 0; n < ( 1 << PRED_QUNAT_FILTER_MAG_BITS ); n++ ) { - const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); - psPredictionDecoder->pfMagLUT[n] = sinf( fInvMagScale * (float) n ); + psPredictionDecoder->pfMagLUT_fx[n] = c_pfMagLUT[n]; /* Q31 */ + move32(); } - for ( n = 0; n < ( 1 << PRED_QUANT_FILTER_PHASE_BITS ); n++ ) + FOR( n = 0; n < ( 1 << PRED_QUANT_FILTER_PHASE_BITS ); n++ ) { - const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); - int16_t iVal; - - iVal = n + PRED_QUANT_FILTER_PHASE_MIN; - psPredictionDecoder->pfP2RRealLUT[n] = cosf( fInvPhaseScale * (float) iVal ); - psPredictionDecoder->pfP2RImagLUT[n] = sinf( fInvPhaseScale * (float) iVal ); + psPredictionDecoder->pfP2RRealLUT_fx[n] = c_pfP2RRealLUT[n]; /* Q31 */ + move32(); + psPredictionDecoder->pfP2RImagLUT_fx[n] = c_pfP2RImagLUT[n]; /* Q31 */ + move32(); } *psPredictionDecoder_out = psPredictionDecoder; @@ -196,40 +207,38 @@ ivas_error CreatePredictionDecoder( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * Function DeletePredictionDecoder() * * *-------------------------------------------------------------------*/ -void DeletePredictionDecoder( +void DeletePredictionDecoder_fx( PredictionDecoder *psPredictionDecoder ) { - int32_t n; + Word32 n; - for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) + FOR( n = 0; n < psPredictionDecoder->iChannels; n++ ) { free( psPredictionDecoder->ppiPredBandEnable[n] ); - free( psPredictionDecoder->ppfA1Real[n] ); - free( psPredictionDecoder->ppfA1Imag[n] ); + free( psPredictionDecoder->ppfA1Real_fx[n] ); + free( psPredictionDecoder->ppfA1Imag_fx[n] ); free( psPredictionDecoder->ppiA1Mag[n] ); free( psPredictionDecoder->ppiA1Phase[n] ); - free( psPredictionDecoder->ppfPredStateReal[n] ); - free( psPredictionDecoder->ppfPredStateImag[n] ); - /* PLC_IMPROVEMENT */ + free( psPredictionDecoder->ppfPredStateReal_fx[n] ); + free( psPredictionDecoder->ppfPredStateImag_fx[n] ); free( psPredictionDecoder->ppiDecodingUnresolved[n] ); free( psPredictionDecoder->ppiDecodingFailed[n] ); free( psPredictionDecoder->ppiDecodingFailedPrev[n] ); } free( psPredictionDecoder->piPredChanEnable ); free( psPredictionDecoder->ppiPredBandEnable ); - free( psPredictionDecoder->ppfA1Real ); - free( psPredictionDecoder->ppfA1Imag ); + free( psPredictionDecoder->ppfA1Real_fx ); + free( psPredictionDecoder->ppfA1Imag_fx ); free( psPredictionDecoder->ppiA1Mag ); free( psPredictionDecoder->ppiA1Phase ); - free( psPredictionDecoder->ppfPredStateReal ); - free( psPredictionDecoder->ppfPredStateImag ); + free( psPredictionDecoder->ppfPredStateReal_fx ); + free( psPredictionDecoder->ppfPredStateImag_fx ); /* PLC_IMPROVEMENT */ free( psPredictionDecoder->ppiDecodingUnresolved ); free( psPredictionDecoder->ppiDecodingFailed ); @@ -240,95 +249,109 @@ void DeletePredictionDecoder( return; } - /*-------------------------------------------------------------------* * Function ReadPredictors() * * *-------------------------------------------------------------------*/ -int32_t ReadPredictors( +Word32 ReadPredictors_fx( PredictionDecoder *psPredictionDecoder, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int16_t iBitsRead = 0; - int32_t c; - int32_t b; - int16_t iNumPredBandBits = 6; - const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 ); - - psPredictionDecoder->iNumSubSets = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ) + 1; - iBitsRead += iSubSetBits; - - if ( psPredictionDecoder->iNumSubSets > 1 ) + Word16 iBitsRead = 0; + Word32 c; + Word32 b; + Word16 iNumPredBandBits = 6; + const Word16 iSubSetBits = ( GT_32( LCLD_MAX_NUM_PRED_SUBSETS, 4 ) ? 3 : 2 ); + move16(); + move16(); + move16(); + + psPredictionDecoder->iNumSubSets = L_add( ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ), 1 ); + iBitsRead = add( iBitsRead, iSubSetBits ); + + IF( GT_32( psPredictionDecoder->iNumSubSets, 1 ) ) { psPredictionDecoder->iSubSetId = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ); - iBitsRead += iSubSetBits; - iNumPredBandBits = ( psPredictionDecoder->iNumSubSets >= 4 ? 4 : 5 ); + iBitsRead = add( iBitsRead, iSubSetBits ); + iNumPredBandBits = ( GE_32( psPredictionDecoder->iNumSubSets, 4 ) ? 4 : 5 ); + move16(); } - else + ELSE { psPredictionDecoder->iSubSetId = 0; + move32(); } - for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + FOR( c = 0; c < psPredictionDecoder->iChannels; c++ ) { psPredictionDecoder->piPredChanEnable[c] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, psPredictionDecoder->iNumSubSets ); - iBitsRead += (int16_t) psPredictionDecoder->iNumSubSets; + move32(); + iBitsRead = add( iBitsRead, (Word16) psPredictionDecoder->iNumSubSets ); - if ( get_bit( psPredictionDecoder->piPredChanEnable[c], psPredictionDecoder->iSubSetId ) ) + IF( get_bit( psPredictionDecoder->piPredChanEnable[c], psPredictionDecoder->iSubSetId ) ) { - int32_t b0 = psPredictionDecoder->iSubSetId; - int32_t bstep = psPredictionDecoder->iNumSubSets; - int32_t iNumPredBands; + Word32 b0 = psPredictionDecoder->iSubSetId; + Word32 bstep = psPredictionDecoder->iNumSubSets; + Word32 iNumPredBands; + move32(); + move32(); - for ( b = b0; b < LCLD_BANDS; b += bstep ) + FOR( b = b0; b < LCLD_BANDS; b = L_add( b, bstep ) ) { psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + move32(); } iNumPredBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iNumPredBandBits ); - iBitsRead += iNumPredBandBits; - iNumPredBands = iNumPredBands * psPredictionDecoder->iNumSubSets + b0; + iBitsRead = add( iBitsRead, iNumPredBandBits ); + iNumPredBands = L_add( L_mult0( (Word16) iNumPredBands, (Word16) psPredictionDecoder->iNumSubSets ), b0 ); - for ( b = b0; b < iNumPredBands; b += bstep ) + FOR( b = b0; b < iNumPredBands; b = L_add( b, bstep ) ) { psPredictionDecoder->ppiPredBandEnable[c][b] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; + move32(); + iBitsRead = add( iBitsRead, 1 ); - if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + IF( EQ_32( psPredictionDecoder->ppiPredBandEnable[c][b], 1 ) ) { - int32_t iA1Mag; - int32_t iA1Phase; - float fA1Real; - float fA1Imag; + Word32 iA1Mag; + Word32 iA1Phase; + Word32 fA1Real; + Word32 fA1Imag; iA1Mag = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); - iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; + iBitsRead = add( iBitsRead, PRED_QUNAT_FILTER_MAG_BITS ); iA1Phase = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); - iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; + iBitsRead = add( iBitsRead, PRED_QUANT_FILTER_PHASE_BITS ); psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; - psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase + PRED_QUANT_FILTER_PHASE_MIN; + move32(); + psPredictionDecoder->ppiA1Phase[c][b] = L_add( iA1Phase, PRED_QUANT_FILTER_PHASE_MIN ); + move32(); - fA1Real = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RRealLUT[iA1Phase]; - fA1Imag = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RImagLUT[iA1Phase]; + fA1Real = Mpy_32_32( psPredictionDecoder->pfMagLUT_fx[iA1Mag], psPredictionDecoder->pfP2RRealLUT_fx[iA1Phase] ); /* Q31 */ + fA1Imag = Mpy_32_32( psPredictionDecoder->pfMagLUT_fx[iA1Mag], psPredictionDecoder->pfP2RImagLUT_fx[iA1Phase] ); /* Q31 */ - psPredictionDecoder->ppfA1Real[c][b] = fA1Real; - psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; + psPredictionDecoder->ppfA1Real_fx[c][b] = fA1Real; /* Q31 */ + move32(); + psPredictionDecoder->ppfA1Imag_fx[c][b] = fA1Imag; /* Q31 */ + move32(); } } } } /* disable any inactive prediction bands */ - for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + FOR( c = 0; c < psPredictionDecoder->iChannels; c++ ) { - int32_t set; - for ( set = 0; set < psPredictionDecoder->iNumSubSets; set++ ) + Word32 set; + FOR( set = 0; set < psPredictionDecoder->iNumSubSets; set++ ) { - if ( !get_bit( psPredictionDecoder->piPredChanEnable[c], set ) ) + IF( !get_bit( psPredictionDecoder->piPredChanEnable[c], set ) ) { - for ( b = set; b < LCLD_BANDS; b += psPredictionDecoder->iNumSubSets ) + FOR( b = set; b < LCLD_BANDS; b = L_add( b, psPredictionDecoder->iNumSubSets ) ) { psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + move32(); } } } @@ -336,7 +359,6 @@ int32_t ReadPredictors( return iBitsRead; } - /* PLC_IMPROVEMENT */ void SetDecodingPassed( PredictionDecoder *psPredictionDecoder ) { @@ -406,52 +428,64 @@ void UpdateDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) * *-------------------------------------------------------------------*/ -void ApplyInversePredictors( +void ApplyInversePredictors_fx( PredictionDecoder *psPredictionDecoder, - float ***pppfReal, - float ***pppfImag ) + Word32 ***pppfReal, + Word32 ***pppfImag ) { - int32_t c; - for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + Word32 c; + FOR( c = 0; c < psPredictionDecoder->iChannels; c++ ) { - if ( psPredictionDecoder->piPredChanEnable[c] > 0 ) + IF( GT_32( psPredictionDecoder->piPredChanEnable[c], 0 ) ) { - int32_t b; - for ( b = 0; b < LCLD_BANDS; b++ ) + Word32 b; + FOR( b = 0; b < LCLD_BANDS; b++ ) { - if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + IF( EQ_32( psPredictionDecoder->ppiPredBandEnable[c][b], 1 ) ) { - int32_t n; - float fA1Real; - float fA1Imag; - float fPrevReal = 0.0f; - float fPrevImag = 0.0f; - int32_t iSubset = b % psPredictionDecoder->iNumSubSets; - - if ( iSubset != psPredictionDecoder->iSubSetId ) + Word32 n; + Word32 fA1Real; + Word32 fA1Imag; + Word32 fPrevReal = 0; + move32(); + Word32 fPrevImag = 0; + move32(); + Word32 iSubset = b % psPredictionDecoder->iNumSubSets; + + IF( NE_32( iSubset, psPredictionDecoder->iSubSetId ) ) { - fPrevReal = psPredictionDecoder->ppfPredStateReal[c][b]; - fPrevImag = psPredictionDecoder->ppfPredStateImag[c][b]; + fPrevReal = psPredictionDecoder->ppfPredStateReal_fx[c][b]; + move32(); + fPrevImag = psPredictionDecoder->ppfPredStateImag_fx[c][b]; + move32(); } - fA1Real = psPredictionDecoder->ppfA1Real[c][b]; - fA1Imag = psPredictionDecoder->ppfA1Imag[c][b]; - for ( n = 0; n < psPredictionDecoder->iNumBlocks; n++ ) + fA1Real = psPredictionDecoder->ppfA1Real_fx[c][b]; + move32(); + fA1Imag = psPredictionDecoder->ppfA1Imag_fx[c][b]; + move32(); + FOR( n = 0; n < psPredictionDecoder->iNumBlocks; n++ ) { - float fReal; - float fImag; + Word32 fReal; + Word32 fImag; - fReal = pppfReal[c][n][b] - fA1Real * fPrevReal + fA1Imag * fPrevImag; - fImag = pppfImag[c][n][b] - fA1Real * fPrevImag - fA1Imag * fPrevReal; + fReal = L_add( L_sub( pppfReal[c][n][b], Mpy_32_32( fA1Real, fPrevReal ) ), Mpy_32_32( fA1Imag, fPrevImag ) ); + fImag = L_sub( L_sub( pppfImag[c][n][b], Mpy_32_32( fA1Real, fPrevImag ) ), Mpy_32_32( fA1Imag, fPrevReal ) ); pppfReal[c][n][b] = fReal; + move32(); pppfImag[c][n][b] = fImag; + move32(); fPrevReal = fReal; + move32(); fPrevImag = fImag; + move32(); } - psPredictionDecoder->ppfPredStateReal[c][b] = fPrevReal; - psPredictionDecoder->ppfPredStateImag[c][b] = fPrevImag; + psPredictionDecoder->ppfPredStateReal_fx[c][b] = fPrevReal; + move32(); + psPredictionDecoder->ppfPredStateImag_fx[c][b] = fPrevImag; + move32(); } } } diff --git a/lib_isar/isar_PredEncoder.c b/lib_isar/isar_PredEncoder.c index 0433ff30e..0ca4d7add 100644 --- a/lib_isar/isar_PredEncoder.c +++ b/lib_isar/isar_PredEncoder.c @@ -35,10 +35,14 @@ #ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "isar_lcld_prot.h" -#include "isar_rom_lcld_tables.h" +#include "isar_lcld_rom_tables.h" #include "prot.h" #include "isar_prot.h" #include "wmc_auto.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "enh64.h" +#include "basop32.h" /*-------------------------------------------------------------------* @@ -47,10 +51,10 @@ * *-------------------------------------------------------------------*/ static void activate_bit( - int32_t *state, - const int32_t bit_id ) + Word32 *state, + const Word32 bit_id ) { - ( *state ) |= ( 1 << bit_id ); + ( *state ) = L_or( ( *state ), L_shl( 1, extract_l( bit_id ) ) ); } /*-------------------------------------------------------------------* @@ -60,26 +64,211 @@ static void activate_bit( *-------------------------------------------------------------------*/ static void deactivate_bit( - int32_t *state, - const int32_t bit_id ) + Word32 *state, + const Word32 bit_id ) { - ( *state ) &= ( ~( 1 << bit_id ) ); + ( *state ) = L_and( ( *state ), ~L_shl( 1, extract_l( bit_id ) ) ); } - void UpdatePredictionSubSetId( PredictionEncoder *psPredictionEncoder ) { - if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets ) + IF( EQ_32( ++psPredictionEncoder->iSubSetId, psPredictionEncoder->iNumSubSets ) ) { psPredictionEncoder->iSubSetId = 0; + move32(); } } - /*-------------------------------------------------------------------* * Function CreatePredictionEncoder() * * *-------------------------------------------------------------------*/ +ivas_error CreatePredictionEncoder_fx( + PredictionEncoder **psPredictionEncoder_out, + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iNumSubSets, + const Word32 iMaxNumPredBands ) +{ + Word32 k, n; + PredictionEncoder *psPredictionEncoder = NULL; + + IF( ( psPredictionEncoder = (PredictionEncoder *) malloc( sizeof( PredictionEncoder ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + psPredictionEncoder->iChannels = iChannels; + move32(); + psPredictionEncoder->iNumBlocks = iNumBlocks; + move32(); + psPredictionEncoder->iSubSetId = 0; + move32(); + psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands; + move32(); + psPredictionEncoder->iNumSubSets = iNumSubSets; + move32(); + IF( ( psPredictionEncoder->piPredChanEnable = (Word32 *) malloc( sizeof( Word32 ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + IF( ( psPredictionEncoder->piNumPredBands = (Word32 *) malloc( sizeof( Word32 ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + FOR( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + psPredictionEncoder->piPredChanEnable[n] = 0; + move32(); + psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly + move32(); + } + + IF( ( psPredictionEncoder->ppiPredBandEnable = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfA1Real_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfA1Imag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppiA1Mag = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppiA1Phase = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufReal_fx = (Word32 ***) malloc( sizeof( Word32 ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufImag_fx = (Word32 ***) malloc( sizeof( Word32 ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfInpPrevReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfInpPrevImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateRealTmp_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateImagTmp_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + FOR( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + IF( ( psPredictionEncoder->ppiPredBandEnable[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfA1Real_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfA1Imag_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppiA1Mag[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppiA1Phase[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufReal_fx[n] = (Word32 **) malloc( sizeof( Word32 * ) * LCLD_PRED_WIN_LEN ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufImag_fx[n] = (Word32 **) malloc( sizeof( Word32 * ) * LCLD_PRED_WIN_LEN ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + FOR( k = 0; k < LCLD_PRED_WIN_LEN; k++ ) + { + IF( ( psPredictionEncoder->pppfInpBufReal_fx[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufImag_fx[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set32_fx( psPredictionEncoder->pppfInpBufReal_fx[n][k], 0, LCLD_BANDS ); + set32_fx( psPredictionEncoder->pppfInpBufImag_fx[n][k], 0, LCLD_BANDS ); + } + IF( ( psPredictionEncoder->ppfPredStateReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set32_fx( psPredictionEncoder->ppfPredStateReal_fx[n], 0, LCLD_BANDS ); + set32_fx( psPredictionEncoder->ppfPredStateImag_fx[n], 0, LCLD_BANDS ); + + IF( ( psPredictionEncoder->ppfInpPrevReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfInpPrevImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + set32_fx( psPredictionEncoder->ppfInpPrevReal_fx[n], 0, LCLD_BANDS ); + set32_fx( psPredictionEncoder->ppfInpPrevImag_fx[n], 0, LCLD_BANDS ); + + IF( ( psPredictionEncoder->ppfPredStateRealTmp_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateImagTmp_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set32_fx( psPredictionEncoder->ppfPredStateRealTmp_fx[n], 0, LCLD_BANDS ); + set32_fx( psPredictionEncoder->ppfPredStateImagTmp_fx[n], 0, LCLD_BANDS ); + FOR( k = 0; k < LCLD_BANDS; k++ ) + { + psPredictionEncoder->ppiPredBandEnable[n][k] = 0; + move32(); + psPredictionEncoder->ppfA1Real_fx[n][k] = 0; + move32(); + psPredictionEncoder->ppfA1Imag_fx[n][k] = 0; + move32(); + } + } + + *psPredictionEncoder_out = psPredictionEncoder; + + return IVAS_ERR_OK; +} ivas_error CreatePredictionEncoder( PredictionEncoder **psPredictionEncoder_out, const int32_t iChannels, @@ -113,7 +302,7 @@ ivas_error CreatePredictionEncoder( for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) { psPredictionEncoder->piPredChanEnable[n] = 0; - psPredictionEncoder->piNumPredBands[n] = 40; + psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly } if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) @@ -265,6 +454,53 @@ ivas_error CreatePredictionEncoder( * *-------------------------------------------------------------------*/ +void DeletePredictionEncoder_fx( + PredictionEncoder *psPredictionEncoder ) +{ + Word32 n; + FOR( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + Word32 k; + free( psPredictionEncoder->ppiPredBandEnable[n] ); + free( psPredictionEncoder->ppfA1Real_fx[n] ); + free( psPredictionEncoder->ppfA1Imag_fx[n] ); + free( psPredictionEncoder->ppiA1Mag[n] ); + free( psPredictionEncoder->ppiA1Phase[n] ); + FOR( k = 0; k < LCLD_PRED_WIN_LEN; k++ ) + { + free( psPredictionEncoder->pppfInpBufReal_fx[n][k] ); + free( psPredictionEncoder->pppfInpBufImag_fx[n][k] ); + } + free( psPredictionEncoder->pppfInpBufReal_fx[n] ); + free( psPredictionEncoder->pppfInpBufImag_fx[n] ); + free( psPredictionEncoder->ppfInpPrevReal_fx[n] ); + free( psPredictionEncoder->ppfInpPrevImag_fx[n] ); + free( psPredictionEncoder->ppfPredStateReal_fx[n] ); + free( psPredictionEncoder->ppfPredStateImag_fx[n] ); + free( psPredictionEncoder->ppfPredStateRealTmp_fx[n] ); + free( psPredictionEncoder->ppfPredStateImagTmp_fx[n] ); + } + free( psPredictionEncoder->piPredChanEnable ); + free( psPredictionEncoder->piNumPredBands ); + free( psPredictionEncoder->ppiPredBandEnable ); + free( psPredictionEncoder->ppfA1Real_fx ); + free( psPredictionEncoder->ppfA1Imag_fx ); + free( psPredictionEncoder->ppiA1Mag ); + free( psPredictionEncoder->ppiA1Phase ); + free( psPredictionEncoder->pppfInpBufReal_fx ); + free( psPredictionEncoder->pppfInpBufImag_fx ); + free( psPredictionEncoder->ppfInpPrevReal_fx ); + free( psPredictionEncoder->ppfInpPrevImag_fx ); + free( psPredictionEncoder->ppfPredStateReal_fx ); + free( psPredictionEncoder->ppfPredStateImag_fx ); + free( psPredictionEncoder->ppfPredStateRealTmp_fx ); + free( psPredictionEncoder->ppfPredStateImagTmp_fx ); + + + free( psPredictionEncoder ); + + return; +} void DeletePredictionEncoder( PredictionEncoder *psPredictionEncoder ) { @@ -412,7 +648,7 @@ void ComputePredictors( /* compute these before quant */ /* Compute est coding gain based on quantized filter coefficients */ fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); - fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); + fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag ); fA1Mag = fMagScale * asinf( fA1Mag ); iA1Mag = (int32_t) ( fA1Mag + 0.5f ); @@ -424,14 +660,14 @@ void ComputePredictors( fA1Phase = fPhaseScale * fA1Phase; iA1Phase = ( fA1Phase > 0.0f ) ? (int32_t) ( fA1Phase + 0.5f ) : (int32_t) ( fA1Phase - 0.5f ); iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN; - iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; + iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap? fA1Phase = fInvPhaseScale * (float) iA1Phase; fA1Real = fA1Mag * cosf( fA1Phase ); fA1Imag = fA1Mag * sinf( fA1Phase ); fGain2 = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); - fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); + fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) fGain = ( fGain < fGain2 ) ? fGain : fGain2; fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2; } @@ -441,11 +677,11 @@ void ComputePredictors( fA1Imag = 0.0f; iA1Mag = 0; iA1Phase = 0; - fGain = -10.0f; + fGain = -10.0f; // Fix this } pfEstPredBitGain[b] = fBitGain; - psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); // Initial prediction enable psPredictionEncoder->ppfA1Real[c][b] = fA1Real; psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; @@ -462,7 +698,7 @@ void ComputePredictors( iPredBands = 0; fBitGain = -7.0; for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) - { + { // still getting this decision wrong! fBitGain -= 1.0; if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) { @@ -498,6 +734,402 @@ void ComputePredictors( } } +void ComputePredictors_fx( + PredictionEncoder *psPredictionEncoder, + Word32 ***pppfReal_fx, // Q12? + Word32 ***pppfImag_fx ) // Q12? +{ + Word32 c; + + Word32 b0 = psPredictionEncoder->iSubSetId; + Word32 bstep = psPredictionEncoder->iNumSubSets; + Word32 iNumBlocks = psPredictionEncoder->iNumBlocks; + /*float ***pppfRealBuf; + float ***pppfImagBuf;*/ + Word32 ***pppfRealBuf_fx; + Word32 ***pppfImagBuf_fx; + // float pfEstPredBitGain[LCLD_BANDS] = { 0 }; + Word32 pfEstPredBitGain_fx[LCLD_BANDS] = { 0 }; + + IF( LT_32( iNumBlocks, LCLD_PRED_WIN_LEN ) ) + { + /*pppfRealBuf = psPredictionEncoder->pppfInpBufReal; + pppfImagBuf = psPredictionEncoder->pppfInpBufImag;*/ + pppfRealBuf_fx = psPredictionEncoder->pppfInpBufReal_fx; + move32(); + pppfImagBuf_fx = psPredictionEncoder->pppfInpBufImag_fx; + move32(); + FOR( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + Word32 n; + FOR( n = 0; n < L_sub( LCLD_PRED_WIN_LEN, iNumBlocks ); n++ ) + { + /*mvr2r(pppfRealBuf[c][n + iNumBlocks], pppfRealBuf[c][n], LCLD_BANDS); + mvr2r(pppfImagBuf[c][n + iNumBlocks], pppfImagBuf[c][n], LCLD_BANDS);*/ + mvl2l( pppfRealBuf_fx[c][n + iNumBlocks], pppfRealBuf_fx[c][n], LCLD_BANDS ); + mvl2l( pppfImagBuf_fx[c][n + iNumBlocks], pppfImagBuf_fx[c][n], LCLD_BANDS ); + } + FOR( n = 0; n < iNumBlocks; n++ ) + { + /*mvr2r(pppfReal[c][n], pppfRealBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS); + mvr2r(pppfImag[c][n], pppfImagBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS);*/ + mvl2l( pppfReal_fx[c][n], pppfRealBuf_fx[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS ); + mvl2l( pppfImag_fx[c][n], pppfImagBuf_fx[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS ); + } + } + } + ELSE + { + /*pppfRealBuf = pppfReal; + pppfImagBuf = pppfImag;*/ + pppfRealBuf_fx = pppfReal_fx; + move32(); + pppfImagBuf_fx = pppfImag_fx; + move32(); + } + + FOR( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + Word32 b; + FOR( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { + Word32 n; + /*float fGain = 0.0; + float fBitGain = 0.0; + float *pfRxxReal; + float *pfRxxImag; + float fA1Real; + float fA1Imag;*/ + Word32 fGain_fx = 0; + Word32 fBitGain_fx = 0; + Word32 *pfRxxReal_fx; + Word32 *pfRxxImag_fx; + Word32 fA1Real_fx; + Word32 fA1Imag_fx; + Word32 L_temp; + Word64 W_temp1, W_temp2; + Word32 iA1Mag; + Word32 iA1Phase; + + /*pfRxxReal = psPredictionEncoder->pfRxxReal; + pfRxxImag = psPredictionEncoder->pfRxxImag;*/ + pfRxxReal_fx = psPredictionEncoder->pfRxxReal_fx; + move32(); + pfRxxImag_fx = psPredictionEncoder->pfRxxImag_fx; + move32(); + /*pfRxxReal[0] = 0.0; + pfRxxImag[0] = 0.0;*/ + pfRxxReal_fx[0] = 0; + move32(); + pfRxxImag_fx[0] = 0; + move32(); + W_temp1 = 0; + FOR( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) + { + // pfRxxReal[0] += (pppfRealBuf[c][n][b] * pppfRealBuf[c][n][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n][b]); + W_temp1 = W_add( W_temp1, W_add( W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfRealBuf_fx[c][n][b] ), + W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfImagBuf_fx[c][n][b] ) ) ); // Q40 + } + Word16 w_norm1 = W_norm( W_temp1 ); + W_temp1 = W_shr( W_temp1, 32 - w_norm1 ); + pfRxxReal_fx[0] = W_extract_l( W_temp1 ); + /*pfRxxReal[1] = 0.0; + pfRxxImag[1] = 0.0;*/ + pfRxxReal_fx[1] = 0; + move32(); + pfRxxImag_fx[1] = 0; + move32(); + W_temp1 = 0; + W_temp2 = 0; + FOR( n = 1; n < LCLD_PRED_WIN_LEN; n++ ) + { + /*pfRxxReal[1] += (pppfRealBuf[c][n][b] * pppfRealBuf[c][n - 1][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n - 1][b]); + pfRxxImag[1] += (pppfImagBuf[c][n][b] * pppfRealBuf[c][n - 1][b] - pppfRealBuf[c][n][b] * pppfImagBuf[c][n - 1][b]);*/ + W_temp1 = W_add( W_temp1, W_add( W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfRealBuf_fx[c][n - 1][b] ), + W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfImagBuf_fx[c][n - 1][b] ) ) ); // Q40 + W_temp2 = W_add( W_temp2, W_sub( W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfRealBuf_fx[c][n - 1][b] ), + W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfImagBuf_fx[c][n - 1][b] ) ) ); // Q40 + } + + Word16 w_norm2 = W_norm( W_temp1 ); + W_temp1 = W_shr( W_temp1, 32 - w_norm2 ); + pfRxxReal_fx[1] = W_extract_l( W_temp1 ); + Word16 w_norm3 = W_norm( W_temp2 ); + W_temp2 = W_shr( W_temp2, 32 - w_norm3 ); + pfRxxImag_fx[1] = W_extract_l( W_temp2 ); + Word16 final_w_norm = min( w_norm1, min( w_norm2, w_norm3 ) ); + pfRxxReal_fx[0] = L_shr( pfRxxReal_fx[0], w_norm1 - final_w_norm ); // Q8 + final_w_norm + pfRxxReal_fx[1] = L_shr( pfRxxReal_fx[1], w_norm2 - final_w_norm ); // Q8 + final_w_norm + pfRxxImag_fx[1] = L_shr( pfRxxImag_fx[1], w_norm3 - final_w_norm ); // Q8 + final_w_norm + // if (pfRxxReal[0] > 1e-12f) + IF( GT_32( pfRxxReal_fx[0], 0 ) ) + { + /*float fA1Mag; + float fA1Phase; + float fGain2; + float fBitGain2;*/ + Word32 fA1Mag_fx; + Word32 fA1Phase_fx; + Word32 fGain2_fx; + Word32 fBitGain2_fx; + Word32 iNumBlocksPerPredCoef = L_min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN ); + const Word32 fMagScale_fx32 = 1452576210; // Q28 + move32(); + // const float fInvMagScale = M_PI / (2.0f * (float)(1 << (PRED_QUNAT_FILTER_MAG_BITS)) + 1.0f); + const Word16 fInvMagScale_fx = 6055; // Q15 + move16(); + // const float fPhaseScale = (float)(1 << (PRED_QUANT_FILTER_PHASE_BITS - 1)) / M_PI + const Word32 fPhaseScale_fx32 = 1367130551; // Q28 + // const float fInvPhaseScale = M_PI / (float)(1 << (PRED_QUANT_FILTER_PHASE_BITS - 1)); + const Word16 fInvPhaseScale_fx = 6434; // Q15 + move16(); + + /* Compute filter coefficeints */ + // fA1Real = -pfRxxReal[1] / pfRxxReal[0]; + Word16 sf_r, sf_i; + fA1Real_fx = BASOP_Util_Divide3232_Scale( -pfRxxReal_fx[1], pfRxxReal_fx[0], &sf_r ); + // fA1Imag = -pfRxxImag[1] / pfRxxReal[0]; + fA1Imag_fx = BASOP_Util_Divide3232_Scale( -pfRxxImag_fx[1], pfRxxReal_fx[0], &sf_i ); + + IF( GT_16( sf_r, sf_i ) ) + { + fA1Imag_fx = L_shr( fA1Imag_fx, sub( sf_r, sf_i ) ); + sf_i = sf_r; + move16(); + } + ELSE IF( LT_16( sf_r, sf_i ) ) + { + fA1Real_fx = L_shr( fA1Real_fx, sub( sf_i, sf_r ) ); + sf_r = sf_i; + move16(); + } + Word32 L_temp_1; + IF( LT_16( sf_r, -7 ) ) + { + fA1Real_fx = L_shr( fA1Real_fx, sub( -8, sf_r ) ); + fA1Imag_fx = L_shr( fA1Imag_fx, sub( -8, sf_i ) ); + sf_r = sf_i = -8; + move16(); + L_temp_1 = MAX_32; + move32(); + } + ELSE + { + L_temp_1 = L_shl( 1, sub( 15, shl( sf_r, 1 ) ) ); + } + /* compute these before quant */ + /* Compute est coding gain based on quantized filter coefficients */ + // fGain = 1.0f / (1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag); + L_temp = L_sub( L_sub( L_temp_1, mult_r( extract_l( fA1Real_fx ), extract_l( fA1Real_fx ) ) ), mult_r( extract_l( fA1Imag_fx ), extract_l( fA1Imag_fx ) ) ); + Word16 exp = norm_l( L_temp ); + IF( LT_16( exp, 16 ) ) + { + L_temp = L_shr( L_temp, sub( 16, exp ) ); + exp = add( sub( 16, exp ), shl( sf_r, 1 ) ); + } + else + { + exp = shl( sf_r, 1 ); + } + // fGain_fx = sub(sub(32767, extract_h(Mpy_32_32(fA1Real_fx, fA1Real_fx))), extract_h(Mpy_32_32(fA1Imag_fx, fA1Imag_fx))); + // fGain_fx = extract_l(L_shl(L_temp, 2*sf_r)); + fGain_fx = extract_l( L_temp ); + fGain_fx = max( 1, fGain_fx ); + fGain_fx = Inv16( extract_l( fGain_fx ), &exp ); // Q15 - exp + // fGain_fx = L_shl(fGain_fx, exp); //Q15 + // fBitGain = 0.65f * log2f(fGain) * (float)(iNumBlocksPerPredCoef)-(float)(PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS); // Wrong fix (iNumBlocks-1) + // fBitGain_fx = L_sub(L_mult0(L_shr(L_mult0(21299, L_shr(L_add(BASOP_Util_Log2(fGain_fx), 335544320), 10)), 15), (Word16)iNumBlocksPerPredCoef), 262144); // Wrong fix (iNumBlocks-1) Q15 + W_temp1 = W_mult0_32_32( L_shr( Mpy_32_32( 1395864371, L_add( BASOP_Util_Log2( fGain_fx ), L_shl( add( 16, exp ), 25 ) ) ), 10 ), iNumBlocksPerPredCoef ); + Word16 w_norm4 = W_norm( W_temp1 ); + IF( LT_16( w_norm4, 32 ) ) + { + W_temp1 = W_shr( W_temp1, 32 - w_norm4 ); + w_norm4 = sub( 32, w_norm4 ); + } + ELSE + { + w_norm4 = 0; + move16(); + } + fBitGain_fx = L_sub( W_extract_l( W_temp1 ), L_shr( 262144, w_norm4 ) ); // Wrong fix (iNumBlocks-1) Q15 + // fA1Mag = sqrtf(fA1Real * fA1Real + fA1Imag * fA1Imag); + fA1Mag_fx = L_add( mult_r( extract_l( fA1Real_fx ), extract_l( fA1Real_fx ) ), mult_r( extract_l( fA1Imag_fx ), extract_l( fA1Imag_fx ) ) ); // Q15 - 2*sf_r + // fA1Mag = fMagScale * asinf(fA1Mag); + exp = 0; + move16(); + L_temp = L_sub( L_temp_1, fA1Mag_fx ); // Q15 - 2*sf_r + IF( NE_32( L_temp, 0 ) ) + { + fA1Mag_fx = BASOP_Util_Divide3232_Scale( fA1Mag_fx, L_temp, &exp ); + } + ELSE + { + fA1Mag_fx = 0; + move32(); + exp = 0; + move16(); + } + fA1Mag_fx = L_shl( fA1Mag_fx, 16 ); + IF( fA1Mag_fx > 0 ) + { + fA1Mag_fx = Sqrt32( fA1Mag_fx, &exp ); + } + ELSE + { + fA1Mag_fx = 0; + move32(); + exp = 0; + move16(); + } + + fA1Mag_fx = BASOP_util_atan( L_shr_r_sat( fA1Mag_fx, 6 - exp ) ); // Q14 + fA1Mag_fx = Mpy_32_16_1( fMagScale_fx32, extract_l( fA1Mag_fx ) ); // Q27 + + // iA1Mag = (int32_t)(fA1Mag + 0.5f); + IF( GE_32( fA1Mag_fx, 0 ) ) + { + iA1Mag = L_shr( L_add( fA1Mag_fx, 67108864 ), Q27 ); // Q27 -> Q0 + } + ELSE + { + fA1Mag_fx = L_negate( fA1Mag_fx ); + iA1Mag = L_shr( L_add( fA1Mag_fx, 67108864 ), Q27 ); // Q27 -> Q0 + iA1Mag = L_negate( iA1Mag ); + } + iA1Mag = ( iA1Mag > PRED_QUANT_FILTER_MAG_MIN ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MIN; + iA1Mag = ( iA1Mag < PRED_QUANT_FILTER_MAG_MAX ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MAX; + // fA1Mag = sinf(fInvMagScale * (float)iA1Mag); + fA1Mag_fx = L_deposit_l( getSinWord16( extract_l( L_shr( L_mult0( extract_l( fInvMagScale_fx ), extract_l( iA1Mag ) ), 2 ) ) ) ); // Q14 + + // fA1Phase = atan2f(fA1Imag, fA1Real); + fA1Phase_fx = BASOP_util_atan2( fA1Imag_fx, fA1Real_fx, 0 ); // Q13 + // fA1Phase = fPhaseScale * fA1Phase; + fA1Phase_fx = Mpy_32_16_1( fPhaseScale_fx32, extract_l( fA1Phase_fx ) ); // Q26 + // iA1Phase = (fA1Phase > 0.0f) ? (int32_t)(fA1Phase + 0.5f) : (int32_t)(fA1Phase - 0.5f); + // iA1Phase = (fA1Phase_fx > 0) ? shr(add(fA1Phase_fx, 512), 10) : shr(sub(fA1Phase_fx, 512), 10); + IF( GE_32( fA1Phase_fx, 0 ) ) + { + iA1Phase = L_shr( L_add( fA1Phase_fx, 33554432 ), Q26 ); // Q26 -> Q0 + } + ELSE + { + fA1Phase_fx = L_negate( fA1Phase_fx ); + iA1Phase = L_shr( L_add( fA1Phase_fx, 33554432 ), Q26 ); // Q26 -> Q0 + iA1Phase = L_negate( iA1Phase ); + } + iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN; + iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap? + // fA1Phase = fInvPhaseScale * (float)iA1Phase; + L_temp = L_mult0( fInvPhaseScale_fx, (Word16) iA1Phase ); // Q15 + + // fA1Real = fA1Mag * cosf(fA1Phase); + fA1Real_fx = L_mult0( extract_l( fA1Mag_fx ), getCosWord16( extract_l( L_shr( L_temp, 2 ) ) ) ); // Q28 + // fA1Imag = fA1Mag * sinf(fA1Phase); + fA1Imag_fx = L_mult0( extract_l( fA1Mag_fx ), getSinWord16( extract_l( L_shr( L_temp, 2 ) ) ) ); // Q28 + + // fGain2 = 1.0f / (1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag); + exp = 0; + fGain2_fx = sub( sub( 32767, mult_r( extract_l( L_shr( fA1Real_fx, 13 ) ), extract_l( L_shr( fA1Real_fx, 13 ) ) ) ), mult_r( extract_l( L_shr( fA1Imag_fx, 13 ) ), extract_l( L_shr( fA1Imag_fx, 13 ) ) ) ); + fGain2_fx = L_max( 1, fGain2_fx ); + fGain2_fx = Inv16( extract_l( fGain2_fx ), &exp ); // Q15-exp + fGain2_fx = L_shl( fGain2_fx, exp ); + // fBitGain2 = 0.65f * log2f(fGain) * (float)(iNumBlocksPerPredCoef)-(float)(PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS); // Wrong fix (iNumBlocks-1) + // fBitGain2_fx = L_sub(L_mult0(L_shr(L_mult0(21299, L_shr(L_add(BASOP_Util_Log2(fGain_fx), 335544320), 10)), 15), (Word16)iNumBlocksPerPredCoef), 262144); // Wrong fix (iNumBlocks-1) Q15 + fBitGain2_fx = L_sub( W_extract_l( W_temp1 ), L_shr( 262144, w_norm4 ) ); // Wrong fix (iNumBlocks-1) Q15 + // fGain = (fGain < fGain2) ? fGain : fGain2; + fGain_fx = ( fGain_fx < fGain2_fx ) ? fGain_fx : fGain2_fx; + // fBitGain = (fBitGain < fBitGain2) ? fBitGain : fBitGain2; + fBitGain_fx = ( fBitGain_fx < fBitGain2_fx ) ? fBitGain_fx : fBitGain2_fx; + } + ELSE + { + /*fA1Real = 0.0f; + fA1Imag = 0.0f;*/ + fA1Real_fx = 0; + move32(); + fA1Imag_fx = 0; + move32(); + iA1Mag = 0; + move32(); + iA1Phase = 0; + move32(); + // fGain = -10.0f; // Fix this + fGain_fx = -327680; // Fix this + move32(); + } + + // pfEstPredBitGain[b] = fBitGain; + // psPredictionEncoder->ppiPredBandEnable[c][b] = (fBitGain > 0.0f); // Initial prediction enable + // psPredictionEncoder->ppfA1Real[c][b] = fA1Real; + // psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; + pfEstPredBitGain_fx[b] = fBitGain_fx; // Q15 + move32(); + // printf("\n %d %d %f %f %f ", iA1Mag, iA1Phase, (float)fBitGain_fx / 32768, (float)fA1Real_fx / ONE_IN_Q28, (float)fA1Imag_fx / ONE_IN_Q28); + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain_fx > 0 ); // Initial prediction enable + psPredictionEncoder->ppfA1Real_fx[c][b] = L_shl( fA1Real_fx, Q3 ); // Q31 + psPredictionEncoder->ppfA1Imag_fx[c][b] = L_shl( fA1Imag_fx, Q3 ); // Q31 + psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; + move32(); + psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase; + move32(); + } + + { + // float fBestCost; + Word32 fBestCost_fx; + Word32 iPredBands; + // float fBitGain; + Word32 fBitGain_fx; + Word32 iPredChanEnable = 0; + + // fBestCost = 0.0; + fBestCost_fx = 0; + move32(); + iPredBands = 0; + move32(); + // fBitGain = -7.0; + fBitGain_fx = -229376; // Q15 + move32(); + FOR( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { // still getting this decision wrong! + // fBitGain -= 1.0; + fBitGain_fx = L_sub( fBitGain_fx, 32768 ); + IF( EQ_32( psPredictionEncoder->ppiPredBandEnable[c][b], 1 ) ) + { + // fBitGain += pfEstPredBitGain[b]; + fBitGain_fx = L_add( fBitGain_fx, pfEstPredBitGain_fx[b] ); + } + // if (fBitGain > fBestCost) + IF( GT_32( fBitGain_fx, fBestCost_fx ) ) + { + fBestCost_fx = fBitGain_fx; + iPredBands = b; + iPredChanEnable = 1; + } + } + + IF( EQ_32( iPredChanEnable, 1 ) ) + { + FOR( b = iPredBands + bstep; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep; + } + ELSE + { + FOR( b = b0; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + deactivate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = 0; + move32(); + } + } + } +} /*-------------------------------------------------------------------* * Function ApplyForwardPredictors() @@ -511,62 +1143,68 @@ void ComputePredictors( * *-------------------------------------------------------------------*/ -int32_t WritePredictors( +Word32 WritePredictors( PredictionEncoder *psPredictionEncoder, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsWritten = 0; - int32_t c; - int32_t iNumSubSets = psPredictionEncoder->iNumSubSets; - int32_t iSubSetId = psPredictionEncoder->iSubSetId; - int32_t iNumPredBandBits = 6; - const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 ); + Word32 iBitsWritten = 0; + Word32 c; + Word32 iNumSubSets = psPredictionEncoder->iNumSubSets; + Word32 iSubSetId = psPredictionEncoder->iSubSetId; + Word32 iNumPredBandBits = 6; + const Word16 iSubSetBits = ( GT_16( LCLD_MAX_NUM_PRED_SUBSETS, 4 ) ? 3 : 2 ); + move32(); + move32(); + move16(); /* number of subsets */ - ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumSubSets - 1, iSubSetBits ); /* otherwise use default */ - iBitsWritten += iSubSetBits; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iNumSubSets, 1 ), iSubSetBits ); /* otherwise use default */ + iBitsWritten = L_add( iBitsWritten, iSubSetBits ); - if ( iNumSubSets > 1 ) + IF( GT_32( iNumSubSets, 1 ) ) { /* write current subset */ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iSubSetId, iSubSetBits ); - iBitsWritten += iSubSetBits; - iNumPredBandBits = ( iNumSubSets >= 4 ? 4 : 5 ); + iBitsWritten = L_add( iBitsWritten, iSubSetBits ); + iNumPredBandBits = ( GE_32( iNumSubSets, 4 ) ? 4 : 5 ); + move32(); } - for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + FOR( c = 0; c < psPredictionEncoder->iChannels; c++ ) { - int32_t b; - int32_t b0 = iSubSetId; + Word32 b; + Word32 b0 = iSubSetId; + move32(); ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets ); - iBitsWritten += iNumSubSets; + iBitsWritten = L_add( iBitsWritten, iNumSubSets ); - if ( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) ) + IF( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) ) { - int32_t iNumPredBands = ( psPredictionEncoder->piNumPredBands[c] - b0 ) / iNumSubSets; + Word32 iNumPredBands = L_sub( psPredictionEncoder->piNumPredBands[c], b0 ) / iNumSubSets; ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumPredBands, iNumPredBandBits ); - iBitsWritten += iNumPredBandBits; + iBitsWritten = L_add( iBitsWritten, iNumPredBandBits ); - for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets ) + FOR( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); - if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + IF( EQ_32( psPredictionEncoder->ppiPredBandEnable[c][b], 1 ) ) { - int32_t iA1Mag; - int32_t iA1Phase; + Word32 iA1Mag; + Word32 iA1Phase; iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; - iA1Phase = psPredictionEncoder->ppiA1Phase[c][b] - PRED_QUANT_FILTER_PHASE_MIN; + move32(); + iA1Phase = L_sub( psPredictionEncoder->ppiA1Phase[c][b], PRED_QUANT_FILTER_PHASE_MIN ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); - iBitsWritten += PRED_QUNAT_FILTER_MAG_BITS; + iBitsWritten = L_add( iBitsWritten, PRED_QUNAT_FILTER_MAG_BITS ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); - iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS; + iBitsWritten = L_add( iBitsWritten, PRED_QUANT_FILTER_PHASE_BITS ); } } } diff --git a/lib_isar/isar_RMSEnvGrouping.c b/lib_isar/isar_RMSEnvGrouping.c index 1a0b3aa11..2283764a1 100644 --- a/lib_isar/isar_RMSEnvGrouping.c +++ b/lib_isar/isar_RMSEnvGrouping.c @@ -30,84 +30,126 @@ *******************************************************************************************************/ +/* Double check cost function calculation */ + #include #include "options.h" #ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "prot.h" #include "isar_lcld_prot.h" -#include "isar_rom_lcld_tables.h" +#include "isar_lcld_rom_tables.h" #include "wmc_auto.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "enh64.h" +Word32 Inv_grp_length[17] = { + // Q31 + 0, + 2147483647, + 1073741823, + 715827882, + 536870911, + 429496729, + 357913941, + 306783378, + 268435455, + 238609294, + 214748364, + 195225786, + 178956970, + 165191049, + 153391689, + 143165576, + 134217727, +}; +static Word16 find_guarded_bits_fx( Word32 n ) +{ + return n <= 1 ? 0 : n <= 2 ? 1 + : n <= 4 ? 2 + : n <= 8 ? 3 + : n <= 16 ? 4 + : n <= 32 ? 5 + : n <= 64 ? 6 + : n <= 128 ? 7 + : n <= 256 ? 8 + : n <= 512 ? 9 + : n <= 1024 ? 10 + : n <= 2048 ? 11 + : n <= 4096 ? 12 + : n <= 8192 ? 13 + : n <= 16384 ? 14 + : 15; +} /*-------------------------------------------------------------------* * Local ROM tables * * *-------------------------------------------------------------------*/ - -static const float c_afThreshQuiet48[23] = { - -8.40653699e+01f, - -8.40653699e+01f, - -8.40653699e+01f, - -8.40653699e+01f, - -8.40653699e+01f, - -8.40653699e+01f, - -8.40653699e+01f, - -8.40653699e+01f, - -8.38067304e+01f, - -8.28409495e+01f, - -8.17031225e+01f, - -7.89799501e+01f, - -7.70607916e+01f, - -7.58484320e+01f, - -7.47976303e+01f, - -7.37491303e+01f, - -7.13163746e+01f, - -6.86144293e+01f, - -6.56295695e+01f, - -6.06521800e+01f, - -3.15408065e+01f, - -1.92542188e+01f, - -1.88401753e+01f, +static const Word32 c_afThreshQuiet48_fx[23] = { + // Q23 + -705191424, + -705191424, + -705191424, + -705191424, + -705191424, + -705191424, + -705191424, + -705191424, + -703021824, + -694920256, + -685375488, + -662531840, + -646432768, + -636262784, + -627448000, + -618652544, + -598245120, + -575579520, + -550540736, + -508787360, + -264583456, + -161516096, + -158042848, }; - -static const float c_fiDefaultTheta48[MAX_BANDS_48] = { - 0.4375, - 0.4375, - 0.375, - 0.3125, - 0.3125, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, - 0.25, +static const Word32 c_fiDefaultTheta48_fx[MAX_BANDS_48] = { + // Q31 + 939524096, + 939524096, + 805306368, + 671088640, + 671088640, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, }; - typedef struct GMNODE { int32_t iGroupStart; int32_t iGroupLength; - float *pfMergedEnergydB; + Word32 *pfMergedEnergydB_fx; int32_t *piQRMSEnvelope; int32_t iGroupRMSEnvelopeCost; - float fGroupSNRPenalty; - + Word32 fGroupSNRPenalty_fx; + Word16 fGroupSNRPenalty_exp; struct GMNODE *psNext; } GMNode; @@ -115,9 +157,12 @@ struct RMS_ENVELOPE_GROUPING { int32_t iNumBlocks; int32_t iMaxGroups; - float **ppfBandEnergy; - float **ppfBandEnergydB; - float **ppfWeight; + Word32 **ppfWeight_man; + Word16 **ppfWeight_exp; + Word32 **ppfBandEnergy_man; + Word16 **ppfBandEnergy_exp; + Word32 **ppfBandEnergydB_fx; + // Word32 **ppfWeight_fx; GMNode *psGMNodes; }; @@ -129,9 +174,9 @@ struct RMS_ENVELOPE_GROUPING *-------------------------------------------------------------------*/ RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( - const int32_t iNumBlocks ) + const Word32 iNumBlocks ) { - int32_t n; + Word32 n; RMSEnvelopeGrouping *psRMSEnvelopeGrouping; @@ -139,24 +184,29 @@ RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( psRMSEnvelopeGrouping->iNumBlocks = iNumBlocks; psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks >> 1; + psRMSEnvelopeGrouping->ppfBandEnergy_man = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) ); + psRMSEnvelopeGrouping->ppfBandEnergy_exp = (Word16 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word16 * ) ); + psRMSEnvelopeGrouping->ppfBandEnergydB_fx = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) ); + psRMSEnvelopeGrouping->ppfWeight_man = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) ); + psRMSEnvelopeGrouping->ppfWeight_exp = (Word16 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word16 * ) ); - psRMSEnvelopeGrouping->ppfBandEnergy = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) ); - psRMSEnvelopeGrouping->ppfBandEnergydB = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) ); - psRMSEnvelopeGrouping->ppfWeight = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) ); for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) { - psRMSEnvelopeGrouping->ppfBandEnergy[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); /* 2 for stereo joint group calc */ - psRMSEnvelopeGrouping->ppfBandEnergydB[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); - psRMSEnvelopeGrouping->ppfWeight[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); + psRMSEnvelopeGrouping->ppfBandEnergy_man[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) ); /* 2 for stereo joint group calc */ + psRMSEnvelopeGrouping->ppfBandEnergy_exp[n] = (Word16 *) malloc( MAX_BANDS * 2 * sizeof( Word16 ) ); /* 2 for stereo joint group calc */ + psRMSEnvelopeGrouping->ppfBandEnergydB_fx[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) ); + psRMSEnvelopeGrouping->ppfWeight_man[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) ); + psRMSEnvelopeGrouping->ppfWeight_exp[n] = (Word16 *) malloc( MAX_BANDS * 2 * sizeof( Word16 ) ); } psRMSEnvelopeGrouping->psGMNodes = (GMNode *) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( GMNode ) ); for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) { - psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); - psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope = (int32_t *) malloc( MAX_BANDS * 2 * sizeof( int32_t ) ); + psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB_fx = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( float ) ); + psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( int32_t ) ); psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; - psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 ); + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_exp = 1; } return psRMSEnvelopeGrouping; @@ -176,17 +226,22 @@ void DeleteRMSEnvelopeGrouping( for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) { - free( psRMSEnvelopeGrouping->ppfBandEnergy[n] ); - free( psRMSEnvelopeGrouping->ppfBandEnergydB[n] ); - free( psRMSEnvelopeGrouping->ppfWeight[n] ); + free( psRMSEnvelopeGrouping->ppfBandEnergy_man[n] ); + free( psRMSEnvelopeGrouping->ppfBandEnergy_exp[n] ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB_fx[n] ); + free( psRMSEnvelopeGrouping->ppfWeight_man[n] ); + free( psRMSEnvelopeGrouping->ppfWeight_exp[n] ); } - free( psRMSEnvelopeGrouping->ppfBandEnergy ); - free( psRMSEnvelopeGrouping->ppfBandEnergydB ); - free( psRMSEnvelopeGrouping->ppfWeight ); + free( psRMSEnvelopeGrouping->ppfBandEnergy_man ); + free( psRMSEnvelopeGrouping->ppfBandEnergy_exp ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB_fx ); + free( psRMSEnvelopeGrouping->ppfWeight_man ); + free( psRMSEnvelopeGrouping->ppfWeight_exp ); + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) { - free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB ); + free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB_fx ); free( psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope ); } free( psRMSEnvelopeGrouping->psGMNodes ); @@ -202,54 +257,142 @@ void DeleteRMSEnvelopeGrouping( * * *-------------------------------------------------------------------*/ - static void ComputeBandEnergy( - const int32_t iChannels, - const int32_t iNumBlocks, - const int32_t iNumBands, - const int32_t *piBandwidths, - float ***pppfReal, - float ***pppfImag, - float **ppfBandEnergy, - float **ppfBandEnergydB, - float **ppfWeight ) + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + Word32 **ppfBandEnergy_man, + Word16 **ppfBandEnergy_exp, + Word32 **ppfBandEnergydB_fx, + Word32 **ppfWeight_man, + Word16 **ppfWeight_exp, + Word16 q_final ) { - int32_t n; - for ( n = 0; n < iChannels; n++ ) + Word32 n; + Word32 constant = 1616142483; // Q29 of(1/log2(10))*10 + Word32 const_comp3, const_comp1; + Word16 exp3 = 0, exp1 = 0, Flag1, Flag2, Flag3; + Word16 div_exp; + /*For 0.33f*/ + const_comp3 = 1417339264; + move32(); + exp3 = -1; + move16(); + // f2me( 0.33, &const_comp3, &exp3 );// + // f2me( 1.0, &const_comp1, &exp1 );// + /*For 1.0f*/ + Word32 mul_32; + Word16 mul_exp; + const_comp1 = 1073741824; + move32(); + exp1 = 1; + move16(); + FOR( n = 0; n < iChannels; n++ ) { - int32_t k; - int32_t iChanOffset; + Word32 k; + Word32 iChanOffset; - iChanOffset = n * iNumBands; - for ( k = 0; k < iNumBlocks; k++ ) + iChanOffset = L_mult0( extract_l( n ), extract_l( iNumBands ) ); + FOR( k = 0; k < iNumBlocks; k++ ) { - int32_t b; - int32_t iFBOffset; - float fMaxWeight; - + Word32 b; + Word32 iFBOffset; + Word32 fMaxWeight_fx = 0; + move32(); + Word16 fMaxWeight_exp = 0; + move16(); iFBOffset = 0; - fMaxWeight = 0.0f; - for ( b = 0; b < iNumBands; b++ ) + move32(); + FOR( b = 0; b < iNumBands; b++ ) { - int32_t m; - float fEnergy = 1e-12f; - float fWeight; - - for ( m = 0; m < piBandwidths[b]; m++ ) + Word32 m; + Word16 fEnergy_exp; + Word32 fEnergy_fx, fWeight_temp; + Word16 shift_value; + Word32 fEnergy_log_fx, fEnergy_log_fx1; + fEnergy_exp = 0; + move16(); + /*For 1e-12f in Q63*/ + Word32 fWeight_fx; + Word64 Wmult_value; + Word16 exp_pow = 0; + move16(); + Word16 guard_bits = find_guarded_bits_fx( piBandwidths[b] + 1 ); + // fEnergy_f64 = W_shr( fEnergy_f64, ( 63 - ( 2 * ( q_final - guard_bits ) + 1 ) ) ); + fEnergy_fx = 1180591616; + fEnergy_exp = -39; + FOR( m = 0; m < piBandwidths[b]; m++ ) { - fEnergy += ( pppfReal[n][k][iFBOffset] * pppfReal[n][k][iFBOffset] + pppfImag[n][k][iFBOffset] * pppfImag[n][k][iFBOffset] ); + Wmult_value = W_add( W_mult_32_32( L_shr( pppfReal_fx[n][k][iFBOffset], guard_bits ), L_shr( pppfReal_fx[n][k][iFBOffset], guard_bits ) ), W_mult_32_32( L_shr( pppfImag_fx[n][k][iFBOffset], guard_bits ), L_shr( pppfImag_fx[n][k][iFBOffset], guard_bits ) ) ); + shift_value = W_norm( Wmult_value ); + mul_32 = W_extract_h( W_shl( Wmult_value, shift_value ) ); + mul_exp = 31 - ( 2 * ( q_final - guard_bits ) + 1 + shift_value - 32 ); + fEnergy_fx = BASOP_Util_Add_Mant32Exp( fEnergy_fx, fEnergy_exp, mul_32, mul_exp, &fEnergy_exp ); // Some large number to prevent clipping iFBOffset++; } - fEnergy /= (float) ( piBandwidths[b] ); /* Correction removed normalization by 2*/ - ppfBandEnergy[k][iChanOffset + b] = fEnergy; - - fWeight = 0.33f * powf( 10.0f, 0.0068f * ( 10.0f * log10f( fEnergy ) - c_afThreshQuiet48[b] ) ); - fWeight = ( fWeight > 0.33f ) ? fWeight : 0.33f; - fWeight = ( fWeight < 1.0f ) ? fWeight : 1.0f; - fMaxWeight = ( fMaxWeight > fWeight ) ? fMaxWeight : fWeight; - ppfWeight[k][iChanOffset + b] = fWeight; - + IF( EQ_32( fEnergy_fx, 0 ) ) + { + // f2me( 1e-12f, &fEnergy_fx, &fEnergy_exp ); // + fEnergy_fx = 1180591616; + fEnergy_exp = -39; + fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2 + ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx; + move32(); + ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp; + move16(); + fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2 + ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx; + move32(); + ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp; + move16(); + fEnergy_log_fx1 = -1006632960; // Q23 + fWeight_fx = 403727488; // Q31 + exp_pow = 0; + } + ELSE + { + fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2 + ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx; + move32(); + ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp; + move16(); + fEnergy_fx = BASOP_Util_Log2( fEnergy_fx ); + move32(); + fEnergy_log_fx = L_add( fEnergy_fx, L_shl( L_deposit_l( fEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/ // log2f( fEnergy ) + fEnergy_log_fx1 = Mpy_32_32( fEnergy_log_fx, constant ); + fEnergy_log_fx = L_sub( fEnergy_log_fx1, c_afThreshQuiet48_fx[b] ); // Q23 of ( 10.0f * log10f( fEnergy ) - c_afThreshQuiet48[b] ) ) + fWeight_fx = Mpy_32_32( 48509336, fEnergy_log_fx ); // 0.0068f*3.3219 in Q31, result in Q23 + fWeight_temp = BASOP_util_Pow2( fWeight_fx, 8, &exp_pow ); + fWeight_fx = Mpy_32_32( 708669604, fWeight_temp ); // 708669604 = Q31 0f 0.33 + } + Flag1 = BASOP_Util_Cmp_Mant32Exp( fWeight_fx, exp_pow, const_comp3, exp3 ); + IF( NE_16( Flag1, 1 ) ) + { + fWeight_fx = const_comp3; + move32(); + exp_pow = exp3; + move16(); + } + Flag2 = BASOP_Util_Cmp_Mant32Exp( const_comp1, exp1, fWeight_fx, exp_pow ); + IF( NE_16( Flag2, 1 ) ) + { + fWeight_fx = const_comp1; + move32(); + exp_pow = exp1; + move16(); + } + Flag3 = BASOP_Util_Cmp_Mant32Exp( fMaxWeight_fx, fMaxWeight_exp, fWeight_fx, exp_pow ); + IF( NE_16( Flag3, 1 ) ) + { + fMaxWeight_fx = fWeight_fx; + move32(); + fMaxWeight_exp = exp_pow; + move16(); + } #ifdef APPLY_TEMPORAL_SMOOTHING if ( k > 0 ) { @@ -259,228 +402,303 @@ static void ComputeBandEnergy( fEnergy = ( fEnergy > fSmoothEnergy ) ? fEnergy : fSmoothEnergy; } #endif - fEnergy = 10.0f * log10f( fEnergy ); - ppfBandEnergydB[k][iChanOffset + b] = fEnergy; + ppfWeight_man[k][iChanOffset + b] = fWeight_fx; + ppfWeight_exp[k][iChanOffset + b] = exp_pow; + ppfBandEnergydB_fx[k][iChanOffset + b] = fEnergy_log_fx1; // Q23 } - for ( b = 0; b < iNumBands; b++ ) + FOR( b = 0; b < iNumBands; b++ ) { - ppfWeight[k][iChanOffset + b] /= fMaxWeight; + ppfWeight_man[k][iChanOffset + b] = L_deposit_h( BASOP_Util_Divide3232_Scale( ppfWeight_man[k][iChanOffset + b], fMaxWeight_fx, &div_exp ) ); + ppfWeight_exp[k][iChanOffset + b] = div_exp + ppfWeight_exp[k][iChanOffset + b] - fMaxWeight_exp; } } } - + /* fclose( fp ); + fclose( fp1 );*/ return; } - /*-------------------------------------------------------------------* * Function ComputeMergeRMS() * * *-------------------------------------------------------------------*/ - static void ComputeMergeRMS( - const int32_t iNumBands, - const int32_t iStartBlock, - const int32_t iGroupLength, - float **ppfBandEnergy, - float *pfMergedEnergydB, - int32_t *piQRMSEnvelope ) + const Word32 iNumBands, + const Word32 iStartBlock, + const Word32 iGroupLength, + Word32 *pfMergedEnergydB, + Word32 *piQRMSEnvelope, + Word32 **ppfBandEnergy_man, + Word16 **ppfBandEnergy_exp ) { - int32_t b; - float fInvGroupSize = 1.0f / (float) iGroupLength; - - for ( b = 0; b < iNumBands; b++ ) + Word32 b; + /* FILE *fp = fopen( "float_fGroupEnergy.txt","ab+" ); + FILE *fp1 = fopen( "fixed_fGroupEnergy.txt","ab+" );*/ + Word32 constant = 1616142483; // Q29 of(1/log2(10))*10 // Note epsolon was added when computing BandEnergy; + move32(); + Word32 fGroupEnergy32_fx; + + FOR( b = 0; b < iNumBands; b++ ) { - int32_t n; - float fGroupEnergy; - float fRMSEnvelope; - int32_t iQRMSEnvelope; - - fGroupEnergy = 0.0; - for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + Word32 n; + Word32 fGroupEnergy_fx = 0; + move32(); + Word16 fGroupEnergy_exp = 0; + move16(); + Word32 fRMSEnvelope_fx; + Word32 iQRMSEnvelope_fx; + FOR( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) { - fGroupEnergy += ppfBandEnergy[n][b]; + fGroupEnergy_fx = BASOP_Util_Add_Mant32Exp( ppfBandEnergy_man[n][b], ppfBandEnergy_exp[n][b], fGroupEnergy_fx, fGroupEnergy_exp, &fGroupEnergy_exp ); } - fGroupEnergy *= fInvGroupSize; - - fRMSEnvelope = log2f( fGroupEnergy ); - iQRMSEnvelope = ( fRMSEnvelope > 0.0 ) ? (int32_t) ( fRMSEnvelope + 0.5 ) : (int32_t) ( fRMSEnvelope - 0.5 ); - - fGroupEnergy = 10.0f * log10f( fGroupEnergy ); /* Note epsilon was added when computing BandEnergy;*/ + fGroupEnergy_fx = Mpy_32_32( fGroupEnergy_fx, Inv_grp_length[iGroupLength] ); // Division by iGroupLength + move32(); + IF( NE_32( fGroupEnergy_fx, 0 ) ) + { + fRMSEnvelope_fx = BASOP_Util_Log2( fGroupEnergy_fx ); + move32(); + fRMSEnvelope_fx = L_add( fRMSEnvelope_fx, L_shl( L_deposit_l( fGroupEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/ + } + ELSE + { + fRMSEnvelope_fx = 0; + fGroupEnergy_exp = 0; + } + iQRMSEnvelope_fx = ( fRMSEnvelope_fx > 0 ) ? L_add( fRMSEnvelope_fx, ONE_IN_Q24 ) : L_negate( L_add( L_negate( fRMSEnvelope_fx ), ONE_IN_Q24 ) ); + iQRMSEnvelope_fx = L_shr( iQRMSEnvelope_fx, 25 ); - pfMergedEnergydB[b] = fGroupEnergy; - piQRMSEnvelope[b] = iQRMSEnvelope; + fGroupEnergy32_fx = fRMSEnvelope_fx; /*Q25*/ // BASOP_Util_Log2( fGroupEnergy_fx ); + fGroupEnergy32_fx = Mpy_32_32( fGroupEnergy32_fx, constant ); // Q23 + pfMergedEnergydB[b] = fGroupEnergy32_fx; // Q23 + piQRMSEnvelope[b] = iQRMSEnvelope_fx; // Q25 } - return; } - - /*-------------------------------------------------------------------* * Function ComputeRMSEnvelopeBits() * * *-------------------------------------------------------------------*/ - -static int32_t ComputeRMSEnvelopeBits( - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piQRMSEnevelope ) +static Word32 ComputeRMSEnvelopeBits( + const Word32 iChannels, + const Word32 iNumBands, + const Word32 *piQRMSEnevelope ) { - int32_t n; - int32_t iRMSEnvelopeBits = 0; - int32_t iChanOffset = 0; + Word32 n; + Word32 iRMSEnvelopeBits = 0; + move32(); + Word32 iChanOffset = 0; + move32(); - for ( n = 0; n < iChannels; n++ ) + FOR( n = 0; n < iChannels; n++ ) { - int32_t b; - int32_t iLastRMSVal; + Word32 b; + Word32 iLastRMSVal; - iRMSEnvelopeBits += ENV0_BITS; + iRMSEnvelopeBits = L_add( iRMSEnvelopeBits, ENV0_BITS ); iLastRMSVal = piQRMSEnevelope[iChanOffset]; - for ( b = 1; b < iNumBands; b++ ) + move32(); + FOR( b = 1; b < iNumBands; b++ ) { - int32_t iDelta; + Word32 iDelta; - iDelta = piQRMSEnevelope[iChanOffset + b] - iLastRMSVal; + iDelta = L_sub( piQRMSEnevelope[iChanOffset + b], iLastRMSVal ); iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN; iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX; - iDelta -= ENV_DELTA_MIN; - iRMSEnvelopeBits += c_aaiRMSEnvHuffEnc[iDelta][0]; + iDelta = L_sub( iDelta, ENV_DELTA_MIN ); + iRMSEnvelopeBits = L_add( iRMSEnvelopeBits, c_aaiRMSEnvHuffEnc[iDelta][0] ); iLastRMSVal = piQRMSEnevelope[iChanOffset + b]; + move32(); } - iChanOffset += iNumBands; + iChanOffset = L_add( iChanOffset, iNumBands ); } return iRMSEnvelopeBits; } - - /*-------------------------------------------------------------------* * Function ComputeSNRPenalty() * * *-------------------------------------------------------------------*/ - -static float ComputeSNRPenalty( - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piBandwidths, - const int32_t iStartBlock, - const int32_t iGroupLength, - float **ppfBandEnergydB, - const int32_t *piRMSEnvelope ) +static Word32 ComputeSNRPenalty( + const Word32 iChannels, + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 iStartBlock, + const Word32 iGroupLength, + Word32 **ppfBandEnergy_dB_fx, + const Word32 *piRMSEnvelope, + Word16 *fSNRPenalty_exp ) { - int32_t n; - int32_t iChanOffset; - float fSNRPenalty = 0.0; - + Word32 n; + Word32 iChanOffset; + Word32 temp; + Word32 fSNRPenalty_fx = 0; + move32(); + Word32 fSNRPenaltyconst_fx = 0; + move32(); + Word32 mul_temp; + Word16 fSNRPenaltycnst_exp = 0, exp = 0; + /*FILE *fp = fopen( "float_SNRpenalty.txt", "ab+" ); + FILE *fp1 = fopen( "fixed_SNRpenalty.txt", "ab+" );*/ + // f2me( 1e10f, &fSNRPenaltyconst_fx, &fSNRPenaltycnst_exp );// + /*For 1e10f*/ + fSNRPenaltyconst_fx = 1250000000; + fSNRPenaltycnst_exp = 34; iChanOffset = 0; - for ( n = 0; n < iChannels; n++ ) + move32(); + FOR( n = 0; n < iChannels; n++ ) { - int32_t b; - for ( b = 0; b < iNumBands; b++ ) + Word32 b; + FOR( b = 0; b < iNumBands; b++ ) { - int32_t k; - float fRMSVal; - - fRMSVal = 3.0103f * (float) piRMSEnvelope[iChanOffset + b]; - - for ( k = iStartBlock; k < ( iStartBlock + iGroupLength ); k++ ) + Word32 k; + Word32 fRMSVal_fx; + Word32 RMS_value_fx; + // RMS_value = piRMSEnvelope[iChanOffset + b]; + RMS_value_fx = L_shl( piRMSEnvelope[iChanOffset + b], 25 ); + move32(); + // fRMSVal = 3.0103f * (float) RMS_value; + fRMSVal_fx = Mpy_32_32( 1616142506, RMS_value_fx ); // Q23 + move32(); + FOR( k = iStartBlock; k < ( iStartBlock + iGroupLength ); k++ ) { - float fDeltadB; - - fDeltadB = fRMSVal - ppfBandEnergydB[k][iChanOffset + b]; - if ( fDeltadB < -9.0309f ) + Word32 fDeltadB_fx; + fDeltadB_fx = L_sub( fRMSVal_fx, ppfBandEnergy_dB_fx[k][iChanOffset + b] ); + IF( LT_32( fDeltadB_fx, -75756680 ) ) { - fSNRPenalty += 1e10f; /* Some large number to prevent clipping*/ + fSNRPenalty_fx = BASOP_Util_Add_Mant32Exp( fSNRPenalty_fx, *fSNRPenalty_exp, fSNRPenaltyconst_fx, fSNRPenaltycnst_exp, fSNRPenalty_exp ); // Some large number to prevent clipping } - else /*if(fDeltadB < 0.0)*/ + ELSE { - fSNRPenalty += fabsf( c_fiDefaultTheta48[b] * fDeltadB - fDeltadB ) * 2.0f * (float) piBandwidths[b] / 6.0f; + mul_temp = L_abs( L_sub( Mpy_32_32( c_fiDefaultTheta48_fx[b], fDeltadB_fx ), fDeltadB_fx ) ); + temp = Mpy_32_32( mul_temp, Mpy_32_32( 715827883, L_shl( piBandwidths[b], 27 ) ) ); // Q27+23 -31=19 + exp = Q12; // Q31 - Q19 + fSNRPenalty_fx = BASOP_Util_Add_Mant32Exp( fSNRPenalty_fx, *fSNRPenalty_exp, temp, exp, fSNRPenalty_exp ); } } } - iChanOffset += iNumBands; + iChanOffset = L_add( iChanOffset, iNumBands ); } - - return fSNRPenalty; + // fprintf( fp,"%f\n", fSNRPenalty ); + // fprintf( fp1,"%f\n", fSNRPenalty ); + /* fclose( fp ); + fclose( fp1 );*/ + return fSNRPenalty_fx; } - - /*-------------------------------------------------------------------* * Function TryMerge2() * * *-------------------------------------------------------------------*/ - -static float TryMerge2( - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piBandwidths, - float **ppfBandEnergy, - float **ppfBandEnergydB, +static Word32 TryMerge2( + const Word32 iChannels, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 **ppfBandEnergy_man, + Word16 **ppfBandEnergy_exp, + Word32 **ppfBandEnergydB_fx, GMNode *psGMNode1, - GMNode *psGMNode2 ) + GMNode *psGMNode2, + Word16 *fMergedCost_exp ) { - int32_t iRMSEnvBits1; - int32_t iRMSEnvBits2; - int32_t iRMSEnvBitsMerged; - float fSNRPenalty1; - float fSNRPenalty2; - float fSNRPenaltyMerged; - float fMergedCost = 0.0; - + Word32 iRMSEnvBits1; + Word32 iRMSEnvBits2; + Word32 iRMSEnvBitsMerged; + Word32 temp = 0; + move32(); + Word16 temp_exp = 0; + move16(); + Word32 fMergedCost_fx = 0; + move32(); + Word32 RMSEnvBits_fx; + Word32 fSNRPenalty1_fx; + Word32 fSNRPenalty2_fx; + Word32 fSNRPenaltyMerged_fx; + Word16 fSNRPenalty1_exp = 0; + move16(); + Word16 fSNRPenalty2_exp = 0; + move16(); + Word16 fSNRPenaltyMerged_exp = 0; + move16(); + Word32 one_in_mant = L_negate( ONE_IN_Q30 ); + Word16 one_in_exp = 1; + move16(); + *fMergedCost_exp = 0; + move16(); + Word16 flag = 0; + move16(); + IF( EQ_32( psGMNode1->fGroupSNRPenalty_fx, one_in_mant ) && EQ_16( psGMNode1->fGroupSNRPenalty_exp, one_in_exp ) ) + { + flag = 1; + move16(); + } /* First compute current RMS Envelope for each group */ - if ( psGMNode1->iGroupRMSEnvelopeCost == -1 || psGMNode1->fGroupSNRPenalty == -1.0 ) + IF( EQ_32( psGMNode1->iGroupRMSEnvelopeCost, -1 ) || flag ) { - ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope ); - + ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength, psGMNode1->pfMergedEnergydB_fx, psGMNode1->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp ); iRMSEnvBits1 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); - - fSNRPenalty1 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergydB, psGMNode1->piQRMSEnvelope ); - + fSNRPenalty1_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergydB_fx, psGMNode1->piQRMSEnvelope, &fSNRPenalty1_exp ); psGMNode1->iGroupRMSEnvelopeCost = iRMSEnvBits1; - psGMNode1->fGroupSNRPenalty = fSNRPenalty1; + move32(); + psGMNode1->fGroupSNRPenalty_fx = fSNRPenalty1_fx; + move32(); + psGMNode1->fGroupSNRPenalty_exp = fSNRPenalty1_exp; + move16(); } - else + ELSE { iRMSEnvBits1 = psGMNode1->iGroupRMSEnvelopeCost; - fSNRPenalty1 = psGMNode1->fGroupSNRPenalty; + move32(); + fSNRPenalty1_fx = psGMNode1->fGroupSNRPenalty_fx; + move32(); + fSNRPenalty1_exp = psGMNode1->fGroupSNRPenalty_exp; + move16(); } - - if ( psGMNode2->iGroupRMSEnvelopeCost == -1 || psGMNode2->fGroupSNRPenalty == -1.0 ) + IF( EQ_32( psGMNode2->fGroupSNRPenalty_fx, one_in_mant ) && EQ_16( psGMNode2->fGroupSNRPenalty_exp, one_in_exp ) ) + { + flag = 1; + move16(); + } + IF( EQ_32( psGMNode2->iGroupRMSEnvelopeCost, -1 ) || flag ) { - ComputeMergeRMS( iNumBands * iChannels, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergy, psGMNode2->pfMergedEnergydB, psGMNode2->piQRMSEnvelope ); + ComputeMergeRMS( iNumBands * iChannels, psGMNode2->iGroupStart, psGMNode2->iGroupLength, psGMNode2->pfMergedEnergydB_fx, psGMNode2->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp ); iRMSEnvBits2 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode2->piQRMSEnvelope ); - - fSNRPenalty2 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergydB, psGMNode2->piQRMSEnvelope ); - + fSNRPenalty2_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergydB_fx, psGMNode2->piQRMSEnvelope, &fSNRPenalty2_exp ); psGMNode2->iGroupRMSEnvelopeCost = iRMSEnvBits2; - psGMNode2->fGroupSNRPenalty = fSNRPenalty2; + move32(); + psGMNode2->fGroupSNRPenalty_fx = fSNRPenalty2_fx; + move32(); + psGMNode2->fGroupSNRPenalty_exp = fSNRPenalty2_exp; + move16(); } - else + ELSE { iRMSEnvBits2 = psGMNode2->iGroupRMSEnvelopeCost; - fSNRPenalty2 = psGMNode2->fGroupSNRPenalty; + move32(); + fSNRPenalty2_fx = psGMNode2->fGroupSNRPenalty_fx; + move32(); + fSNRPenalty2_exp = psGMNode2->fGroupSNRPenalty_exp; + move16(); } - - /* Compute the merged group */ - ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope ); + ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, psGMNode1->pfMergedEnergydB_fx, psGMNode1->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp ); /* Compute the RMS Envelope cost for merged group */ iRMSEnvBitsMerged = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); - + // fSNRPenalty_exp = 0; /* Compute an approximation of the bit cost based on SNR increase/decrease due to merging */ - fSNRPenaltyMerged = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergydB, psGMNode1->piQRMSEnvelope ); - - fMergedCost = fSNRPenaltyMerged - fSNRPenalty1 - fSNRPenalty2 + (float) iRMSEnvBitsMerged - (float) iRMSEnvBits1 - (float) iRMSEnvBits2; - - return fMergedCost; + fSNRPenaltyMerged_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergydB_fx, psGMNode1->piQRMSEnvelope, &fSNRPenaltyMerged_exp ); + RMSEnvBits_fx = L_sub( L_sub( iRMSEnvBitsMerged, iRMSEnvBits1 ), iRMSEnvBits2 ); + RMSEnvBits_fx = L_shl( RMSEnvBits_fx, 10 ); // Converting to Q10 + temp = BASOP_Util_Add_Mant32Exp( fSNRPenaltyMerged_fx, fSNRPenaltyMerged_exp, L_negate( fSNRPenalty1_fx ), fSNRPenalty1_exp, &temp_exp ); + fMergedCost_fx = BASOP_Util_Add_Mant32Exp( temp, temp_exp, L_negate( fSNRPenalty2_fx ), fSNRPenalty2_exp, fMergedCost_exp ); + fMergedCost_fx = BASOP_Util_Add_Mant32Exp( fMergedCost_fx, *fMergedCost_exp, RMSEnvBits_fx, 21, fMergedCost_exp ); + // fMergedCost = fSNRPenaltyMerged - fSNRPenalty1 - fSNRPenalty2 + (float) iRMSEnvBitsMerged - (float) iRMSEnvBits1 - (float) iRMSEnvBits2; + return fMergedCost_fx; } /*-------------------------------------------------------------------* @@ -488,7 +706,6 @@ static float TryMerge2( * * *-------------------------------------------------------------------*/ - static void ComputeGreedyGroups3( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, const int32_t iChannels, @@ -497,226 +714,264 @@ static void ComputeGreedyGroups3( const int32_t iMaxGroups ) { - int32_t iDone = 0; - int32_t iNumGroups = psRMSEnvelopeGrouping->iMaxGroups; - - while ( iDone == 0 ) + Word32 iDone = 0; + Word32 iNumGroups = psRMSEnvelopeGrouping->iMaxGroups; + WHILE( EQ_32( iDone, 0 ) ) { GMNode *psGMNode; GMNode *psBestGMNode; - float fBestMergeCost; - - fBestMergeCost = 1e20f; + /* Instead of 1e20f*/ + Word32 fBestMergeCost_fx = 1455191552; // mantissa of 1e20f + move32(); + Word16 fBestMergeCost_exp = 67; // exp of 1e20f + move16(); + Word16 Flag = 0; + move16(); psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; psBestGMNode = NULL; - while ( psGMNode->psNext != NULL ) + WHILE( psGMNode->psNext != NULL ) { - float fMergeCost; - - fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext ); + Word32 fMergeCost_fx = 0; + move32(); + Word16 fMergeCost_exp = 0; + move16(); + fMergeCost_fx = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, psRMSEnvelopeGrouping->ppfBandEnergydB_fx, psGMNode, psGMNode->psNext, &fMergeCost_exp ); + IF( LT_32( fMergeCost_fx, 0 ) && ( GT_32( fBestMergeCost_fx, 0 ) ) ) + { - if ( fMergeCost < fBestMergeCost ) + Flag = 1; + move16(); + } + ELSE IF( ( GT_32( fMergeCost_fx, 0 ) && ( LT_32( fBestMergeCost_fx, 0 ) ) ) ) { - fBestMergeCost = fMergeCost; + Flag = -1; + move16(); + } + ELSE + { + Flag = BASOP_Util_Cmp_Mant32Exp( fBestMergeCost_fx, fBestMergeCost_exp, fMergeCost_fx, fMergeCost_exp ); + } + IF( EQ_32( Flag, 1 ) ) + { + fBestMergeCost_fx = fMergeCost_fx; + move32(); + fBestMergeCost_exp = fMergeCost_exp; + move16(); psBestGMNode = psGMNode; } psGMNode = psGMNode->psNext; } - if ( fBestMergeCost > 0.0 && iNumGroups <= iMaxGroups ) + IF( ( GT_32( fBestMergeCost_fx, 0 ) && ( LE_32( iNumGroups, iMaxGroups ) ) ) ) { iDone++; } - else if ( psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + ELSE IF( ( psBestGMNode != NULL ) && ( psBestGMNode->psNext != NULL ) ) { - psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; - psBestGMNode->iGroupRMSEnvelopeCost = -1; - psBestGMNode->fGroupSNRPenalty = -1.0; + psBestGMNode->iGroupLength = L_add( psBestGMNode->psNext->iGroupLength, psBestGMNode->iGroupLength ); + psBestGMNode->fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 ); + psBestGMNode->fGroupSNRPenalty_exp = 1; + move16(); psBestGMNode->psNext = psBestGMNode->psNext->psNext; iNumGroups--; } - else + ELSE { - iDone++; /* This only catches a problem*/ + iDone++; // This only catches a problem } } - return; } - - /*-------------------------------------------------------------------* * Function ComputeRMSEnvelope() * * *-------------------------------------------------------------------*/ - static void ComputeRMSEnvelope( - const int32_t iChannels, - const int32_t iNumBands, - const int32_t iNumGroups, - const int32_t *piGroupLengths, - float **ppfBandEnergy, - int32_t ***pppiRMSEnvelope ) + const Word32 iChannels, + const Word32 iNumBands, + const Word32 iNumGroups, + const Word32 *piGroupLengths, + Word32 **ppfBandEnergy_man, + Word16 **ppfBandEnergy_exp, + Word32 ***pppiRMSEnvelope ) { - int32_t n; - - for ( n = 0; n < iChannels; n++ ) + Word32 n; + Word32 fGroupEnergy_fx; + Word16 fGroupEnergy_exp; + Word32 temp; + // FILE *fp = fopen( "RmsEnvelope_fixed", "ab+" ); + // FILE *fp1 = fopen( "RmsEnvelope_float", "ab+" ); + FOR( n = 0; n < iChannels; n++ ) { - int32_t b; - int32_t iChanOffset; + Word32 b; + Word32 iChanOffset; - iChanOffset = n * iNumBands; - for ( b = 0; b < iNumBands; b++ ) - { - int32_t k; - int32_t iBlockOffset; + iChanOffset = L_mult0( extract_l( n ), extract_l( iNumBands ) ); + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 k; + Word32 iBlockOffset; iBlockOffset = 0; - for ( k = 0; k < iNumGroups; k++ ) + FOR( k = 0; k < iNumGroups; k++ ) { - int32_t m; - float fGroupEnergy; - fGroupEnergy = 0.0; - for ( m = 0; m < piGroupLengths[k]; m++ ) + Word32 m; + fGroupEnergy_exp = 0; + move16(); + fGroupEnergy_fx = 0; + move32(); + FOR( m = 0; m < piGroupLengths[k]; m++ ) { - fGroupEnergy += ppfBandEnergy[iBlockOffset][b + iChanOffset]; + fGroupEnergy_fx = BASOP_Util_Add_Mant32Exp( ppfBandEnergy_man[iBlockOffset][b + iChanOffset], ppfBandEnergy_exp[iBlockOffset][b + iChanOffset], fGroupEnergy_fx, fGroupEnergy_exp, &fGroupEnergy_exp ); iBlockOffset++; } - fGroupEnergy /= (float) piGroupLengths[k]; - - fGroupEnergy = log2f( fGroupEnergy ); - pppiRMSEnvelope[n][k][b] = ( fGroupEnergy > 0.0 ) ? (int32_t) ( fGroupEnergy + 0.5 ) : (int32_t) ( fGroupEnergy - 0.5 ); - pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] > ENV_MIN ) ? pppiRMSEnvelope[n][k][b] : ENV_MIN; - pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] < ENV_MAX ) ? pppiRMSEnvelope[n][k][b] : ENV_MAX; + fGroupEnergy_fx = Mpy_32_32( fGroupEnergy_fx, Inv_grp_length[piGroupLengths[k]] ); // Division by iGroupLength + fGroupEnergy_fx = BASOP_Util_Log2( fGroupEnergy_fx ); + move32(); + fGroupEnergy_fx = L_add( fGroupEnergy_fx, L_shl( L_deposit_l( fGroupEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/ + temp = ( fGroupEnergy_fx > 0 ) ? L_add( fGroupEnergy_fx, ONE_IN_Q24 ) : L_negate( L_add( L_negate( fGroupEnergy_fx ), ONE_IN_Q24 ) ); // Q25 + temp = L_shr( temp, 25 ); + temp = ( temp > ENV_MIN ) ? temp : ENV_MIN; + temp = ( temp < ENV_MAX ) ? temp : ENV_MAX; + pppiRMSEnvelope[n][k][b] = temp; + // fprintf( fp,"%d\n", pppiRMSEnvelope[n][k][b] ); } } } - + // fclose( fp ); + /* fclose( fp1 );*/ return; } - /*-------------------------------------------------------------------* * Function LimitRMSEnvelope() * * *-------------------------------------------------------------------*/ - static void LimitRMSEnvelope( - const int32_t iBandCount, - const int32_t iRMSDeltaMax, - const int32_t iRMSDeltaMin, - int32_t *piRMSEnvelope ) + const Word32 iBandCount, + const Word32 iRMSDeltaMax, + const Word32 iRMSDeltaMin, + Word32 *piRMSEnvelope ) { - int32_t iBand; - int32_t iLastSCF; + Word32 iBand; + Word32 iLastSCF; /* Increase low envelope values to ensure that the scale factors traces the large values correctly (checking for max deltas) */ iLastSCF = piRMSEnvelope[iBandCount - 1]; + move32(); for ( iBand = iBandCount - 2; iBand > -1; iBand-- ) { - int32_t iDelta; + Word32 iDelta; - iDelta = iLastSCF - piRMSEnvelope[iBand]; + iDelta = L_sub( iLastSCF, piRMSEnvelope[iBand] ); - if ( iDelta > iRMSDeltaMax ) + IF( GT_32( iDelta, iRMSDeltaMax ) ) { #ifdef DEBUG_VERBOSE printf( "WARNING RMS envelope delta limited\n" ); #endif - piRMSEnvelope[iBand] += ( iDelta - iRMSDeltaMax ); + piRMSEnvelope[iBand] = L_add( L_sub( iDelta, iRMSDeltaMax ), piRMSEnvelope[iBand] ); } iLastSCF = piRMSEnvelope[iBand]; + move32(); } /* Increase low envelope values to ensure that the envelope traces the large values correctly (checking for min deltas)*/ iLastSCF = piRMSEnvelope[0]; - for ( iBand = 1; iBand < iBandCount; iBand++ ) + FOR( iBand = 1; iBand < iBandCount; iBand++ ) { - int32_t iDelta; + Word32 iDelta; - iDelta = piRMSEnvelope[iBand] - iLastSCF; + iDelta = L_sub( piRMSEnvelope[iBand], iLastSCF ); - if ( iDelta < iRMSDeltaMin ) + IF( LT_32( iDelta, iRMSDeltaMin ) ) { #ifdef DEBUG_VERBOSE printf( "WARNING RMS envelope delta limited\n" ); #endif - piRMSEnvelope[iBand] += ( iRMSDeltaMin - iDelta ); + piRMSEnvelope[iBand] = L_add( piRMSEnvelope[iBand], L_sub( iRMSDeltaMin, iDelta ) ); } iLastSCF = piRMSEnvelope[iBand]; + move32(); } return; } - /*-------------------------------------------------------------------* * Function ComputeEnvelopeGrouping() * * *-------------------------------------------------------------------*/ - void ComputeEnvelopeGrouping( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piBandwidths, - float ***pppfReal, - float ***pppfImag, - int32_t *piNumGroups, - int32_t *piGroupLengths, - int32_t ***pppiRMSEnvelope ) + const Word32 iChannels, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + Word32 *piNumGroups, + Word32 *piGroupLengths, + Word32 ***pppiRMSEnvelope, + Word16 q_final ) { - int32_t n; + Word32 n; GMNode *psGMNode; /* Compute Band Energies */ - ComputeBandEnergy( iChannels, psRMSEnvelopeGrouping->iNumBlocks, iNumBands, piBandwidths, pppfReal, pppfImag, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psRMSEnvelopeGrouping->ppfWeight ); - + ComputeBandEnergy( iChannels, psRMSEnvelopeGrouping->iNumBlocks, iNumBands, piBandwidths, pppfReal_fx, pppfImag_fx, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, psRMSEnvelopeGrouping->ppfBandEnergydB_fx, psRMSEnvelopeGrouping->ppfWeight_man, psRMSEnvelopeGrouping->ppfWeight_exp, q_final ); /* Init GMNodes */ psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0; + move32(); psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 2; + move32(); psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL; psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1; - psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty = -1.0f; - - for ( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ ) + move32(); + psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 ); + psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty_exp = 1; + move16(); + FOR( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ ) { psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n]; - psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = n * 2; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = L_shl( n, 1 ); + move32(); psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 2; + move32(); psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; - psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + move32(); + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 ); + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_exp = 1; + move16(); psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL; } - /* Perform grouping via Greedy Merge */ /* Allows control over max groups can call using 16 if want same as previous call */ ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->iNumBlocks ); - /* Calc Groups from Merge Results */ *piNumGroups = 0; + move32(); psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; - while ( psGMNode != NULL ) + WHILE( psGMNode != NULL ) { piGroupLengths[*piNumGroups] = psGMNode->iGroupLength; - *piNumGroups += 1; + move32(); + *piNumGroups = L_add( *piNumGroups, 1 ); psGMNode = psGMNode->psNext; } - /* Compute RMS Envelope given group lengths */ - ComputeRMSEnvelope( iChannels, iNumBands, *piNumGroups, piGroupLengths, psRMSEnvelopeGrouping->ppfBandEnergy, pppiRMSEnvelope ); + ComputeRMSEnvelope( iChannels, iNumBands, *piNumGroups, piGroupLengths, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, pppiRMSEnvelope ); /* Envelope Tenting */ - for ( n = 0; n < iChannels; n++ ) + FOR( n = 0; n < iChannels; n++ ) { - int32_t k; - for ( k = 0; k < *piNumGroups; k++ ) + Word32 k; + FOR( k = 0; k < *piNumGroups; k++ ) { LimitRMSEnvelope( iNumBands, ENV_DELTA_MAX, ENV_DELTA_MIN, pppiRMSEnvelope[n][k] ); } diff --git a/lib_isar/isar_cnst.h b/lib_isar/isar_cnst.h index e54fcd0ea..72ff5b892 100644 --- a/lib_isar/isar_cnst.h +++ b/lib_isar/isar_cnst.h @@ -70,6 +70,7 @@ typedef enum #define SPLIT_REND_MAX_ROLL_ONLY_POSES 2 #define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2 #define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ +#define MAX_EXTRAPOLATION_ANGLE_Q22 (62914560) /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ #define MAX_HEAD_ROT_POSES ( 2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES ) #define MAX_SPLIT_REND_MD_BANDS 20 @@ -83,6 +84,14 @@ typedef enum #endif #define SPLIT_REND_RO_MD_BAND_THRESH 4 +#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS_LOG2_CEIL 6 +#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS_LOG2_CEIL 5 +#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS_LOG2_CEIL 5 +#define ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL 4 + +#define ISAR_SPLIT_REND_PRED_MIN_VAL_Q30 -1503238553 //Q30 +#define ISAR_SPLIT_REND_PRED_MAX_VAL_Q30 1503238553 //Q30 + #define ISAR_SPLIT_REND_NUM_QUANT_STRATS 4 #define ISAR_SPLIT_REND_PRED_63QUANT_PNTS 63 #define ISAR_SPLIT_REND_PRED_31QUANT_PNTS 31 @@ -93,21 +102,37 @@ typedef enum #define ISAR_SPLIT_REND_PITCH_G_MIN_VAL 0.5f #define ISAR_SPLIT_REND_PITCH_G_MAX_VAL 1.5f +#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30 (1<<29) //0.5f in Q30 +#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30 1610612736 //1.5f in Q30 #define ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS ISAR_SPLIT_REND_D_QUANT_PNTS #define ISAR_SPLIT_REND_D_MIN_VAL 0.0f #define ISAR_SPLIT_REND_D_MAX_VAL 1.0f +#define ISAR_SPLIT_REND_D_MIN_VAL_FX 0 //Q31 +#define ISAR_SPLIT_REND_D_MAX_VAL_FX MAX_32 //Q31 #define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 200431807 +#define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26 719023543 #define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ( ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) #define ISAR_SPLIT_REND_PRED31_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) ) #define ISAR_SPLIT_REND_PRED31_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) #define ISAR_SPLIT_REND_PRED63_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) ) #define ISAR_SPLIT_REND_PRED63_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PRED31_Q_STEP_FX_Q31 200431807 +#define ISAR_SPLIT_REND_PRED31_1BYQ_STEP_FX_Q26 719023543 +#define ISAR_SPLIT_REND_PRED63_Q_STEP_FX_Q31 96983132 +#define ISAR_SPLIT_REND_PRED63_1BYQ_STEP_FX_Q26 1485981989 + #define ISAR_SPLIT_REND_D_Q_STEP ( ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) / ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) ) #define ISAR_SPLIT_REND_D_1BYQ_STEP ( ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) ) #define ISAR_SPLIT_REND_PITCH_G_Q_STEP ( ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) / ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) ) #define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP ( ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ) +#define ISAR_SPLIT_REND_D_Q_STEP_Q31 153391689 +#define ISAR_SPLIT_REND_D_1BYQ_STEP_Q27 (14 << 27) //Q27 +#define ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31 153391689 +#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27 (14 << 27) //Q27 + #define ISAR_SPLIT_REND_HEAD_POSE_BITS 9 #define ISAR_SPLIT_REND_DOF_BITS 2 @@ -118,7 +143,6 @@ typedef enum #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS #define IVAS_LC3PLUS_MAX_NUM_DECODERS 2 #endif - /*----------------------------------------------------------------------------------* * Split rendering bitrate constants *----------------------------------------------------------------------------------*/ diff --git a/lib_isar/isar_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c index 77cd4da21..1c63158b3 100644 --- a/lib_isar/isar_lc3plus_dec.c +++ b/lib_isar/isar_lc3plus_dec.c @@ -77,6 +77,7 @@ ivas_error ISAR_LC3PLUS_DEC_Open( { LC3PLUS_Error err; int32_t decoder_size; + Word32 scratch_size; #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS int16_t i; @@ -153,7 +154,7 @@ ivas_error ISAR_LC3PLUS_DEC_Open( ( *handle )->bitstream_caches[iCh] = NULL; } /* allocate and configure LC3plus decoder */ - decoder_size = lc3plus_dec_get_size( config.samplerate, 1 ); + decoder_size = lc3plus_dec_get_size( config.samplerate, 1, LC3PLUS_PLC_ADVANCED ); if ( 0 == decoder_size ) { ISAR_LC3PLUS_DEC_Close( handle ); @@ -242,6 +243,13 @@ ivas_error ISAR_LC3PLUS_DEC_Open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" ); } + scratch_size = lc3plus_dec_get_scratch_size( ( *handle )->handles[0] ); + if ( ( ( *handle )->scratch = malloc( sizeof( uint8_t ) * scratch_size ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper scratch\n" ); + } + return IVAS_ERR_OK; } @@ -458,7 +466,6 @@ void ISAR_LC3PLUS_DEC_Close( { if ( NULL != ( *handle )->handles && NULL != ( *handle )->handles[iDec] ) { - lc3plus_free_decoder_structs( ( *handle )->handles[iDec] ); free( ( *handle )->handles[iDec] ); } @@ -481,6 +488,11 @@ void ISAR_LC3PLUS_DEC_Close( { free( ( *handle )->pcm_conversion_buffer ); } + if ( NULL != ( *handle )->scratch ) + { + free( ( *handle )->scratch ); + } + free( ( *handle )->handles ); if ( NULL != ( *handle )->bitstream_caches ) @@ -507,12 +519,13 @@ static ivas_error decode_or_conceal_one_lc3plus_frame( uint8_t *bitstream_in, const int32_t bitstream_in_length, int16_t **pcm_out_buffer, - const int32_t badFrameIndicator ) + const int32_t badFrameIndicator, + uint8_t *scratch ) { LC3PLUS_Error err; push_wmops( "lc3plus_dec16" ); - err = lc3plus_dec16( dec, bitstream_in, bitstream_in_length, pcm_out_buffer, NULL, badFrameIndicator ); + err = lc3plus_dec16( dec, bitstream_in, bitstream_in_length, pcm_out_buffer, scratch, badFrameIndicator ); pop_wmops(); if ( err == LC3PLUS_DECODE_ERROR && 1 == badFrameIndicator ) @@ -541,7 +554,7 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( uint8_t *bitstream_in, /* i : pointer to input bitstream */ int32_t bitstream_in_size, /* i : size of bitstream_in */ const int16_t badFrameIndicator, /* i : bad frame indicator. If set to 1, triggers concealment */ - float **pcm_out /* o : decoded samples */ + Word32 **pcm_out /* o : decoded samples */ ) { uint32_t iDec; @@ -641,7 +654,7 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "LC3plus cache is empty\n" ); } - err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], handle->bitstream_caches[iDec]->bitstream_cache, handle->bitstream_caches[iDec]->bitstream_cache_size, &handle->pcm_conversion_buffer, badFrameIndicator ); + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], handle->bitstream_caches[iDec]->bitstream_cache, handle->bitstream_caches[iDec]->bitstream_cache_size, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch ); if ( err != IVAS_ERR_OK ) { return IVAS_ERROR( err, "lc3plus decoding failed\n" ); @@ -665,7 +678,7 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS case DEC_ACTION_DECODE_AND_DROP: { - err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch ); if ( err != IVAS_ERR_OK ) { return IVAS_ERROR( err, "lc3plus decoding failed\n" ); @@ -679,7 +692,7 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS if ( badFrameIndicator ) { - err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in, bitstream_in_size, &handle->pcm_conversion_buffer, badFrameIndicator ); + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in, bitstream_in_size, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch ); } else if ( payload.ftds[iFtd].frame_data_length == LC3PLUS_RTP_FDL_SPEECH_BAD ) { @@ -689,7 +702,7 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( } else { - err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], payload.ftds[iFtd].frame_data, payload.ftds[iFtd].frame_data_length, &handle->pcm_conversion_buffer, badFrameIndicator ); + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], payload.ftds[iFtd].frame_data, payload.ftds[iFtd].frame_data_length, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch ); } if ( err != IVAS_ERR_OK ) { @@ -699,7 +712,7 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( for ( int16_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) { ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; - pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; + pcm_out[iDec][ivasSampleIndex] = handle->pcm_conversion_buffer[iSampleInt16]; } handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; break; @@ -713,7 +726,7 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( for ( int32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) { ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; - pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; + pcm_out[iDec][ivasSampleIndex] = handle->pcm_conversion_buffer[iSampleInt16]; } handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; break; @@ -789,7 +802,7 @@ ivas_error ISAR_LC3PLUS_DEC_Decode( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ uint8_t *bitstream_in, /* i : pointer to input bitstream */ const int32_t bitstream_in_size, /* i : size of bitstream_in */ - float **pcm_out /* o : decoded samples */ + Word32 **pcm_out /* o : decoded samples */ ) { int16_t badFrameIndicator; @@ -820,7 +833,7 @@ ivas_error ISAR_LC3PLUS_DEC_Decode( ivas_error ISAR_LC3PLUS_DEC_Conceal( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ - float **pcm_out /* o : concealed samples */ + Word32 **pcm_out /* o : decoded samples */ ) { uint8_t bitstream_in[LC3PLUS_MAX_BYTES]; diff --git a/lib_isar/isar_lc3plus_dec.h b/lib_isar/isar_lc3plus_dec.h index 2be6649b9..309ec4e06 100644 --- a/lib_isar/isar_lc3plus_dec.h +++ b/lib_isar/isar_lc3plus_dec.h @@ -86,6 +86,7 @@ typedef struct ISAR_LC3PLUS_DEC_HANDLE ISAR_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches; uint32_t num_decs; int16_t *pcm_conversion_buffer; + uint8_t *scratch; LC3PLUS_CONFIG config; } * ISAR_LC3PLUS_DEC_HANDLE; @@ -115,12 +116,12 @@ ivas_error ISAR_LC3PLUS_DEC_Decode( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ uint8_t *bitstream_in, /* i : pointer to input bitstream */ const int32_t bitstream_in_size, /* i : size of bitstream_in */ - float **pcm_out /* o : decoded samples */ + Word32 **pcm_out /* o : decoded samples */ ); ivas_error ISAR_LC3PLUS_DEC_Conceal( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ - float **pcm_out /* o : concealed samples */ + Word32 **pcm_out /* o : decoded samples */ ); #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS @@ -128,7 +129,7 @@ ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ); -void ISAR_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); +void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); #endif #endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c index 002741040..f6bb0284d 100644 --- a/lib_isar/isar_lc3plus_enc.c +++ b/lib_isar/isar_lc3plus_enc.c @@ -87,10 +87,9 @@ static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config, * * *-------------------------------------------------------------------*/ - ivas_error ISAR_LC3PLUS_ENC_Open( const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */ - const uint32_t bitsPerSecond, /* i : bit rate */ + const UWord32 bitsPerSecond, /* i : bit rate */ ISAR_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ ) { @@ -107,6 +106,7 @@ ivas_error ISAR_LC3PLUS_ENC_Open( #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS int32_t bitsPerSecondPerChannel; #endif + Word32 scratch_size; int32_t encoder_size; LC3PLUS_Error err; int32_t lfeChans[1]; @@ -285,6 +285,14 @@ ivas_error ISAR_LC3PLUS_ENC_Open( } #endif #endif + scratch_size = lc3plus_enc_get_scratch_size( ( *handle )->handles[0] ); + ( *handle )->scratch = malloc( sizeof( uint8_t ) * scratch_size ); + IF( NULL == ( *handle )->scratch ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper scratch\n" ); + } + return IVAS_ERR_OK; } @@ -439,7 +447,7 @@ ivas_error ISAR_LC3PLUS_ENC_GetDelay( ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *bsSize /* o : size of each bitstream frame in bytes */ + Word32 *bsSize /* o : size of each bitstream frame in bytes */ ) { #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS @@ -548,7 +556,6 @@ void ISAR_LC3PLUS_ENC_Close( { if ( NULL != ( *handle )->handles[iEnc] ) { - lc3plus_free_encoder_structs( ( *handle )->handles[iEnc] ); free( ( *handle )->handles[iEnc] ); } } @@ -557,6 +564,11 @@ void ISAR_LC3PLUS_ENC_Close( free( ( *handle )->pcm_conversion_buffer ); } + if ( NULL != ( *handle )->scratch ) + { + free( ( *handle )->scratch ); + } + free( ( *handle )->handles ); free( *handle ); @@ -571,17 +583,16 @@ void ISAR_LC3PLUS_ENC_Close( * * *-------------------------------------------------------------------*/ - ivas_error ISAR_LC3PLUS_ENC_Encode( - ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - float **pcm_in, /* i : pointer input samples */ + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + Word32 **pcm_in, /* i : pointer input samples */ #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS void *bitstream_out, /* o : pointer to bitstream frame */ - const int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ + const Word32 bitstream_out_size, /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ #else void *bitstream_out /* o : pointer to bitstream frame */ #endif -) + Word16 q_in[16] ) { #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS int32_t ftdIndex; @@ -645,7 +656,7 @@ ivas_error ISAR_LC3PLUS_ENC_Encode( #else ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; #endif - handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); + handle->pcm_conversion_buffer[iSampleInt16] = (Word16) max( INT16_MIN, min( L_shr( pcm_in[iEnc][ivasSampleIndex], q_in[iEnc] ), INT16_MAX ) ); } #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS @@ -654,7 +665,7 @@ ivas_error ISAR_LC3PLUS_ENC_Encode( num_bytes = 0; push_wmops( "lc3plus_enc16" ); #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, NULL ); + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, handle->scratch ); #else err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); #endif diff --git a/lib_isar/isar_lc3plus_enc.h b/lib_isar/isar_lc3plus_enc.h index 6fda1cb21..a2bc10bfc 100644 --- a/lib_isar/isar_lc3plus_enc.h +++ b/lib_isar/isar_lc3plus_enc.h @@ -38,6 +38,7 @@ #ifdef SPLIT_REND_WITH_HEAD_ROT #include "lc3.h" #include "isar_lc3plus_common.h" +#include "typedef.h" #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS #include "isar_lc3plus_payload.h" #endif @@ -54,6 +55,7 @@ typedef struct ISAR_LC3PLUS_ENC_HANDLE int32_t num_ftds; LC3PLUS_RTP_FDL fdl_request; #endif + uint8_t *scratch; } * ISAR_LC3PLUS_ENC_HANDLE; ivas_error ISAR_LC3PLUS_ENC_Open( @@ -89,14 +91,14 @@ void ISAR_LC3PLUS_ENC_Close( ivas_error ISAR_LC3PLUS_ENC_Encode( ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - float **pcm_in, /* i : pointer input samples */ + Word32 **pcm_in, /* i : pointer input samples */ #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS void *bitstream_out, /* o : pointer to bitstream frame */ - const int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ + const Word32 bitstream_out_size, /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ #else void *bitstream_out /* o : pointer to bitstream frame */ #endif -); + Word16 q_in[16] ); #endif #endif /* ISAR_LC3PLUS_ENC_H */ diff --git a/lib_isar/isar_lcld_decoder.c b/lib_isar/isar_lcld_decoder.c index 47045ba59..c067ad064 100644 --- a/lib_isar/isar_lcld_decoder.c +++ b/lib_isar/isar_lcld_decoder.c @@ -34,12 +34,16 @@ #include "options.h" #ifdef SPLIT_REND_WITH_HEAD_ROT #include "isar_lcld_prot.h" -#include "isar_rom_lcld_tables.h" +#include "isar_lcld_rom_tables.h" #include "prot.h" #include #include "isar_prot.h" #include "wmc_auto.h" - +#include "basop_util.h" +#include "prot_fx2.h" +// #define DEBUG_WRITE +#include "debug.h" +#include "enh64.h" /*------------------------------------------------------------------------------------------* * Local constants @@ -56,10 +60,11 @@ typedef struct TableNode struct TableNode **ppoNextTable; struct TableNode *poOrderedNext; - int32_t *piCodeIndex; - int32_t *piDifference; - int32_t *piLength; + Word32 *piCodeIndex; + Word32 *piDifference; + Word32 *piLength; } TableNode; + typedef struct TableList { TableNode *poOrderedTop; @@ -69,36 +74,36 @@ typedef struct TableList struct LCLD_DECODER { - int32_t iSampleRate; - int32_t iChannels; - int32_t iNumBlocks; + Word32 iSampleRate; + Word32 iChannels; + Word32 iNumBlocks; - int32_t iNumBands; - const int32_t *piBandwidths; + Word32 iNumBands; + const Word32 *piBandwidths; - int32_t iMSMode; - int32_t *piMSFlags; + Word32 iMSMode; + Word32 *piMSFlags; TableList *ptable_list; - uint32_t ( *c_apauiHuffDecTable_RAM[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE]; - uint32_t num_decode_table[2 * ALLOC_TABLE_SIZE]; - int32_t piMSPredCoefs[MAX_BANDS]; - int32_t piLRPhaseDiffs[MAX_BANDS]; - int32_t iCommonGrouping; - int32_t *piNumGroups; - int32_t **ppiGroupLengths; - - int32_t ***pppiRMSEnvelope; - int32_t ***pppiSMR; - int32_t ***pppiExcitation; - int32_t ***pppiAlloc; - - int32_t iAllocOffset; - int32_t iRealOnlyOut; - - int32_t ***pppiLCLDSignReal; - int32_t ***pppiLCLDSignImag; - int32_t ***pppiQLCLDReal; - int32_t ***pppiQLCLDImag; + UWord32 ( *c_apauiHuffDecTable_RAM[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE]; + UWord32 num_decode_table[2 * ALLOC_TABLE_SIZE]; + Word32 piMSPredCoefs[MAX_BANDS]; + Word32 piLRPhaseDiffs[MAX_BANDS]; + Word32 iCommonGrouping; + Word32 *piNumGroups; + Word32 **ppiGroupLengths; + + Word32 ***pppiRMSEnvelope; + Word32 ***pppiSMR; + Word32 ***pppiExcitation; + Word32 ***pppiAlloc; + + Word32 iAllocOffset; + Word32 iRealOnlyOut; + + Word32 ***pppiLCLDSignReal; + Word32 ***pppiLCLDSignImag; + Word32 ***pppiQLCLDReal; + Word32 ***pppiQLCLDImag; PredictionDecoder *psPredictionDecoder; @@ -106,229 +111,261 @@ struct LCLD_DECODER NoiseGen *psNoiseGen; }; -static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, const int32_t num, const uint16_t ( *ppuiEncTable )[2], const int32_t iSize, const int32_t iReadLength, uint32_t *iTables ); -static TableNode *CreateTableList( const int32_t iReadLength ); -static void DeleteTableList( TableList *ptable_list, int32_t iTables ); -static TableNode *GetNextTable( const int32_t iIndex, TableList *table_list, TableNode *poParent, const int32_t iReadLength, uint32_t *iTablesCreated ); -static void AddcodeTableList( TableList *ptable_list, const int32_t iLength, const int32_t iCode, const int32_t iCodeIndex, const int32_t iReadLength, uint32_t *iTables ); -static void CompleteTables( LCLDDecoder *psLCLDDecoder, const int32_t n, TableList *ptable_list, const int32_t iReadLength, const int32_t iTablesCreated ); +static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, Word32 num, const UWord16 ( *ppuiEncTable )[2], Word32 iSize, Word32 iReadLength, UWord32 *iTables ); +static TableNode *CreateTableList( Word32 iReadLength ); +static void DeleteTableList( TableList *ptable_list, Word32 iTables ); +static TableNode *GetNextTable( Word32 iIndex, TableList *table_list, TableNode *poParent, Word32 iReadLength, UWord32 *iTablesCreated ); +static void AddcodeTableList( TableList *ptable_list, Word32 iLength, Word32 iCode, Word32 iCodeIndex, Word32 iReadLength, UWord32 *iTables ); +static void CompleteTables( LCLDDecoder *psLCLDDecoder, Word32 n, TableList *ptable_list, Word32 iReadLength, Word32 iTablesCreated ); -static TableNode *CreateTableList( const int32_t iReadLength ) +static TableNode *CreateTableList( Word32 iReadLength ) { - int32_t n; - int32_t iMaxTables; + Word32 n; + Word32 iMaxTables; TableNode *ptable_top; - iMaxTables = 1 << iReadLength; + iMaxTables = L_shl( 1, (Word16) iReadLength ); ptable_top = (TableNode *) malloc( sizeof( TableNode ) ); ptable_top->ppoNextTable = (TableNode **) malloc( iMaxTables * sizeof( TableNode * ) ); - ptable_top->piCodeIndex = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); - ptable_top->piDifference = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); - ptable_top->piLength = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); - for ( n = 0; n < iMaxTables; n++ ) + ptable_top->piCodeIndex = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) ); + ptable_top->piDifference = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) ); + ptable_top->piLength = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) ); + FOR( n = 0; n < iMaxTables; n++ ) { ptable_top->ppoNextTable[n] = NULL; ptable_top->piCodeIndex[n] = 0xffff; + move32(); ptable_top->piDifference[n] = 0; + move32(); ptable_top->piLength[n] = 0; + move32(); } return ptable_top; } -static void DeleteTableList( TableList *ptable_list, int32_t iTables ) + +static void DeleteTableList( TableList *ptable_list, Word32 iTables ) { TableNode *node; node = ptable_list->poOrderedTop; - while ( ( iTables ) ) + WHILE( ( iTables ) ) { TableNode *node1 = node; node = node1->poOrderedNext; - if ( node1->piCodeIndex != NULL ) + IF( node1->piCodeIndex != NULL ) { free( node1->piCodeIndex ); } - if ( node1->piLength != NULL ) + IF( node1->piLength != NULL ) { free( node1->piLength ); } - if ( node1->piDifference != NULL ) + IF( node1->piDifference != NULL ) { free( node1->piDifference ); } - if ( node1->ppoNextTable != NULL ) + IF( node1->ppoNextTable != NULL ) { free( node1->ppoNextTable ); } - if ( node1 != NULL ) + IF( node1 != NULL ) { free( node1 ); } iTables--; } - if ( ptable_list != NULL ) + IF( ptable_list != NULL ) { free( ptable_list ); } } -static TableNode *GetNextTable( const int32_t iIndex, TableList *table_list, TableNode *poParent, const int32_t iReadLength, uint32_t *iTablesCreated ) + +static TableNode *GetNextTable( Word32 iIndex, TableList *table_list, TableNode *poParent, Word32 iReadLength, UWord32 *iTablesCreated ) { TableNode *poNextNode; - if ( poParent->ppoNextTable[iIndex] == NULL ) + IF( poParent->ppoNextTable[iIndex] == NULL ) { poNextNode = CreateTableList( iReadLength ); poParent->ppoNextTable[iIndex] = poNextNode; poParent->piDifference[iIndex] = *iTablesCreated; /* this is a link to the next table rather than the difference */ + move32(); table_list->poOrderedBottom->poOrderedNext = poNextNode; table_list->poOrderedBottom = poNextNode; ( *iTablesCreated )++; } - else + ELSE { poNextNode = poParent->ppoNextTable[iIndex]; } return poNextNode; } -static void CompleteTables( LCLDDecoder *psLCLDDecoder, const int32_t n, TableList *ptable_list, const int32_t iReadLength, const int32_t iTablesCreated ) + +static void CompleteTables( LCLDDecoder *psLCLDDecoder, Word32 n, TableList *ptable_list, Word32 iReadLength, Word32 iTablesCreated ) { - int32_t iMaxTables; - int32_t j; + Word32 iMaxTables; + Word32 j; TableNode *poNode; - iMaxTables = 1 << iReadLength; + iMaxTables = L_shl( 1, (Word16) iReadLength ); psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = - malloc( iTablesCreated * iMaxTables * sizeof( uint32_t ) ); + malloc( iTablesCreated * iMaxTables * sizeof( UWord32 * ) ); poNode = ptable_list->poOrderedTop; - for ( j = 0; j < iTablesCreated; j++ ) + FOR( j = 0; j < iTablesCreated; j++ ) { - int32_t k; - if ( poNode != NULL ) + Word32 k; + IF( poNode != NULL ) { - for ( k = 0; k < iMaxTables; k++ ) + FOR( k = 0; k < iMaxTables; k++ ) { - uint32_t uiCode; + UWord32 uiCode; uiCode = poNode->piDifference[k]; - uiCode <<= 16; - uiCode |= poNode->piCodeIndex[k]; + move32(); + uiCode = (UWord32) L_shl( (Word32) uiCode, 16 ); + uiCode = (UWord32) L_or( (Word32) uiCode, poNode->piCodeIndex[k] ); psLCLDDecoder->c_apauiHuffDecTable_RAM[n][j][k] = uiCode; + move32(); } } poNode = poNode->poOrderedNext; } } -static void AddcodeTableList( TableList *ptable_list, const int32_t iLength, const int32_t iCode, const int32_t iCodeIndex, const int32_t iReadLength, uint32_t *iTables ) + +static void AddcodeTableList( TableList *ptable_list, Word32 iLength, Word32 iCode, Word32 iCodeIndex, Word32 iReadLength, UWord32 *iTables ) { - int32_t iDifference; - int32_t iMask; - int32_t iCurrentLength; - int32_t iIndex; - int32_t iCodeLow; - int32_t iCodeHigh; + Word32 iDifference; + Word32 iMask; + Word32 iCurrentLength; + Word32 iIndex; + Word32 iCodeLow; + Word32 iCodeHigh; TableNode *poNode; poNode = ptable_list->poOrderedTop; - iMask = ( 1 << iReadLength ) - 1; + iMask = L_sub( L_shl( 1, (Word16) iReadLength ), 1 ); iCurrentLength = iLength; - while ( iCurrentLength > iReadLength ) + move32(); + WHILE( GT_32( iCurrentLength, iReadLength ) ) { - iDifference = iCurrentLength - iReadLength; - iIndex = iCode >> iDifference; - iIndex &= iMask; + iDifference = L_sub( iCurrentLength, iReadLength ); + iIndex = L_shr( iCode, (Word16) iDifference ); + iIndex = L_and( iIndex, iMask ); poNode = GetNextTable( iIndex, ptable_list, poNode, iReadLength, iTables ); - iCurrentLength -= iReadLength; + iCurrentLength = L_sub( iCurrentLength, iReadLength ); } - iMask = ( 1 << iCurrentLength ) - 1; - iDifference = iReadLength - iCurrentLength; - iCodeLow = ( iCode & iMask ) << iDifference; - iMask = ( 1 << iDifference ) - 1; - iCodeHigh = iCodeLow | iMask; - for ( iIndex = iCodeLow; iIndex <= iCodeHigh; iIndex++ ) + iMask = L_sub( L_shl( 1, (Word16) iCurrentLength ), 1 ); + iDifference = L_sub( iReadLength, iCurrentLength ); + iCodeLow = L_shl( L_and( iCode, iMask ), (Word16) iDifference ); + iMask = L_sub( L_shl( 1, (Word16) iDifference ), 1 ); + iCodeHigh = L_or( iCodeLow, iMask ); + FOR( iIndex = iCodeLow; iIndex <= iCodeHigh; iIndex++ ) { poNode->piCodeIndex[iIndex] = iCodeIndex; + move32(); poNode->piDifference[iIndex] = iDifference; + move32(); poNode->piLength[iIndex] = iLength; + move32(); } } -static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, const int32_t num, const uint16_t ( *ppuiEncTable )[2], const int32_t iSize, const int32_t iReadLength, uint32_t *iTables ) +static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, Word32 num, const UWord16 ( *ppuiEncTable )[2], Word32 iSize, Word32 iReadLength, UWord32 *iTables ) { - int32_t n; - uint32_t **ppsort_enc_table; + Word32 n; + UWord32 **ppsort_enc_table; TableList *ptable_list; ptable_list = (TableList *) malloc( sizeof( TableList ) ); - ppsort_enc_table = (uint32_t **) malloc( iSize * sizeof( int32_t * ) ); - for ( n = 0; n < iSize; n++ ) + ppsort_enc_table = (UWord32 **) malloc( iSize * sizeof( Word32 * ) ); + FOR( n = 0; n < iSize; n++ ) { - - ppsort_enc_table[n] = (uint32_t *) malloc( 3 * sizeof( int32_t ) ); - ppsort_enc_table[n][0] = (uint32_t) ppuiEncTable[n][0]; - ppsort_enc_table[n][1] = (uint32_t) ppuiEncTable[n][1]; - ppsort_enc_table[n][2] = (uint32_t) n; + ppsort_enc_table[n] = (UWord32 *) malloc( 3 * sizeof( Word32 ) ); + ppsort_enc_table[n][0] = (UWord32) ppuiEncTable[n][0]; + move32(); + ppsort_enc_table[n][1] = (UWord32) ppuiEncTable[n][1]; + move32(); + ppsort_enc_table[n][2] = (UWord32) n; + move32(); } - for ( n = 0; n < iSize; n++ ) + FOR( n = 0; n < iSize; n++ ) { - uint32_t iMin; - int32_t iMinIndex; - int32_t k; + UWord32 iMin; + Word32 iMinIndex; + Word32 k; iMin = ppsort_enc_table[n][0]; + move32(); iMinIndex = n; - for ( k = n; k < iSize; k++ ) + move32(); + FOR( k = n; k < iSize; k++ ) { - if ( ppsort_enc_table[k][0] < iMin ) + IF( ppsort_enc_table[k][0] < iMin ) { iMin = ppsort_enc_table[k][0]; + move32(); iMinIndex = k; + move32(); } } - if ( iMinIndex != n ) + IF( NE_32( iMinIndex, n ) ) { - uint32_t uiLength; - uint32_t uiCode; - uint32_t uiCodeIndex; + UWord32 uiLength; + UWord32 uiCode; + UWord32 uiCodeIndex; uiLength = ppsort_enc_table[n][0]; + move32(); uiCode = ppsort_enc_table[n][1]; + move32(); uiCodeIndex = ppsort_enc_table[n][2]; + move32(); ppsort_enc_table[n][0] = ppsort_enc_table[iMinIndex][0]; + move32(); ppsort_enc_table[n][1] = ppsort_enc_table[iMinIndex][1]; + move32(); ppsort_enc_table[n][2] = ppsort_enc_table[iMinIndex][2]; + move32(); ppsort_enc_table[iMinIndex][0] = uiLength; + move32(); ppsort_enc_table[iMinIndex][1] = uiCode; + move32(); ppsort_enc_table[iMinIndex][2] = uiCodeIndex; + move32(); } } ptable_list->poOrderedTop = CreateTableList( iReadLength ); ptable_list->poOrderedBottom = ptable_list->poOrderedTop; - for ( n = 0; n < iSize; n++ ) + FOR( n = 0; n < iSize; n++ ) { - int32_t iLength; - int32_t iCode; - int32_t iCodeIndex; + Word32 iLength; + Word32 iCode; + Word32 iCodeIndex; iLength = ppsort_enc_table[n][0]; + move32(); iCode = ppsort_enc_table[n][1]; + move32(); iCodeIndex = ppsort_enc_table[n][2]; + move32(); AddcodeTableList( ptable_list, iLength, iCode, iCodeIndex, iReadLength, iTables ); } CompleteTables( psLCLDDecoder, num, ptable_list, iReadLength, *iTables ); DeleteTableList( ptable_list, *iTables ); - for ( n = 0; n < iSize; n++ ) + FOR( n = 0; n < iSize; n++ ) { free( ppsort_enc_table[n] ); } @@ -344,164 +381,170 @@ static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, const int32_t num, co ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, - const int32_t iSampleRate, - const int32_t iChannels, - const int32_t iNumBlocks, - const int32_t iRealOnlyOut ) + const Word32 iSampleRate, + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iRealOnlyOut ) { - int32_t n; - int32_t read_length; + Word32 n; + Word32 read_length; ivas_error error; LCLDDecoder *psLCLDDecoder = NULL; assert( iSampleRate == 48000 ); assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); - if ( ( psLCLDDecoder = (LCLDDecoder *) malloc( sizeof( LCLDDecoder ) ) ) == NULL ) + IF( ( psLCLDDecoder = (LCLDDecoder *) malloc( sizeof( LCLDDecoder ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } psLCLDDecoder->iSampleRate = iSampleRate; + move32(); psLCLDDecoder->iChannels = iChannels; psLCLDDecoder->iAllocOffset = 0; psLCLDDecoder->iRealOnlyOut = iRealOnlyOut; if ( iRealOnlyOut == 1 ) { - psLCLDDecoder->iNumBlocks = iNumBlocks / 2; + psLCLDDecoder->iNumBlocks = L_shr( iNumBlocks, 1 ); } else { psLCLDDecoder->iNumBlocks = iNumBlocks; } psLCLDDecoder->iNumBands = 0; /* read from bitstream*/ + move32(); psLCLDDecoder->piBandwidths = c_aiBandwidths48; psLCLDDecoder->iMSMode = 0; - if ( ( psLCLDDecoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + move32(); + IF( ( psLCLDDecoder->piMSFlags = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( n = 0; n < MAX_BANDS; n++ ) + FOR( n = 0; n < MAX_BANDS; n++ ) { psLCLDDecoder->piLRPhaseDiffs[n] = 0; + move32(); psLCLDDecoder->piMSPredCoefs[n] = 0; + move32(); } psLCLDDecoder->iCommonGrouping = 1; /* Common grouping always on only impacts stereo */ - if ( ( psLCLDDecoder->piNumGroups = (int32_t *) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ) ) ) == NULL ) + move32(); + IF( ( psLCLDDecoder->piNumGroups = (Word32 *) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->ppiGroupLengths = (int32_t **) malloc( psLCLDDecoder->iChannels * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->ppiGroupLengths = (Word32 **) malloc( psLCLDDecoder->iChannels * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiRMSEnvelope = (int32_t ***) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiRMSEnvelope = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiSMR = (int32_t ***) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiSMR = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiExcitation = (int32_t ***) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiExcitation = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiAlloc = (int32_t ***) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiAlloc = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiLCLDSignReal = (int32_t ***) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiLCLDSignReal = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiLCLDSignImag = (int32_t ***) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiLCLDSignImag = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiQLCLDReal = (int32_t ***) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiQLCLDReal = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiQLCLDImag = (int32_t ***) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiQLCLDImag = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( n = 0; n < iChannels; n++ ) + FOR( n = 0; n < iChannels; n++ ) { - int16_t k; - if ( ( psLCLDDecoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == NULL ) + Word16 k; + IF( ( psLCLDDecoder->ppiGroupLengths[n] = (Word32 *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiRMSEnvelope[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiRMSEnvelope[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiSMR[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiSMR[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiExcitation[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiExcitation[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiAlloc[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiAlloc[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiLCLDSignReal[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiLCLDSignReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiLCLDSignImag[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiLCLDSignImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiQLCLDReal[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiQLCLDReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiQLCLDImag[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiQLCLDImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { - if ( ( psLCLDDecoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiRMSEnvelope[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiSMR[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiSMR[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiExcitation[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiExcitation[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiAlloc[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiAlloc[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiLCLDSignReal[n][k] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiLCLDSignReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiLCLDSignImag[n][k] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiLCLDSignImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiQLCLDReal[n][k] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiQLCLDReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDDecoder->pppiQLCLDImag[n][k] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDDecoder->pppiQLCLDImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } @@ -509,21 +552,22 @@ ivas_error CreateLCLDDecoder( } read_length = READ_LENGTH; - for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + move32(); + FOR( n = 0; n < shl( ALLOC_TABLE_SIZE, 1 ); n++ ) { psLCLDDecoder->num_decode_table[n] = 1; - if ( c_apauiHuffEncTabels[n] != NULL ) + move32(); + IF( c_apauiHuffEncTabels[n] != NULL ) { - CreateDecodeTable( psLCLDDecoder, n, c_apauiHuffEncTabels[n], num_row_aauiLCLDHuff[n], read_length, &psLCLDDecoder->num_decode_table[n] ); } - else + ELSE { psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = NULL; } } - if ( ( error = CreatePredictionDecoder( &psLCLDDecoder->psPredictionDecoder, iChannels, psLCLDDecoder->iNumBlocks ) ) != IVAS_ERR_OK ) + IF( ( error = CreatePredictionDecoder_fx( &psLCLDDecoder->psPredictionDecoder, iChannels, psLCLDDecoder->iNumBlocks ) ) != IVAS_ERR_OK ) { return error; } @@ -535,41 +579,41 @@ ivas_error CreateLCLDDecoder( /*------------------------------------------------------------------------------------------* - * Function CreateLCLDDecoder() + * Function DeleteLCLDDecoder() * * *------------------------------------------------------------------------------------------*/ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) { - int32_t k, n; + Word32 k, n; - if ( psLCLDDecoder != NULL ) + IF( psLCLDDecoder != NULL ) { - if ( psLCLDDecoder->piMSFlags != NULL ) + IF( psLCLDDecoder->piMSFlags != NULL ) { free( psLCLDDecoder->piMSFlags ); } - if ( psLCLDDecoder->piNumGroups != NULL ) + IF( psLCLDDecoder->piNumGroups != NULL ) { free( psLCLDDecoder->piNumGroups ); } - if ( psLCLDDecoder->ppiGroupLengths != NULL ) + IF( psLCLDDecoder->ppiGroupLengths != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { free( psLCLDDecoder->ppiGroupLengths[n] ); } free( psLCLDDecoder->ppiGroupLengths ); } - if ( psLCLDDecoder->pppiRMSEnvelope != NULL ) + IF( psLCLDDecoder->pppiRMSEnvelope != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDDecoder->pppiRMSEnvelope[n][k] ); } @@ -578,11 +622,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiRMSEnvelope ); } - if ( psLCLDDecoder->pppiSMR != NULL ) + IF( psLCLDDecoder->pppiSMR != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDDecoder->pppiSMR[n][k] ); } @@ -591,11 +635,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiSMR ); } - if ( psLCLDDecoder->pppiExcitation != NULL ) + IF( psLCLDDecoder->pppiExcitation != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDDecoder->pppiExcitation[n][k] ); } @@ -605,11 +649,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) } - if ( psLCLDDecoder->pppiAlloc != NULL ) + IF( psLCLDDecoder->pppiAlloc != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDDecoder->pppiAlloc[n][k] ); } @@ -618,11 +662,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiAlloc ); } - if ( psLCLDDecoder->pppiLCLDSignReal != NULL ) + IF( psLCLDDecoder->pppiLCLDSignReal != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDDecoder->pppiLCLDSignReal[n][k] ); } @@ -631,11 +675,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiLCLDSignReal ); } - if ( psLCLDDecoder->pppiLCLDSignImag != NULL ) + IF( psLCLDDecoder->pppiLCLDSignImag != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDDecoder->pppiLCLDSignImag[n][k] ); } @@ -644,11 +688,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiLCLDSignImag ); } - if ( psLCLDDecoder->pppiQLCLDReal != NULL ) + IF( psLCLDDecoder->pppiQLCLDReal != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDDecoder->pppiQLCLDReal[n][k] ); } @@ -657,11 +701,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiQLCLDReal ); } - if ( psLCLDDecoder->pppiQLCLDImag != NULL ) + IF( psLCLDDecoder->pppiQLCLDImag != NULL ) { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDDecoder->pppiQLCLDImag[n][k] ); } @@ -670,25 +714,25 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiQLCLDImag ); } - for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + FOR( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) { - if ( psLCLDDecoder->num_decode_table[n] > 1 ) + IF( psLCLDDecoder->num_decode_table[n] > 1 ) { - if ( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] != NULL ) + IF( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] != NULL ) { free( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] ); } } } - if ( psLCLDDecoder->psPredictionDecoder != NULL ) + IF( psLCLDDecoder->psPredictionDecoder != NULL ) { - DeletePredictionDecoder( psLCLDDecoder->psPredictionDecoder ); + DeletePredictionDecoder_fx( psLCLDDecoder->psPredictionDecoder ); psLCLDDecoder->psPredictionDecoder = NULL; } - if ( psLCLDDecoder->psNoiseGen != NULL ) + IF( psLCLDDecoder->psNoiseGen != NULL ) { DeleteNoiseGen( psLCLDDecoder->psNoiseGen ); } @@ -703,28 +747,29 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) * *------------------------------------------------------------------------------------------*/ -static void ApplyRMSEnvelope( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, float **ppfReal, float **ppfImag ); +static void ApplyRMSEnvelope_fx( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, Word32 **ppfReal_fx, Word32 **ppfImag_fx ); +static void ReplaceSign_fx( const Word32 iNumBlocks, const Word32 iNumLCLDBands, Word32 **ppiSignReal, Word32 **ppiSignImag, Word32 **ppfReal, Word32 **ppfImag, const Word32 *piBandwidths ); -static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag, const int32_t *piBandwidths ); +static void InvQuantizeSpectrum_fx( const Word32 iNumGroups, const Word32 *piGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, Word32 **ppiAlloc, Word32 **ppiQReal, Word32 **ppiQImag, Word32 **ppfReal, Word32 **ppfImag, NoiseGen *psNoiseGen ); +static void InvMSCoding_fx( const Word32 iNumBlocks, const Word32 iNumBands, const Word32 *piBandwidths, const Word32 iMSMode, const Word32 *piMSFlags, const Word32 *piLRPhaseDiffs, const Word32 *piMSPredCoefs, Word32 ***pppfReal, Word32 ***pppfImag ); +// static void InvMSCoding_fx( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, float ***pppfReal, float ***pppfImag, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx,Word16 exp ); -static void InvQuantizeSpectrum( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, int32_t **ppiAlloc, int32_t **ppiQReal, int32_t **ppiQImag, float **ppfReal, float **ppfImag, NoiseGen *psNoiseGen ); +static Word32 ReadHeaderInformation( Word32 *piNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static void InvMSCoding( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, float ***pppfReal, float ***pppfImag ); +static Word32 ReadMSInformation( const Word32 iNumBands, Word32 *piMSMode, Word32 *piMSFlags, Word32 *piLRPhaseDiffs, Word32 *piMSPredCoefs, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadHeaderInformation( int32_t *piNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 ReadGroupInformation( const Word32 iChannels, const Word32 iNumBlocks, Word32 *piCommonGrouping, Word32 *piNumGroups, Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadMSInformation( const int32_t iNumBands, int32_t *piMSMode, int32_t *piMSFlags, int32_t *piLRPhaseDiffs, int32_t *piMSPredCoefs, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 ReadHuff( const UWord32 ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], Word32 *piSymbol, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, int32_t *piCommonGrouping, int32_t *piNumGroups, int32_t **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 ReadRMSEnvelope( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 ReadAllocInformation( Word32 *piAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t ReadAllocInformation( int32_t *piAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t -ReadLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t iNumChannels, int32_t **ppiDecodingUnresolved, int32_t **ppiPredEnable, const int32_t iNumSubSets, const int32_t iSubSetId, int32_t ***pppiAlloc, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); -static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiSMR, const int32_t iAllocOffset, int32_t ***pppiAlloc ); +// static int32_t +// ReadLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); +static Word32 ReadLCLDData_fx( const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 iNumChannels, Word32 **ppiDecodingUnresolved, Word32 **ppiPredEnable, const Word32 iNumSubSets, const Word32 iSubSetId, Word32 ***pppiAlloc, Word32 ***pppiSignReal, Word32 ***pppiSignImag, Word32 ***pppiQReal, Word32 ***pppiQImag, Word32 **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, UWord32 ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); +static void ComputeAllocation( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiSMR, const Word32 iAllocOffset, Word32 ***pppiAlloc ); void SetDecodingUnresolved( LCLDDecoder *psLCLDDecoder ) { @@ -790,89 +835,94 @@ int32_t **GetDecodingFailedPrevStatus( LCLDDecoder *psLCLDDecoder ) return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailedPrev; } -static void UnpackReal( - const int32_t iChannels, - const int32_t iNumBlocks, - float ***pppfReal, - float ***pppfImag ) +static void UnpackReal_fx( + const Word32 iChannels, + const Word32 iNumBlocks, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx ) { - int32_t ch, b, n; - for ( ch = 0; ch < iChannels; ch++ ) + Word32 ch, b, n; + FOR( ch = 0; ch < iChannels; ch++ ) { - for ( b = 0; b < LCLD_BANDS; b++ ) + FOR( b = 0; b < LCLD_BANDS; b++ ) { - int32_t iRealBlock = iNumBlocks - 1; - for ( n = iNumBlocks / 2 - 1; n >= 0; n-- ) + Word32 iRealBlock = iNumBlocks - 1; + FOR( n = iNumBlocks / 2 - 1; n >= 0; n-- ) { - pppfReal[ch][iRealBlock][b] = pppfImag[ch][n][b] * 2.0f; - pppfReal[ch][iRealBlock - 1][b] = pppfReal[ch][n][b] * 2.0f; - pppfImag[ch][iRealBlock][b] = 0.0f; - pppfImag[ch][iRealBlock - 1][b] = 0.0f; + pppfReal_fx[ch][iRealBlock][b] = L_shl( pppfImag_fx[ch][n][b], 1 ); + pppfReal_fx[ch][iRealBlock - 1][b] = L_shl( pppfReal_fx[ch][n][b], 1 ); + pppfImag_fx[ch][iRealBlock][b] = 0; + pppfImag_fx[ch][iRealBlock - 1][b] = 0; iRealBlock -= 2; } } } } - /*------------------------------------------------------------------------------------------* * Function DecodeLCLDFrame() * * *------------------------------------------------------------------------------------------*/ -int32_t DecodeLCLDFrame( +Word32 DecodeLCLDFrame( LCLDDecoder *psLCLDDecoder, ISAR_SPLIT_REND_BITS_HANDLE pBits, - float ***pppfLCLDReal, - float ***pppfLCLDImag ) + Word32 ***pppfLCLDReal_fx, + Word32 ***pppfLCLDImag_fx, + Word16 Q_in, + Word16 *Q_out ) { - int32_t k, n; - + Word32 k, n; + // FILE *ptr = fopen( "cldfb_real.txt", "ab+" ); + // FILE *ptr1 = fopen( "cldfb_imag.txt", "ab+" ); ReadHeaderInformation( &psLCLDDecoder->iNumBands, pBits ); - if ( psLCLDDecoder->iChannels == 2 ) + IF( EQ_32( psLCLDDecoder->iChannels, 2 ) ) { ReadMSInformation( psLCLDDecoder->iNumBands, &psLCLDDecoder->iMSMode, psLCLDDecoder->piMSFlags, psLCLDDecoder->piLRPhaseDiffs, psLCLDDecoder->piMSPredCoefs, pBits ); } - ReadPredictors( psLCLDDecoder->psPredictionDecoder, pBits ); + Word16 i, j; + + ReadPredictors_fx( psLCLDDecoder->psPredictionDecoder, pBits ); + UpdateDecodingUnresolved( psLCLDDecoder->psPredictionDecoder ); UpdateDecodingFailedStatus( psLCLDDecoder->psPredictionDecoder ); ReadGroupInformation( psLCLDDecoder->iChannels, psLCLDDecoder->iNumBlocks, &psLCLDDecoder->iCommonGrouping, psLCLDDecoder->piNumGroups, psLCLDDecoder->ppiGroupLengths, pBits ); - ReadRMSEnvelope( psLCLDDecoder->iChannels, (const int32_t *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope, pBits ); + ReadRMSEnvelope( psLCLDDecoder->iChannels, (const Word32 *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope, pBits ); ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); - if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iCommonGrouping == 1 ) + IF( EQ_32( psLCLDDecoder->iChannels, 2 ) && EQ_32( psLCLDDecoder->iCommonGrouping, 1 ) ) { /* MS Mode? */ - for ( k = 0; k < psLCLDDecoder->piNumGroups[0]; k++ ) + FOR( k = 0; k < psLCLDDecoder->piNumGroups[0]; k++ ) { - PerceptualModelStereo( psLCLDDecoder->iNumBands, psLCLDDecoder->piMSFlags, - psLCLDDecoder->pppiRMSEnvelope[0][k], - psLCLDDecoder->pppiRMSEnvelope[1][k], - psLCLDDecoder->pppiExcitation[0][k], - psLCLDDecoder->pppiExcitation[1][k], - psLCLDDecoder->pppiSMR[0][k], - psLCLDDecoder->pppiSMR[1][k] ); + PerceptualModelStereo_fx( psLCLDDecoder->iNumBands, psLCLDDecoder->piMSFlags, + psLCLDDecoder->pppiRMSEnvelope[0][k], + psLCLDDecoder->pppiRMSEnvelope[1][k], + psLCLDDecoder->pppiExcitation[0][k], + psLCLDDecoder->pppiExcitation[1][k], + psLCLDDecoder->pppiSMR[0][k], + psLCLDDecoder->pppiSMR[1][k] ); } } - else + ELSE { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { /* This will be updated to support multiple sample rates*/ - for ( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ ) + FOR( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ ) { - PerceptualModel( psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope[n][k], psLCLDDecoder->pppiExcitation[n][k], psLCLDDecoder->pppiSMR[n][k] ); + PerceptualModel_fx( (Word16) psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope[n][k], psLCLDDecoder->pppiExcitation[n][k], psLCLDDecoder->pppiSMR[n][k] ); } } } - ComputeAllocation( psLCLDDecoder->iChannels, (const int32_t *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiSMR, psLCLDDecoder->iAllocOffset, psLCLDDecoder->pppiAlloc ); + ComputeAllocation( psLCLDDecoder->iChannels, (const Word32 *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiSMR, psLCLDDecoder->iAllocOffset, psLCLDDecoder->pppiAlloc ); - ReadLCLDData( + ReadLCLDData_fx( psLCLDDecoder->piNumGroups, psLCLDDecoder->ppiGroupLengths, psLCLDDecoder->iNumBands, @@ -889,22 +939,23 @@ int32_t DecodeLCLDFrame( psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed, pBits, psLCLDDecoder->c_apauiHuffDecTable_RAM ); + Word16 q_LCLD = Q_in; - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - InvQuantizeSpectrum( psLCLDDecoder->piNumGroups[n], - (const int32_t *) psLCLDDecoder->ppiGroupLengths[n], - psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, - psLCLDDecoder->pppiAlloc[n], - psLCLDDecoder->pppiQLCLDReal[n], - psLCLDDecoder->pppiQLCLDImag[n], - pppfLCLDReal[n], pppfLCLDImag[n], - psLCLDDecoder->psNoiseGen ); - - ReplaceSign( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands, - psLCLDDecoder->pppiLCLDSignReal[n], - psLCLDDecoder->pppiLCLDSignImag[n], - pppfLCLDReal[n], pppfLCLDImag[n], psLCLDDecoder->piBandwidths ); + InvQuantizeSpectrum_fx( psLCLDDecoder->piNumGroups[n], + (const Word32 *) psLCLDDecoder->ppiGroupLengths[n], + psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, + psLCLDDecoder->pppiAlloc[n], + psLCLDDecoder->pppiQLCLDReal[n], + psLCLDDecoder->pppiQLCLDImag[n], + pppfLCLDReal_fx[n], pppfLCLDImag_fx[n], + psLCLDDecoder->psNoiseGen ); + + ReplaceSign_fx( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands, + psLCLDDecoder->pppiLCLDSignReal[n], + psLCLDDecoder->pppiLCLDSignImag[n], + pppfLCLDReal_fx[n], pppfLCLDImag_fx[n], psLCLDDecoder->piBandwidths ); } #ifdef DEBUG_WRITE_PREDICTORS { @@ -921,182 +972,324 @@ int32_t DecodeLCLDFrame( } #endif - ApplyInversePredictors( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal, pppfLCLDImag ); + ApplyInversePredictors_fx( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal_fx, pppfLCLDImag_fx ); - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) +#ifdef DEBUG_WRITE + FOR( n = 0; n < psLCLDDecoder->psPredictionDecoder->iChannels; ++n ) { - ApplyRMSEnvelope( psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, - psLCLDDecoder->piNumGroups[n], - (const int32_t *) psLCLDDecoder->ppiGroupLengths[n], - psLCLDDecoder->pppiRMSEnvelope[n], - pppfLCLDReal[n], pppfLCLDImag[n] ); + FOR( Word16 i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + dbgwrite_txt( pppfLCLDReal[n][i], LCLD_BANDS, "LCLD_real_ApplyInversePredictors_fix.txt", NULL ); + dbgwrite_txt( pppfLCLDImag[n][i], LCLD_BANDS, "LCLD_imag_ApplyInversePredictors_fix.txt", NULL ); + } } - if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iMSMode > 0 ) + FOR( i = 0; i < psLCLDDecoder->psPredictionDecoder->iChannels; ++i ) { - InvMSCoding( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands, - psLCLDDecoder->piBandwidths, psLCLDDecoder->iMSMode, - (const int32_t *) psLCLDDecoder->piMSFlags, - (const int32_t *) psLCLDDecoder->piLRPhaseDiffs, - (const int32_t *) psLCLDDecoder->piMSPredCoefs, - pppfLCLDReal, pppfLCLDImag ); + dbgwrite_txt( psLCLDDecoder->psPredictionDecoder->ppfPredStateReal[i], LCLD_BANDS, "LCLD_Pred_stat_real_ApplyInversePredictors_fix.txt", NULL ); + dbgwrite_txt( psLCLDDecoder->psPredictionDecoder->ppfPredStateImag[i], LCLD_BANDS, "LCLD_Pred_stat_imag_ApplyInversePredictors_fix.txt", NULL ); } - if ( psLCLDDecoder->iRealOnlyOut == 1 ) +#endif + + Word16 Q = 7; + *Q_out = Q; + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - UnpackReal( psLCLDDecoder->iChannels, - psLCLDDecoder->iNumBlocks * 2, - pppfLCLDReal, - pppfLCLDImag ); + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + pppfLCLDReal_fx[n][i][j] = L_shl( pppfLCLDReal_fx[n][i][j], Q - q_LCLD ); + pppfLCLDImag_fx[n][i][j] = L_shl( pppfLCLDImag_fx[n][i][j], Q - q_LCLD ); + } + } + ApplyRMSEnvelope_fx( psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, + psLCLDDecoder->piNumGroups[n], + (const Word32 *) psLCLDDecoder->ppiGroupLengths[n], + psLCLDDecoder->pppiRMSEnvelope[n], + pppfLCLDReal_fx[n], pppfLCLDImag_fx[n] ); + } + + IF( EQ_32( psLCLDDecoder->iChannels, 2 ) && GT_32( psLCLDDecoder->iMSMode, 0 ) ) + { + Word16 exp1 = Q31 - *Q_out; + Word16 exp2 = Q31 - *Q_out; + Word32 real_max = 0; + Word32 imag_max = 0; + Word16 exp; + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + real_max = L_max( real_max, L_abs( pppfLCLDReal_fx[n][i][j] ) ); + imag_max = L_max( imag_max, L_abs( pppfLCLDImag_fx[n][i][j] ) ); + } + } + } + IF( NE_32( real_max, 0 ) ) + { + exp1 = s_min( exp1, norm_l( real_max ) ); + } + IF( NE_32( imag_max, 0 ) ) + { + exp2 = s_min( exp2, norm_l( imag_max ) ); + } + IF( NE_32( real_max, 0 ) || NE_32( imag_max, 0 ) ) + { + exp = min( exp2, exp1 ); + *Q_out = add( *Q_out, sub( exp, 3 ) ); + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + pppfLCLDReal_fx[n][i][j] = L_shl( pppfLCLDReal_fx[n][i][j], exp - 3 ); + pppfLCLDImag_fx[n][i][j] = L_shl( pppfLCLDImag_fx[n][i][j], exp - 3 ); + } + } + } + } + InvMSCoding_fx( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands, + psLCLDDecoder->piBandwidths, psLCLDDecoder->iMSMode, + (const Word32 *) psLCLDDecoder->piMSFlags, + (const Word32 *) psLCLDDecoder->piLRPhaseDiffs, + (const Word32 *) psLCLDDecoder->piMSPredCoefs, + pppfLCLDReal_fx, pppfLCLDImag_fx ); + +#ifdef DEBUG_WRITE + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + Word32 pppfLCLDReal_dbg[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 pppfLCLDImag_dbg[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + for ( i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + pppfLCLDReal_dbg[n][i][j] = (float) pppfLCLDReal_fx[n][i][j] / ( 1 << ( exp - 3 ) ); + pppfLCLDImag_dbg[n][i][j] = (float) pppfLCLDImag_fx[n][i][j] / ( 1 << ( exp - 3 ) ); + } + } + { + for ( Word16 i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + dbgwrite_txt( pppfLCLDReal_dbg[n][i], CLDFB_NO_CHANNELS_MAX, "LCLD_real_Inv_MS.txt", NULL ); + dbgwrite_txt( pppfLCLDImag_dbg[n][i], CLDFB_NO_CHANNELS_MAX, "LCLD_imag_Inv_MS.txt", NULL ); + } + } + } +#endif + } + IF( EQ_32( psLCLDDecoder->iRealOnlyOut, 1 ) ) + { + UnpackReal_fx( psLCLDDecoder->iChannels, + psLCLDDecoder->iNumBlocks * 2, + pppfLCLDReal_fx, + pppfLCLDImag_fx ); } return AnyDecodingUnresolved( psLCLDDecoder->psPredictionDecoder ); } - - /*------------------------------------------------------------------------------------------* * Local functions * * *------------------------------------------------------------------------------------------*/ - -static void ApplyRMSEnvelope( - const int32_t iNumBands, - const int32_t *piBandwidths, - const int32_t iNumGroups, - const int32_t *piGroupLengths, - int32_t **ppiRMSEnvelope, - float **ppfReal, - float **ppfImag ) +static void ApplyRMSEnvelope_fx( + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 iNumGroups, + const Word32 *piGroupLengths, + Word32 **ppiRMSEnvelope, + Word32 **ppfReal_fx, + Word32 **ppfImag_fx ) { - int32_t b, k, n; - int32_t iBlockOffset, iFBOffset; + Word32 b, k, n; + +#ifdef DEBUG + FILE *fp_real, *fp_imag, *fp_real_fx, *fp_imag_fx, *fp_real_inp, *fp_imag_inp, *fp_real_inp_fx, *fp_imag_inp_fx; + fp_real = fopen( "Float_code_real1.txt", "ab+" ); + fp_imag = fopen( "Float_code_imag1.txt", "ab+" ); + fp_real_fx = fopen( "Fixed_code_real1.txt", "ab+" ); + fp_imag_fx = fopen( "Fixed_code_imag1.txt", "ab+" ); + fp_real_inp = fopen( "real_input.txt", "ab+" ); + fp_imag_inp = fopen( "imag_input.txt", "ab+" ); +#endif + + Word32 iBlockOffset, iFBOffset; iBlockOffset = 0; - for ( n = 0; n < iNumGroups; n++ ) + FOR( n = 0; n < iNumGroups; n++ ) { - for ( k = 0; k < piGroupLengths[n]; k++ ) + FOR( k = 0; k < piGroupLengths[n]; k++ ) { iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) + FOR( b = 0; b < iNumBands; b++ ) { - int32_t m; - int32_t iRMSEnv; - float fGain; + Word32 m; + Word32 iRMSEnv; + Word32 fGain_fx; + Word16 fGain_exp; iRMSEnv = ppiRMSEnvelope[n][b]; - fGain = - c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv]; - for ( m = 0; m < piBandwidths[b]; m++ ) + IF( ( ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv ) % 2 == 0 ) + { + fGain_fx = 1073741824; // 2 ^ 30 + } + ELSE { - ppfReal[iBlockOffset][iFBOffset] *= fGain; - ppfImag[iBlockOffset][iFBOffset] *= fGain; + fGain_fx = 1518500249; // sqrt(2) * 2 ^ 30 + } + fGain_exp = c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv]; + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + Word64 tmp; +#ifdef DEBUG + fprintf( fp_real_inp, "%.6f\n", ppfReal[iBlockOffset][iFBOffset] ); + fprintf( fp_imag_inp, "%.6f\n", ppfImag[iBlockOffset][iFBOffset] ); +#endif + +#ifdef DEBUG + fprintf( fp_real, "%.6f\n", ppfReal[iBlockOffset][iFBOffset] ); + fprintf( fp_imag, "%.6f\n", ppfImag[iBlockOffset][iFBOffset] ); +#endif + tmp = W_mult_32_32( fGain_fx, ppfReal_fx[iBlockOffset][iFBOffset] ); + tmp = W_shr( tmp, fGain_exp + 1 ); + ppfReal_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp ); + + tmp = W_mult_32_32( fGain_fx, ppfImag_fx[iBlockOffset][iFBOffset] ); + tmp = W_shr( tmp, fGain_exp + 1 ); + ppfImag_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp ); + +#ifdef DEBUG + fprintf( fp_real_fx, "%.6f\n", (float) ppfReal_fx[iBlockOffset][iFBOffset] / ( 1 << Q ) ); + fprintf( fp_imag_fx, "%.6f\n", (float) ppfImag_fx[iBlockOffset][iFBOffset] / ( 1 << Q ) ); +#endif + iFBOffset++; } } iBlockOffset++; } } +#ifdef DEBUG + fclose( fp_real ); + fclose( fp_imag ); + fclose( fp_imag_fx ); + fclose( fp_real_fx ); + fclose( fp_real_inp ); + fclose( fp_imag_inp ); +#endif return; } -static void ReplaceSign( - const int32_t iNumBlocks, - const int32_t iNumLCLDBands, - int32_t **ppiSignReal, - int32_t **ppiSignImag, - float **ppfReal, - float **ppfImag, - const int32_t *piBandwidths ) +static void ReplaceSign_fx( + const Word32 iNumBlocks, + const Word32 iNumLCLDBands, + Word32 **ppiSignReal, + Word32 **ppiSignImag, + Word32 **ppfReal, + Word32 **ppfImag, + const Word32 *piBandwidths ) { - int32_t b, n; - int32_t m, idx; + Word32 b, n; + Word32 m, idx; - for ( n = 0; n < iNumBlocks; n++ ) + FOR( n = 0; n < iNumBlocks; n++ ) { idx = 0; - for ( b = 0; b < iNumLCLDBands; b++ ) + move32(); + FOR( b = 0; b < iNumLCLDBands; b++ ) { - for ( m = 0; m < piBandwidths[b]; m++ ) + FOR( m = 0; m < piBandwidths[b]; m++ ) { - if ( ppiSignReal[n][idx] == 1 ) + IF( EQ_32( ppiSignReal[n][idx], 1 ) ) { - ppfReal[n][idx] = -ppfReal[n][idx]; + ppfReal[n][idx] = L_negate( ppfReal[n][idx] ); + move32(); } - if ( ppiSignImag[n][idx] == 1 ) + IF( EQ_32( ppiSignImag[n][idx], 1 ) ) { - ppfImag[n][idx] = -ppfImag[n][idx]; + ppfImag[n][idx] = L_negate( ppfImag[n][idx] ); + move32(); } idx++; } } } - return; } - -static void InvQuantizeSpectrum( - const int32_t iNumGroups, - const int32_t *piGroupLengths, - const int32_t iNumBands, - const int32_t *piBandwidths, - int32_t **ppiAlloc, - int32_t **ppiQReal, - int32_t **ppiQImag, - float **ppfReal, - float **ppfImag, +static void InvQuantizeSpectrum_fx( + const Word32 iNumGroups, + const Word32 *piGroupLengths, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 **ppiAlloc, + Word32 **ppiQReal, + Word32 **ppiQImag, + Word32 **ppfReal, + Word32 **ppfImag, NoiseGen *psNoiseGen /* Pass in NULL to switch off noise gen */ ) { - int32_t b, k, n; - int32_t iBlockOffest, iFBOffset; + Word32 b, k, n; + Word32 iBlockOffest, iFBOffset; iBlockOffest = 0; - for ( n = 0; n < iNumGroups; n++ ) + move32(); + FOR( n = 0; n < iNumGroups; n++ ) { - for ( k = 0; k < piGroupLengths[n]; k++ ) + FOR( k = 0; k < piGroupLengths[n]; k++ ) { iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) + FOR( b = 0; b < iNumBands; b++ ) { - int32_t m; - int32_t iAlloc; - float fInvSCFGain; + Word32 m; + Word32 iAlloc; + Word32 fInvSCFGain; iAlloc = ppiAlloc[n][b]; - fInvSCFGain = c_afInvScaleFactor[iAlloc]; - - if ( iAlloc > 0 ) + move32(); + fInvSCFGain = c_afInvScaleFactor_fx[iAlloc]; // Q29 + move32(); + IF( GT_32( iAlloc, 0 ) ) { - for ( m = 0; m < piBandwidths[b]; m++ ) + FOR( m = 0; m < piBandwidths[b]; m++ ) { - int32_t iQuantValue; - - iQuantValue = ppiQReal[iBlockOffest][iFBOffset]; - ppfReal[iBlockOffest][iFBOffset] = (float) iQuantValue * fInvSCFGain; - - iQuantValue = ppiQImag[iBlockOffest][iFBOffset]; - ppfImag[iBlockOffest][iFBOffset] = (float) iQuantValue * fInvSCFGain; - + Word16 iQuantValue; + + iQuantValue = (Word16) ppiQReal[iBlockOffest][iFBOffset]; + move16(); + ppfReal[iBlockOffest][iFBOffset] = Mpy_32_16_1( fInvSCFGain, iQuantValue ); // Q14 + move32(); + iQuantValue = (Word16) ppiQImag[iBlockOffest][iFBOffset]; + move16(); + ppfImag[iBlockOffest][iFBOffset] = Mpy_32_16_1( fInvSCFGain, iQuantValue ); // Q14 + move32(); iFBOffset++; } } - else if ( psNoiseGen != NULL ) + ELSE IF( psNoiseGen != NULL ) { - for ( m = 0; m < piBandwidths[b]; m++ ) + FOR( m = 0; m < piBandwidths[b]; m++ ) { - ppfReal[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); - ppfImag[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); - + ppfReal[iBlockOffest][iFBOffset] = Mpy_32_16_1( GetNoise_fx( psNoiseGen ), 22938 ); // Q(14 + 15 -15 )=Q14 + move32(); + ppfImag[iBlockOffest][iFBOffset] = Mpy_32_16_1( GetNoise_fx( psNoiseGen ), 22938 ); // Q(14+ 15 -15 )=Q14 + move32(); iFBOffset++; } } - else + ELSE { - iFBOffset += piBandwidths[b]; + iFBOffset = L_add( iFBOffset, piBandwidths[b] ); + move32(); } } @@ -1107,72 +1300,85 @@ static void InvQuantizeSpectrum( return; } - -static void InvMSCoding( - const int32_t iNumBlocks, - const int32_t iNumBands, - const int32_t *piBandwidths, - const int32_t iMSMode, - const int32_t *piMSFlags, - const int32_t *piLRPhaseDiffs, - const int32_t *piMSPredCoefs, - float ***pppfReal, - float ***pppfImag ) +static void InvMSCoding_fx( + const Word32 iNumBlocks, + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 iMSMode, + const Word32 *piMSFlags, + const Word32 *piLRPhaseDiffs, + const Word32 *piMSPredCoefs, + Word32 ***pppfReal, + Word32 ***pppfImag ) { - if ( iMSMode > 0 ) + + IF( GT_32( iMSMode, 0 ) ) { - int32_t b; - int32_t iFBOffset; - int32_t bMSPred = 0; + Word32 b; + Word32 iFBOffset; + Word32 bMSPred = 0; + move32(); iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) + move32(); + FOR( b = 0; b < iNumBands; b++ ) { - if ( piMSFlags[b] == 1 ) + IF( EQ_32( piMSFlags[b], 1 ) ) { - int32_t n; - int32_t phaseIdx; - float fPred; + Word32 n; + Word32 phaseIdx; + + Word32 fPred; + phaseIdx = piLRPhaseDiffs[bMSPred] - PHASE_MIN_VAL; - fPred = dequantPred( piMSPredCoefs[bMSPred] ); - for ( n = 0; n < piBandwidths[b]; n++ ) + move32(); + fPred = dequantPred_fx( piMSPredCoefs[bMSPred] ); + move32(); + FOR( n = 0; n < piBandwidths[b]; n++ ) { - int32_t k; - for ( k = 0; k < iNumBlocks; k++ ) + Word32 k; + FOR( k = 0; k < iNumBlocks; k++ ) { - float fLeftReal; - float fLeftImag; - float fRightReal; - float fRightImag; + Word32 fLeftReal; + Word32 fLeftImag; + Word32 fRightReal; + Word32 fRightImag; - if ( iMSMode == 3 ) + IF( EQ_32( iMSMode, 3 ) ) { - pppfReal[1][k][iFBOffset] += fPred * pppfReal[0][k][iFBOffset]; - pppfImag[1][k][iFBOffset] += fPred * pppfImag[0][k][iFBOffset]; + pppfReal[1][k][iFBOffset] = L_add( pppfReal[1][k][iFBOffset], Mpy_32_32( fPred, pppfReal[0][k][iFBOffset] ) ); + move32(); + pppfImag[1][k][iFBOffset] = L_add( pppfImag[1][k][iFBOffset], Mpy_32_32( fPred, pppfImag[0][k][iFBOffset] ) ); + move32(); } - fLeftReal = ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); - fLeftImag = ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); - fRightReal = ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); - fRightImag = ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + fLeftReal = L_add( pppfReal[0][k][iFBOffset], pppfReal[1][k][iFBOffset] ); + fLeftImag = L_add( pppfImag[0][k][iFBOffset], pppfImag[1][k][iFBOffset] ); + fRightReal = L_sub( pppfReal[0][k][iFBOffset], pppfReal[1][k][iFBOffset] ); + fRightImag = L_sub( pppfImag[0][k][iFBOffset], pppfImag[1][k][iFBOffset] ); - if ( iMSMode == 3 ) + IF( EQ_32( iMSMode, 3 ) ) { - cplxmult_lcld( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); + cplxmult_fx( &fRightReal, &fRightImag, c_afRotRealImag_fx[phaseIdx][0], -c_afRotRealImag_fx[phaseIdx][1] ); } pppfReal[0][k][iFBOffset] = fLeftReal; + move32(); pppfReal[1][k][iFBOffset] = fRightReal; + move32(); pppfImag[0][k][iFBOffset] = fLeftImag; + move32(); pppfImag[1][k][iFBOffset] = fRightImag; + move32(); } iFBOffset++; } bMSPred++; } - else + ELSE { - iFBOffset += piBandwidths[b]; + iFBOffset = L_add( iFBOffset, piBandwidths[b] ); + move32(); } } } @@ -1180,141 +1386,157 @@ static void InvMSCoding( return; } - /* Currently only the number of bands in frame */ -static int32_t ReadHeaderInformation( - int32_t *piNumBands, +static Word32 ReadHeaderInformation( + Word32 *piNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsRead; + Word32 iBitsRead; iBitsRead = 0; + move32(); *piNumBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 5 ); - iBitsRead += 5; + iBitsRead = L_add( iBitsRead, 5 ); return iBitsRead; } -static int32_t ReadMSInformation( - const int32_t iNumBands, - int32_t *piMSMode, - int32_t *piMSFlags, - int32_t *piLRPhaseDiffs, - int32_t *piMSPredCoefs, +static Word32 ReadMSInformation( + const Word32 iNumBands, + Word32 *piMSMode, + Word32 *piMSFlags, + Word32 *piLRPhaseDiffs, + Word32 *piMSPredCoefs, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsRead; + Word32 iBitsRead; iBitsRead = 0; + move32(); *piMSMode = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 2 ); - iBitsRead += 2; + iBitsRead = L_add( iBitsRead, 2 ); - if ( *piMSMode == 0 ) + IF( EQ_32( *piMSMode, 0 ) ) { - int32_t n; - for ( n = 0; n < iNumBands; n++ ) + Word32 n; + FOR( n = 0; n < iNumBands; n++ ) { piMSFlags[n] = 0; + move32(); } } - else if ( *piMSMode == 1 ) + ELSE IF( EQ_32( *piMSMode, 1 ) ) { - int32_t n; - for ( n = 0; n < iNumBands; n++ ) + Word32 n; + FOR( n = 0; n < iNumBands; n++ ) { piMSFlags[n] = 1; + move32(); } } - else if ( *piMSMode == 2 ) + ELSE IF( EQ_32( *piMSMode, 2 ) ) { - int32_t n; - for ( n = 0; n < iNumBands; n++ ) + Word32 n; + FOR( n = 0; n < iNumBands; n++ ) { piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; + move32(); + iBitsRead = L_add( iBitsRead, 1 ); } } - else if ( *piMSMode == 3 ) + ELSE IF( EQ_32( *piMSMode, 3 ) ) { - int32_t n; - int32_t iMSPredAll; - int32_t iNumMSPredBands = 0; - int32_t anyNonZero; + Word32 n; + Word32 iMSPredAll; + Word32 iNumMSPredBands = 0; + Word32 anyNonZero; + move32(); iMSPredAll = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; - if ( iMSPredAll ) + iBitsRead = L_add( iBitsRead, 1 ); + IF( iMSPredAll ) { iNumMSPredBands = iNumBands; - for ( n = 0; n < iNumBands; n++ ) + move32(); + FOR( n = 0; n < iNumBands; n++ ) { piMSFlags[n] = 1; + move32(); } } - else + ELSE { - for ( n = 0; n < iNumBands; n++ ) + FOR( n = 0; n < iNumBands; n++ ) { piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; - if ( piMSFlags[n] ) + move32(); + iBitsRead = L_add( iBitsRead, 1 ); + IF( piMSFlags[n] ) { iNumMSPredBands++; } } } anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - if ( anyNonZero ) + IF( anyNonZero ) { piLRPhaseDiffs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PHASE_BAND0_BITS ); - piLRPhaseDiffs[0] += PHASE_MIN_VAL; - iBitsRead += PHASE_BAND0_BITS; - for ( n = 1; n < iNumMSPredBands; n++ ) + move32(); + piLRPhaseDiffs[0] = L_add( piLRPhaseDiffs[0], PHASE_MIN_VAL ); + move32(); + iBitsRead = L_add( iBitsRead, PHASE_BAND0_BITS ); + FOR( n = 1; n < iNumMSPredBands; n++ ) { - int32_t tabIdx; - iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ); - piLRPhaseDiffs[n] = tabIdx + ENV_DELTA_MIN; + Word32 tabIdx; + iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ) ); + piLRPhaseDiffs[n] = L_add( tabIdx, ENV_DELTA_MIN ); + move32(); } DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM ); } - else + ELSE { - for ( n = 0; n < iNumMSPredBands; n++ ) + FOR( n = 0; n < iNumMSPredBands; n++ ) { piLRPhaseDiffs[n] = 0; + move32(); } } anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - if ( anyNonZero ) + IF( anyNonZero ) { piMSPredCoefs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_BAND0_BITS ); - piMSPredCoefs[0] += PRED_MIN_VAL; - iBitsRead += PRED_BAND0_BITS; - for ( n = 1; n < iNumMSPredBands; n++ ) + move32(); + piMSPredCoefs[0] = L_add( piMSPredCoefs[0], PRED_MIN_VAL ); + move32(); + iBitsRead = L_add( iBitsRead, PRED_BAND0_BITS ); + FOR( n = 1; n < iNumMSPredBands; n++ ) { - int32_t tabIdx; - iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ); - piMSPredCoefs[n] = tabIdx + ENV_DELTA_MIN; + Word32 tabIdx; + iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ) ); + piMSPredCoefs[n] = L_add( tabIdx, ENV_DELTA_MIN ); + move32(); } DecodePredCoef( piMSPredCoefs, iNumMSPredBands ); } - else + ELSE { - for ( n = 0; n < iNumMSPredBands; n++ ) + FOR( n = 0; n < iNumMSPredBands; n++ ) { piMSPredCoefs[n] = 0; + move32(); } } #ifdef DEBUG_WRITE_MS_PRED { static FILE *fid; - if ( !fid ) - fid = fopen( "ms_pred_dec.txt", "wt" ); + IF( !fid ) + fid = fopen( "ms_pred_dec.txt", "wt" ); writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, iNumBands, fid, piMSFlags ); } #endif } - else + ELSE { printf( "ERROR UNSUPPORTED MS MODE\n" ); } @@ -1322,186 +1544,213 @@ static int32_t ReadMSInformation( return iBitsRead; } -static int32_t ReadGroupInformation( - const int32_t iChannels, - const int32_t iNumBlocks, - int32_t *piCommonGrouping, - int32_t *piNumGroups, - int32_t **ppiGroupLengths, +static Word32 ReadGroupInformation( + const Word32 iChannels, + const Word32 iNumBlocks, + Word32 *piCommonGrouping, + Word32 *piNumGroups, + Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t c, k, iBitsRead; + Word32 c, k, iBitsRead; iBitsRead = 0; - if ( iChannels == 2 ) + move32(); + IF( EQ_32( iChannels, 2 ) ) { *piCommonGrouping = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; + move32(); + iBitsRead = L_add( iBitsRead, 1 ); - if ( *piCommonGrouping == 1 ) + IF( EQ_32( *piCommonGrouping, 1 ) ) { piNumGroups[0] = 0; + move32(); ppiGroupLengths[0][piNumGroups[0]] = 1; - for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + move32(); + FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ ) { - int32_t iGroupStart; + Word32 iGroupStart; iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; + iBitsRead = L_add( iBitsRead, 1 ); - if ( iGroupStart == 1 ) + IF( EQ_32( iGroupStart, 1 ) ) { - piNumGroups[0]++; + piNumGroups[0] = L_add( piNumGroups[0], 1 ); + move32(); ppiGroupLengths[0][piNumGroups[0]] = 1; + move32(); } - else + ELSE { - ppiGroupLengths[0][piNumGroups[0]]++; + ppiGroupLengths[0][piNumGroups[0]] = L_add( ppiGroupLengths[0][piNumGroups[0]], 1 ); + move32(); } } - piNumGroups[0]++; + piNumGroups[0] = L_add( piNumGroups[0], 1 ); + move32(); piNumGroups[1] = piNumGroups[0]; - for ( k = 0; k < piNumGroups[1]; k++ ) + move32(); + FOR( k = 0; k < piNumGroups[1]; k++ ) { ppiGroupLengths[1][k] = ppiGroupLengths[0][k]; + move32(); } } - else + ELSE { - for ( c = 0; c < iChannels; c++ ) + FOR( c = 0; c < iChannels; c++ ) { piNumGroups[c] = 0; + move32(); ppiGroupLengths[c][piNumGroups[c]] = 1; - for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + move32(); + FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ ) { - int32_t iGroupStart; + Word32 iGroupStart; iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; + iBitsRead = L_add( iBitsRead, 1 ); - if ( iGroupStart == 1 ) + IF( EQ_32( iGroupStart, 1 ) ) { - piNumGroups[c]++; + piNumGroups[c] = L_add( piNumGroups[c], 1 ); + move32(); ppiGroupLengths[c][piNumGroups[c]] = 1; + move32(); } - else + ELSE { - ppiGroupLengths[c][piNumGroups[c]]++; + ppiGroupLengths[c][piNumGroups[c]] = L_add( ppiGroupLengths[c][piNumGroups[c]], 1 ); + move32(); } } - piNumGroups[c]++; + piNumGroups[c] = L_add( piNumGroups[c], 1 ); + move32(); } } } - else + ELSE { - for ( c = 0; c < iChannels; c++ ) + FOR( c = 0; c < iChannels; c++ ) { piNumGroups[c] = 0; + move32(); ppiGroupLengths[c][piNumGroups[c]] = 1; - for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + move32(); + FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ ) { - int32_t iGroupStart; + Word32 iGroupStart; iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; + iBitsRead = L_add( iBitsRead, 1 ); - if ( iGroupStart == 1 ) + IF( EQ_32( iGroupStart, 1 ) ) { - piNumGroups[c]++; + piNumGroups[c] = L_add( piNumGroups[c], 1 ); + move32(); ppiGroupLengths[c][piNumGroups[c]] = 1; + move32(); } - else + ELSE { - ppiGroupLengths[c][piNumGroups[c]]++; + ppiGroupLengths[c][piNumGroups[c]] = L_add( ppiGroupLengths[c][piNumGroups[c]], 1 ); } } - piNumGroups[c]++; + piNumGroups[c] = L_add( piNumGroups[c], 1 ); } } return iBitsRead; } - -static int32_t BSForceBack( +static Word32 BSForceBack( ISAR_SPLIT_REND_BITS_HANDLE pBits, - int32_t iValue, - int32_t iBitCount ) + Word32 iValue, + Word32 iBitCount ) { - pBits->bits_read -= iBitCount; + pBits->bits_read = L_sub( pBits->bits_read, iBitCount ); - return ( iValue >> iBitCount ); + return ( L_shr( iValue, (Word16) iBitCount ) ); } -static int32_t ReadHuff( - const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], - int32_t *piSymbol, +static Word32 ReadHuff( + const UWord32 ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], + Word32 *piSymbol, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsRead; - int32_t iSymbol; - int32_t iIndex; - int32_t iVal; + Word32 iBitsRead; + Word32 iSymbol; + Word32 iIndex; + Word32 iVal; iVal = 0; + move32(); iIndex = 0; + move32(); iSymbol = 0xFFFF; + move32(); iBitsRead = 0; - while ( iSymbol == 0xFFFF ) + move32(); + WHILE( iSymbol == 0xFFFF ) { iIndex = ISAR_SPLIT_REND_BITStream_read_int32( pBits, HUFF_READ_SIZE ); - iBitsRead += HUFF_READ_SIZE; + iBitsRead = L_add( iBitsRead, HUFF_READ_SIZE ); iIndex = pauiHuffDecTable[iVal][iIndex]; - iSymbol = ( iIndex & 0xFFFF ); + iSymbol = ( L_and( iIndex, 0xFFFF ) ); - iVal = ( iIndex >> 16 ); + iVal = ( L_shr( iIndex, 16 ) ); } - if ( iVal ) + IF( iVal ) { BSForceBack( pBits, iIndex, iVal ); - iBitsRead -= iVal; + iBitsRead = L_sub( iBitsRead, iVal ); } *piSymbol = iSymbol; + move32(); return iBitsRead; } -static int32_t ReadRMSEnvelope( - const int32_t iChannels, - const int32_t *piNumGroups, - const int32_t iNumBands, - int32_t ***pppiRMSEnvelope, +static Word32 ReadRMSEnvelope( + const Word32 iChannels, + const Word32 *piNumGroups, + const Word32 iNumBands, + Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t b, k, n; - int32_t iBitsRead, iLastRMSVal; + Word32 b, k, n; + Word32 iBitsRead, iLastRMSVal; iBitsRead = 0; - for ( n = 0; n < iChannels; n++ ) + move32(); + FOR( n = 0; n < iChannels; n++ ) { - for ( k = 0; k < piNumGroups[n]; k++ ) + FOR( k = 0; k < piNumGroups[n]; k++ ) { iLastRMSVal = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ENV0_BITS ); - iBitsRead += ENV0_BITS; + iBitsRead = L_add( iBitsRead, ENV0_BITS ); - iLastRMSVal += ENV_MIN; + iLastRMSVal = L_add( iLastRMSVal, ENV_MIN ); pppiRMSEnvelope[n][k][0] = iLastRMSVal; - for ( b = 1; b < iNumBands; b++ ) + move32(); + FOR( b = 1; b < iNumBands; b++ ) { - int32_t iDelta; + Word32 iDelta; - iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &iDelta, pBits ); + iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &iDelta, pBits ) ); - iDelta += ENV_DELTA_MIN; - iLastRMSVal += iDelta; + iDelta = L_add( iDelta, ENV_DELTA_MIN ); + iLastRMSVal = L_add( iDelta, iLastRMSVal ); pppiRMSEnvelope[n][k][b] = iLastRMSVal; + move32(); } } } @@ -1510,167 +1759,198 @@ static int32_t ReadRMSEnvelope( } -static int32_t ReadAllocInformation( - int32_t *piAllocOffset, +static Word32 ReadAllocInformation( + Word32 *piAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsRead; + Word32 iBitsRead; iBitsRead = 0; + move32(); *piAllocOffset = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ALLOC_OFFSET_BITS ); - *piAllocOffset += MIN_ALLOC_OFFSET; - iBitsRead += ALLOC_OFFSET_BITS; + *piAllocOffset = L_add( *piAllocOffset, MIN_ALLOC_OFFSET ); + iBitsRead = L_add( iBitsRead, ALLOC_OFFSET_BITS ); return iBitsRead; } -static int32_t ReadLCLDData( - const int32_t *piNumGroups, - int32_t **ppiGroupLengths, - const int32_t iNumBands, - const int32_t iNumChannels, - int32_t **ppiDecodingUnresolved, - int32_t **ppiPredEnable, - const int32_t iNumSubSets, - const int32_t iSubSetId, - int32_t ***pppiAlloc, - int32_t ***pppiSignReal, - int32_t ***pppiSignImag, - int32_t ***pppiQReal, - int32_t ***pppiQImag, - int32_t **ppiDecodingFailed, +static Word32 ReadLCLDData_fx( + const Word32 *piNumGroups, + Word32 **ppiGroupLengths, + const Word32 iNumBands, + const Word32 iNumChannels, + Word32 **ppiDecodingUnresolved, + Word32 **ppiPredEnable, + const Word32 iNumSubSets, + const Word32 iSubSetId, + Word32 ***pppiAlloc, + Word32 ***pppiSignReal, + Word32 ***pppiSignImag, + Word32 ***pppiQReal, + Word32 ***pppiQImag, + Word32 **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, - uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ) + UWord32 ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ) { - int32_t iBitsRead; - int32_t iDecodingStopped = 0; - int32_t iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; - int32_t s; - int32_t iSet = iSubSetId; - + Word32 iBitsRead; + Word32 iDecodingStopped = 0; + Word32 iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; + Word32 s; + Word32 iSet = iSubSetId; + Word16 tmp, tmp_e; iBitsRead = 0; for ( s = 0; s < iNumSubSets; s++, iSet-- ) { - int32_t ch; + Word32 ch; - if ( iSet < 0 ) + IF( LT_32( iSet, 0 ) ) { - iSet = iNumSubSets - 1; + iSet = L_sub( iNumSubSets, 1 ); } - for ( ch = 0; ch < iNumChannels; ch++ ) + FOR( ch = 0; ch < iNumChannels; ch++ ) { - int32_t n; - int32_t iBlockOffest; + Word32 n; + Word32 iBlockOffest; - if ( ppiDecodingUnresolved[ch][iSet] == 1 ) + IF( EQ_32( ppiDecodingUnresolved[ch][iSet], 1 ) ) { iDecodingStopped = 1; ppiDecodingFailed[ch][iSet] = 1; /* mark as not decoded (is also initialized like that when a frame is lost */ } - else + ELSE { ppiDecodingFailed[ch][iSet] = 0; /* mark as correctly decoded */ } iBlockOffest = 0; - for ( n = 0; n < piNumGroups[ch]; n++ ) + FOR( n = 0; n < piNumGroups[ch]; n++ ) { - int32_t k; - for ( k = 0; k < ppiGroupLengths[ch][n]; k++ ) + Word32 k; + FOR( k = 0; k < ppiGroupLengths[ch][n]; k++ ) { - int32_t iFBOffset; + Word32 iFBOffset; - for ( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) + FOR( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) { - int32_t b; - int32_t iAlloc; - int32_t iHuffDim; - int32_t iHuffMod; + Word32 b; + Word32 iAlloc; + Word32 iHuffDim; + Word32 iHuffMod; b = c_aiBandIdPerLcldBand[iFBOffset]; iAlloc = pppiAlloc[ch][n][b]; - iHuffDim = c_aiHuffmanDim[iAlloc]; - iHuffMod = c_aiHuffmanMod[iAlloc]; + iHuffDim = c_aiHuffmanDim_fx[iAlloc]; + iHuffMod = c_aiHuffmanMod_fx[iAlloc]; - if ( iDecodingStopped == 1 ) + IF( EQ_32( iDecodingStopped, 1 ) ) { pppiQReal[ch][iBlockOffest][iFBOffset] = 0; pppiQImag[ch][iBlockOffest][iFBOffset] = 0; pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; } - else if ( iAlloc > 0 ) + ELSE IF( GT_32( iAlloc, 0 ) ) { - const uint32_t( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL; - const uint32_t( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL; - int32_t iQuantValue1 = 0; - int32_t iQuantValue2 = 0; - pauiHuffmanTable = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[iAlloc]; - pauiHuffmanTableDPCM = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc]; + const UWord32( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL; + const UWord32( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL; + Word32 iQuantValue1 = 0; + Word32 iQuantValue2 = 0; +#ifdef USE_DEMOD_TABLES + const int32_t( *paiDemodTable )[2] = NULL; +#endif + pauiHuffmanTable = (const UWord32( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[iAlloc]; + pauiHuffmanTableDPCM = (const UWord32( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc]; +#ifdef USE_DEMOD_TABLES + paiDemodTable = c_apaiDemodTables[iAlloc]; +#endif #ifdef LCLD_HANDLE_PRED_START_SAMPLE if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) #else - if ( ppiPredEnable[ch][iFBOffset] == 1 ) + IF( EQ_32( ppiPredEnable[ch][iFBOffset], 1 ) ) #endif { - if ( iHuffDim == 2 ) + IF( EQ_32( iHuffDim, 2 ) ) { - int32_t iSymbol; - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ); - iQuantValue1 = iSymbol / iHuffMod; + Word32 iSymbol; + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ) ); +#ifdef USE_DEMOD_TABLES + iQuantValue1 = paiDemodTable[iSymbol][0]; + iQuantValue2 = paiDemodTable[iSymbol][1]; +#else + tmp = BASOP_Util_Divide1616_Scale( (Word16) iSymbol, (Word16) iHuffMod, &tmp_e ); + iQuantValue1 = L_deposit_l( shr( tmp, add( 15, negate( tmp_e ) ) ) ); + // iQuantValue1 = iSymbol / iHuffMod; iQuantValue2 = iSymbol % iHuffMod; +#endif } - else + ELSE { - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ); - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ); + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ) ); + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ) ); } } - else + ELSE { - if ( iHuffDim == 2 ) + IF( EQ_32( iHuffDim, 2 ) ) { - int32_t iSymbol; + Word32 iSymbol; - iBitsRead += ReadHuff( pauiHuffmanTable, &iSymbol, pBits ); - iQuantValue1 = iSymbol / iHuffMod; + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iSymbol, pBits ) ); +#ifdef USE_DEMOD_TABLES + iQuantValue1 = paiDemodTable[iSymbol][0]; + iQuantValue2 = paiDemodTable[iSymbol][1]; +#else + tmp = BASOP_Util_Divide1616_Scale( (Word16) iSymbol, (Word16) iHuffMod, &tmp_e ); + iQuantValue1 = L_deposit_l( shr( tmp, add( 15, negate( tmp_e ) ) ) ); iQuantValue2 = iSymbol % iHuffMod; +#endif } - else + ELSE { - iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ); - iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ); + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ) ); + move32(); + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ) ); + move32(); + /*iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ); + iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits );*/ } } pppiQReal[ch][iBlockOffest][iFBOffset] = iQuantValue1; + move32(); pppiQImag[ch][iBlockOffest][iFBOffset] = iQuantValue2; - - if ( iQuantValue1 > 0 ) + move32(); + IF( GT_32( iQuantValue1, 0 ) ) { pppiSignReal[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; + move32(); + iBitsRead = L_add( iBitsRead, 1 ); + move32(); } - else + ELSE { pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; } - if ( iQuantValue2 > 0 ) + IF( GT_32( iQuantValue2, 0 ) ) { pppiSignImag[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); - iBitsRead += 1; + move32(); + iBitsRead = L_add( iBitsRead, 1 ); + move32(); } - else + ELSE { pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; } } - else + ELSE { pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + move32(); pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; + move32(); } } iBlockOffest++; @@ -1683,29 +1963,31 @@ static int32_t ReadLCLDData( } static void ComputeAllocation( - const int32_t iChannels, - const int32_t *piNumGroups, - const int32_t iNumBands, - int32_t ***pppiSMR, - const int32_t iAllocOffset, - int32_t ***pppiAlloc ) + const Word32 iChannels, + const Word32 *piNumGroups, + const Word32 iNumBands, + Word32 ***pppiSMR, + const Word32 iAllocOffset, + Word32 ***pppiAlloc ) { - int32_t b, k, n, iAlloc; + Word32 b, k, n, iAlloc; - for ( n = 0; n < iChannels; n++ ) + FOR( n = 0; n < iChannels; n++ ) { - for ( k = 0; k < piNumGroups[n]; k++ ) + FOR( k = 0; k < piNumGroups[n]; k++ ) { - for ( b = 0; b < iNumBands; b++ ) + FOR( b = 0; b < iNumBands; b++ ) { - iAlloc = ( ( pppiSMR[n][k][b] + iAllocOffset * ALLOC_OFFSET_SCALE ) >> 5 ); + iAlloc = L_shr( L_add( pppiSMR[n][k][b], L_mult0( (Word16) iAllocOffset, ALLOC_OFFSET_SCALE ) ), 5 ); iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC; iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC; pppiAlloc[n][k][b] = iAlloc; + move32(); } } } return; } + #endif diff --git a/lib_isar/isar_lcld_encoder.c b/lib_isar/isar_lcld_encoder.c index b71ed9854..aa9332c26 100644 --- a/lib_isar/isar_lcld_encoder.c +++ b/lib_isar/isar_lcld_encoder.c @@ -35,128 +35,133 @@ #ifdef SPLIT_REND_WITH_HEAD_ROT #include #include +#include "isar_lcld_prot.h" +#include "isar_lcld_rom_tables.h" #include "prot.h" +#include "prot_fx2.h" #include "isar_prot.h" #include "wmc_auto.h" +#include "basop_util.h" +#include "enh64.h" +#include "basop32.h" +#include "basop_mpy.h" +#define LOG10_2_FX ( 646456993 ) /*------------------------------------------------------------------------------------------* * Local structures *------------------------------------------------------------------------------------------*/ - struct LCLD_ENCODER { - int32_t iSampleRate; - int32_t iChannels; - int32_t iNumBlocks; + Word32 iSampleRate; + Word32 iChannels; + Word32 iNumBlocks; - int32_t iTargetBitRate; + Word32 iTargetBitRate; - int32_t iNumBands; - const int32_t *piBandwidths; + Word32 iNumBands; + const Word32 *piBandwidths; - int32_t iMSMode; - int32_t *piMSFlags; - int32_t piMSPredCoefs[MAX_BANDS]; - int32_t piLRPhaseDiffs[MAX_BANDS]; - int32_t iAllowSidePred; + Word32 iMSMode; + Word32 *piMSFlags; + Word32 piMSPredCoefs[MAX_BANDS]; + Word32 piLRPhaseDiffs[MAX_BANDS]; + Word32 iAllowSidePred; - int32_t iRealOnlyOut; + Word32 iRealOnlyOut; RMSEnvelopeGrouping *psRMSEnvelopeGrouping; - int32_t iCommonGrouping; - int32_t *piNumGroups; - int32_t **ppiGroupLengths; + Word32 iCommonGrouping; + Word32 *piNumGroups; + Word32 **ppiGroupLengths; - int32_t ***pppiRMSEnvelope; - int32_t ***pppiSMR; - int32_t ***pppiExcitation; - int32_t ***pppiAlloc; + Word32 ***pppiRMSEnvelope; + Word32 ***pppiSMR; + Word32 ***pppiExcitation; + Word32 ***pppiAlloc; - int32_t iAllocOffset; + Word32 iAllocOffset; - int32_t ***pppiLCLDSignReal; - int32_t ***pppiLCLDSignImag; - int32_t ***pppiQLCLDReal; - int32_t ***pppiQLCLDImag; + Word32 ***pppiLCLDSignReal; + Word32 ***pppiLCLDSignImag; + Word32 ***pppiQLCLDReal; + Word32 ***pppiQLCLDImag; PredictionEncoder *psPredictionEncoder; }; - /*------------------------------------------------------------------------------------------* * Function Quantize() * * *------------------------------------------------------------------------------------------*/ - -static int32_t Quantize( - const float fVal, - const float fScale, - int32_t *iSign, - const int32_t iMaxVal ) +static Word32 Quantize_fx( + const Word32 fVal_fx, + const Word32 fScale_fx, + Word32 *iSign, + const Word32 iMaxVal ) { - int32_t iVal; - if ( fVal > 0.0f ) + Word32 iVal_fx; + IF( GT_32( fVal_fx, 0 ) ) { - iVal = (int32_t) ( fScale * fVal + 0.5f ); + iVal_fx = (Word32) L_add( Mpy_32_32( fScale_fx, fVal_fx ), ONE_IN_Q20 ); *iSign = 0; } - else + ELSE { - iVal = (int32_t) ( -fScale * fVal + 0.5f ); + iVal_fx = (Word32) L_add( Mpy_32_32( -fScale_fx, fVal_fx ), ONE_IN_Q20 ); *iSign = 1; } - iVal = ( iVal < iMaxVal ) ? iVal : iMaxVal; + iVal_fx = ( iVal_fx < iMaxVal ) ? iVal_fx : iMaxVal; - return iVal; + return iVal_fx; } - /*------------------------------------------------------------------------------------------* * Function UnQuantize() * * *------------------------------------------------------------------------------------------*/ - -static float UnQuantize( - const int32_t iVal, - const float fScale, - const int32_t iSign ) +static Word32 UnQuantize_fx( + const Word32 iVal_fx, + const Word32 fScale_fx, + const Word32 iSign ) { - float fVal; - if ( iSign == 0 ) + + Word32 fVal_fx; + IF( EQ_32( iSign, 0 ) ) { - fVal = fScale * (float) iVal; + fVal_fx = Mpy_32_32( fScale_fx, iVal_fx ); // Q19 } - else + ELSE { - fVal = -fScale * (float) iVal; + fVal_fx = Mpy_32_32( -fScale_fx, iVal_fx ); // Q19 } - return fVal; + return fVal_fx; } - static void PackReal( - const int32_t iChannels, - const int32_t iNumBlocks, - float ***pppfReal, - float ***pppfImag ) + const Word32 iChannels, + const Word32 iNumBlocks, + Word32 ***pppfReal, + Word32 ***pppfImag ) { - int32_t ch, b, n; - for ( ch = 0; ch < iChannels; ch++ ) + Word32 ch, b, n; + FOR( ch = 0; ch < iChannels; ch++ ) { - for ( b = 0; b < LCLD_BANDS; b++ ) + FOR( b = 0; b < LCLD_BANDS; b++ ) { - int32_t iRealBlock = 0; - for ( n = 0; n < iNumBlocks; n += 2 ) + Word32 iRealBlock = 0; + move32(); + FOR( n = 0; n < iNumBlocks; n += 2 ) { pppfImag[ch][iRealBlock][b] = pppfReal[ch][n + 1][b]; + move32(); pppfReal[ch][iRealBlock][b] = pppfReal[ch][n][b]; + move32(); iRealBlock++; } } } } - /*------------------------------------------------------------------------------------------* * Function CreateLCLDEncoder() * @@ -165,210 +170,226 @@ static void PackReal( ivas_error CreateLCLDEncoder( LCLDEncoder **psLCLDEncoder_out, - const int32_t iSampleRate, - const int32_t iChannels, - const int32_t iTargetBitRate, - const int32_t iAllowSidePred, - const int16_t iNumBlocks, - const int16_t iNumSubSets, - const int32_t iRealOnlyOut ) + const Word32 iSampleRate, + const Word32 iChannels, + const Word32 iTargetBitRate, + const Word32 iAllowSidePred, + const Word16 iNumBlocks, + const Word16 iNumSubSets, + const Word32 iRealOnlyOut ) { - int32_t n; + Word32 n; LCLDEncoder *psLCLDEncoder; ivas_error error; - int32_t iMaxNumPredBands = 0; + Word32 iMaxNumPredBands = 0; + move32(); - assert( iSampleRate == 48000 ); + assert( iSampleRate == 48000 ); // Fix assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); assert( iNumSubSets > 0 && iNumSubSets <= LCLD_MAX_NUM_PRED_SUBSETS ); - if ( ( psLCLDEncoder = (LCLDEncoder *) malloc( sizeof( LCLDEncoder ) ) ) == NULL ) + IF( ( psLCLDEncoder = (LCLDEncoder *) malloc( sizeof( LCLDEncoder ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } psLCLDEncoder->iSampleRate = iSampleRate; + move32(); psLCLDEncoder->iChannels = iChannels; + move32(); psLCLDEncoder->iRealOnlyOut = iRealOnlyOut; + move32(); psLCLDEncoder->iAllocOffset = 0; + move32(); psLCLDEncoder->iTargetBitRate = iTargetBitRate; + move32(); psLCLDEncoder->piBandwidths = c_aiBandwidths48; psLCLDEncoder->iNumBands = DEF_BANDS_48; /* 22 bands = 50 CLDFB bands (rather than 23 bands) */ - iMaxNumPredBands = min( c_aiNumLcldBandsPerBand[psLCLDEncoder->iNumBands - 1], 50 ); - if ( iRealOnlyOut == 1 ) + move32(); + iMaxNumPredBands = L_min( c_aiNumLcldBandsPerBand[psLCLDEncoder->iNumBands - 1], 50 ); + IF( EQ_32( iRealOnlyOut, 1 ) ) { iMaxNumPredBands = 0; + move32(); assert( iNumSubSets == 1 ); - psLCLDEncoder->iNumBlocks = iNumBlocks / 2; + psLCLDEncoder->iNumBlocks = L_deposit_l( shr( iNumBlocks, 1 ) ); } - else + ELSE { psLCLDEncoder->iNumBlocks = iNumBlocks; + move32(); } + psLCLDEncoder->iMSMode = 0; - if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + move32(); + IF( ( psLCLDEncoder->piMSFlags = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( n = 0; n < MAX_BANDS; n++ ) + FOR( n = 0; n < MAX_BANDS; n++ ) { psLCLDEncoder->piLRPhaseDiffs[n] = 0; + move32(); psLCLDEncoder->piMSPredCoefs[n] = 0; + move32(); } psLCLDEncoder->iAllowSidePred = iAllowSidePred; + move32(); + psLCLDEncoder->psRMSEnvelopeGrouping = CreateRMSEnvelopeGrouping( psLCLDEncoder->iNumBlocks ); - psLCLDEncoder->iCommonGrouping = 1; /*Common grouping always on only impacts stereo */ - if ( ( psLCLDEncoder->piNumGroups = (int32_t *) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ) ) ) == NULL ) + psLCLDEncoder->iCommonGrouping = 1; //*Common grouping always on only impacts stereo */ + move32(); + IF( ( psLCLDEncoder->piNumGroups = (Word32 *) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->ppiGroupLengths = (int32_t **) malloc( psLCLDEncoder->iChannels * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->ppiGroupLengths = (Word32 **) malloc( psLCLDEncoder->iChannels * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiRMSEnvelope = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiRMSEnvelope = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiSMR = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiSMR = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiExcitation = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiExcitation = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiAlloc = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiAlloc = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiLCLDSignReal = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiLCLDSignReal = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiLCLDSignImag = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiLCLDSignImag = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiQLCLDReal = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiQLCLDReal = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiQLCLDImag = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiQLCLDImag = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( n = 0; n < iChannels; n++ ) + FOR( n = 0; n < iChannels; n++ ) { - int32_t k; - if ( ( psLCLDEncoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == NULL ) + Word32 k; + IF( ( psLCLDEncoder->ppiGroupLengths[n] = (Word32 *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiRMSEnvelope[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiRMSEnvelope[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiSMR[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiSMR[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiExcitation[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiExcitation[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiAlloc[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiAlloc[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiLCLDSignReal[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiLCLDSignReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiLCLDSignImag[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiLCLDSignImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiQLCLDReal[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiQLCLDReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiQLCLDImag[n] = (int32_t **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t * ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiQLCLDImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { - if ( ( psLCLDEncoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiRMSEnvelope[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiSMR[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiSMR[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiExcitation[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiExcitation[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiAlloc[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiAlloc[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiLCLDSignReal[n][k] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiLCLDSignReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiLCLDSignImag[n][k] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiLCLDSignImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiQLCLDReal[n][k] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiQLCLDReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiQLCLDImag[n][k] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) + IF( ( psLCLDEncoder->pppiQLCLDImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } } } - if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, (int32_t) iNumSubSets, iMaxNumPredBands ) ) != IVAS_ERR_OK ) + IF( ( error = CreatePredictionEncoder_fx( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, L_deposit_l( iNumSubSets ), iMaxNumPredBands ) ) != IVAS_ERR_OK ) { return error; } @@ -388,39 +409,39 @@ ivas_error CreateLCLDEncoder( void DeleteLCLDEncoder( LCLDEncoder *psLCLDEncoder ) { - int32_t k, n; + Word32 k, n; - if ( psLCLDEncoder != NULL ) + IF( psLCLDEncoder != NULL ) { - if ( psLCLDEncoder->piMSFlags != NULL ) + IF( psLCLDEncoder->piMSFlags != NULL ) { free( psLCLDEncoder->piMSFlags ); } - if ( psLCLDEncoder->piNumGroups != NULL ) + IF( psLCLDEncoder->piNumGroups != NULL ) { free( psLCLDEncoder->piNumGroups ); } - if ( psLCLDEncoder->psRMSEnvelopeGrouping != NULL ) + IF( psLCLDEncoder->psRMSEnvelopeGrouping != NULL ) { DeleteRMSEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping ); } - if ( psLCLDEncoder->ppiGroupLengths != NULL ) + IF( psLCLDEncoder->ppiGroupLengths != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { free( psLCLDEncoder->ppiGroupLengths[n] ); } free( psLCLDEncoder->ppiGroupLengths ); } - if ( psLCLDEncoder->pppiRMSEnvelope != NULL ) + IF( psLCLDEncoder->pppiRMSEnvelope != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDEncoder->pppiRMSEnvelope[n][k] ); } @@ -429,11 +450,11 @@ void DeleteLCLDEncoder( free( psLCLDEncoder->pppiRMSEnvelope ); } - if ( psLCLDEncoder->pppiSMR != NULL ) + IF( psLCLDEncoder->pppiSMR != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDEncoder->pppiSMR[n][k] ); } @@ -442,11 +463,11 @@ void DeleteLCLDEncoder( free( psLCLDEncoder->pppiSMR ); } - if ( psLCLDEncoder->pppiExcitation != NULL ) + IF( psLCLDEncoder->pppiExcitation != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDEncoder->pppiExcitation[n][k] ); } @@ -455,11 +476,11 @@ void DeleteLCLDEncoder( free( psLCLDEncoder->pppiExcitation ); } - if ( psLCLDEncoder->pppiAlloc != NULL ) + IF( psLCLDEncoder->pppiAlloc != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDEncoder->pppiAlloc[n][k] ); } @@ -468,11 +489,11 @@ void DeleteLCLDEncoder( free( psLCLDEncoder->pppiAlloc ); } - if ( psLCLDEncoder->pppiLCLDSignReal != NULL ) + IF( psLCLDEncoder->pppiLCLDSignReal != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDEncoder->pppiLCLDSignReal[n][k] ); } @@ -481,11 +502,11 @@ void DeleteLCLDEncoder( free( psLCLDEncoder->pppiLCLDSignReal ); } - if ( psLCLDEncoder->pppiLCLDSignImag != NULL ) + IF( psLCLDEncoder->pppiLCLDSignImag != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDEncoder->pppiLCLDSignImag[n][k] ); } @@ -494,11 +515,11 @@ void DeleteLCLDEncoder( free( psLCLDEncoder->pppiLCLDSignImag ); } - if ( psLCLDEncoder->pppiQLCLDReal != NULL ) + IF( psLCLDEncoder->pppiQLCLDReal != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDEncoder->pppiQLCLDReal[n][k] ); } @@ -507,11 +528,11 @@ void DeleteLCLDEncoder( free( psLCLDEncoder->pppiQLCLDReal ); } - if ( psLCLDEncoder->pppiQLCLDImag != NULL ) + IF( psLCLDEncoder->pppiQLCLDImag != NULL ) { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) { free( psLCLDEncoder->pppiQLCLDImag[n][k] ); } @@ -520,7 +541,7 @@ void DeleteLCLDEncoder( free( psLCLDEncoder->pppiQLCLDImag ); } - DeletePredictionEncoder( psLCLDEncoder->psPredictionEncoder ); + DeletePredictionEncoder_fx( psLCLDEncoder->psPredictionEncoder ); free( psLCLDEncoder ); } @@ -531,171 +552,165 @@ void DeleteLCLDEncoder( * Local function declarations *------------------------------------------------------------------------------------------*/ -static int32_t MSModeCalculation( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t *piMSMode, int32_t *piLRPhaseDiff, int32_t *piMSPredCoef, const int32_t iAllowSidePred, const int32_t iRealOnlyOut, int32_t *piMSFlags ); +static Word32 MSModeCalculation_fx( const Word32 iNumBlocks, const Word32 iNumBands, const Word32 *piBandwidths, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx, Word16 Q_in, Word32 *piMSMode, Word32 *piLRPhaseDiff, Word32 *piMSPredCoef, const Word32 iAllowSidePred, const Word32 iRealOnlyOut, Word32 *piMSFlags ); +static void RemoveRMSEnvelope( const Word32 iNumBands, const Word32 *piBandwidths, const Word32 iNumGroups, const Word32 *piGroupLengths, Word32 **ppiRMSEnvelope, Word32 **ppfReal_fx, Word32 **ppfImag_fx ); +static Word32 CountLCLDBits( const Word32 iNumGroups, const Word32 *piGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, const Word32 *piPredEnable, Word32 **ppiAlloc, Word32 **ppiQReal, Word32 **ppiQImag ); -static void RemoveRMSEnvelope( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, float **ppfReal, float **ppfImag ); +static Word32 WriteHeaderInformation( const Word32 iNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t CountLCLDBits( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiQReal, int32_t **ppiQImag ); +static Word32 WriteMSInformation( const Word32 iNumBands, const Word32 iMSMode, const Word32 *piMSFlags, const Word32 *piLRPhaseDiff, const Word32 *piMSPredCoef, Word32 iNumMSPredBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t WriteHeaderInformation( const int32_t iNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 WriteGroupInformation( const Word32 iChannels, const Word32 iCommonGrouping, const Word32 *piNumGroups, Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t WriteMSInformation( const int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, int32_t iNumMSPredBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 WriteRMSEnvelope( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t WriteRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t WriteAllocInformation( const int32_t iAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t WriteLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t iNumChannels, int32_t **ppiPredEnable, const int32_t iNumSubSets, const int32_t iSubSetId, int32_t ***pppiAlloc, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t ***pppiQReal, int32_t ***pppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t ***pppiSMR, const int32_t iAvailableBits, int32_t *piAllocOffset, int32_t ***pppiAlloc, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, PredictionEncoder *psPredictionEncoder ); +static Word32 WriteAllocInformation( const Word32 iAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 WriteLCLDData( const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 iNumChannels, Word32 **ppiPredEnable, const Word32 iNumSubSets, const Word32 iSubSetId, Word32 ***pppiAlloc, Word32 ***pppiSignReal, Word32 ***pppiSignImag, Word32 ***pppiQReal, Word32 ***pppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 ComputeAllocation( const Word32 iChannels, const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx, Word16 q_final, Word32 ***pppiSMR, const Word32 iAvailableBits, Word32 *piAllocOffset, Word32 ***pppiAlloc, Word32 ***pppiQReal, Word32 ***pppiQImag, Word32 ***pppiSignReal, Word32 ***pppiSignImag, PredictionEncoder *psPredictionEncoder ); /*------------------------------------------------------------------------------------------* * Function EncodeLCLDFrame() * * *------------------------------------------------------------------------------------------*/ - -int32_t EncodeLCLDFrame( +Word32 EncodeLCLDFrame( LCLDEncoder *psLCLDEncoder, - float ***pppfLCLDReal, - float ***pppfLCLDImag, - int32_t *piBitsWritten, - const int32_t available_bits, - ISAR_SPLIT_REND_BITS_HANDLE pBits ) + Word32 ***pppfLCLDReal_fx, + Word32 ***pppfLCLDImag_fx, + Word32 *piBitsWritten, + const Word32 available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word16 *q_final ) { - int32_t n; - int32_t iAvailableBits, iBitsWritten; - int32_t iNumMSBands = 0; - int32_t iAudioBitsWritten; + Word32 n; + Word32 iAvailableBits, iBitsWritten; + Word32 iNumMSBands = 0; + Word32 iAudioBitsWritten; - iAvailableBits = available_bits; /* HCBR for now*/ + iAvailableBits = available_bits; // HCBR for now iBitsWritten = 0; assert( available_bits <= pBits->buf_len * 8 ); - - if ( psLCLDEncoder->iRealOnlyOut == 1 ) + IF( EQ_32( psLCLDEncoder->iRealOnlyOut, 1 ) ) { - PackReal( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBlocks * 2, pppfLCLDReal, pppfLCLDImag ); + PackReal( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBlocks * 2, pppfLCLDReal_fx, pppfLCLDImag_fx ); } - /* Do MS calc here */ - if ( psLCLDEncoder->iChannels == 2 ) + IF( EQ_32( psLCLDEncoder->iChannels, 2 ) ) { - iNumMSBands = MSModeCalculation( psLCLDEncoder->iNumBlocks, - psLCLDEncoder->iNumBands, - psLCLDEncoder->piBandwidths, - pppfLCLDReal, - pppfLCLDImag, - &psLCLDEncoder->iMSMode, - psLCLDEncoder->piLRPhaseDiffs, - psLCLDEncoder->piMSPredCoefs, - psLCLDEncoder->iAllowSidePred, - psLCLDEncoder->iRealOnlyOut, - psLCLDEncoder->piMSFlags ); - - if ( psLCLDEncoder->iMSMode > 0 ) + iNumMSBands = MSModeCalculation_fx( psLCLDEncoder->iNumBlocks, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal_fx, + pppfLCLDImag_fx, + *q_final, + &psLCLDEncoder->iMSMode, + psLCLDEncoder->piLRPhaseDiffs, + psLCLDEncoder->piMSPredCoefs, + psLCLDEncoder->iAllowSidePred, + psLCLDEncoder->iRealOnlyOut, + psLCLDEncoder->piMSFlags ); + IF( GT_32( psLCLDEncoder->iMSMode, 0 ) ) { - psLCLDEncoder->iCommonGrouping = 1; /* Make sure common grouping is enabled when MS is in use */ + psLCLDEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use } } - - /* Compute Grouping and RMS Envelopes */ - if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) + IF( EQ_32( psLCLDEncoder->iChannels, 2 ) && EQ_32( psLCLDEncoder->iCommonGrouping, 1 ) ) { ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, psLCLDEncoder->iChannels, psLCLDEncoder->iNumBands, psLCLDEncoder->piBandwidths, - pppfLCLDReal, - pppfLCLDImag, + pppfLCLDReal_fx, + pppfLCLDImag_fx, &psLCLDEncoder->piNumGroups[0], psLCLDEncoder->ppiGroupLengths[0], - psLCLDEncoder->pppiRMSEnvelope ); - + psLCLDEncoder->pppiRMSEnvelope, + *q_final ); psLCLDEncoder->piNumGroups[1] = psLCLDEncoder->piNumGroups[0]; - for ( n = 0; n < psLCLDEncoder->piNumGroups[0]; n++ ) + FOR( n = 0; n < psLCLDEncoder->piNumGroups[0]; n++ ) { psLCLDEncoder->ppiGroupLengths[1][n] = psLCLDEncoder->ppiGroupLengths[0][n]; + move32(); } } - else + ELSE { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, psLCLDEncoder->iChannels, psLCLDEncoder->iNumBands, psLCLDEncoder->piBandwidths, - &pppfLCLDReal[n], - &pppfLCLDImag[n], + &pppfLCLDReal_fx[n], + &pppfLCLDImag_fx[n], &psLCLDEncoder->piNumGroups[n], psLCLDEncoder->ppiGroupLengths[n], - &psLCLDEncoder->pppiRMSEnvelope[n] ); + &psLCLDEncoder->pppiRMSEnvelope[n], *q_final ); } } - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { RemoveRMSEnvelope( psLCLDEncoder->iNumBands, psLCLDEncoder->piBandwidths, psLCLDEncoder->piNumGroups[n], - (const int32_t *) psLCLDEncoder->ppiGroupLengths[n], + (const Word32 *) psLCLDEncoder->ppiGroupLengths[n], psLCLDEncoder->pppiRMSEnvelope[n], - pppfLCLDReal[n], - pppfLCLDImag[n] ); + pppfLCLDReal_fx[n], + pppfLCLDImag_fx[n] ); } + *q_final = add( *q_final, 9 ); // Increasing the Q as it has changed inside the RemoveRMSEnvelope - ComputePredictors( psLCLDEncoder->psPredictionEncoder, pppfLCLDReal, pppfLCLDImag ); + ComputePredictors_fx( psLCLDEncoder->psPredictionEncoder, pppfLCLDReal_fx, pppfLCLDImag_fx ); - iBitsWritten += WriteHeaderInformation( psLCLDEncoder->iNumBands, pBits ); + iBitsWritten = L_add( iBitsWritten, WriteHeaderInformation( psLCLDEncoder->iNumBands, pBits ) ); - if ( psLCLDEncoder->iChannels == 2 ) + IF( EQ_32( psLCLDEncoder->iChannels, 2 ) ) { - iBitsWritten += WriteMSInformation( psLCLDEncoder->iNumBands, - psLCLDEncoder->iMSMode, - (const int32_t *) psLCLDEncoder->piMSFlags, - (const int32_t *) psLCLDEncoder->piLRPhaseDiffs, - (const int32_t *) psLCLDEncoder->piMSPredCoefs, - iNumMSBands, - pBits ); + iBitsWritten = L_add( iBitsWritten, WriteMSInformation( psLCLDEncoder->iNumBands, + psLCLDEncoder->iMSMode, + (const Word32 *) psLCLDEncoder->piMSFlags, + (const Word32 *) psLCLDEncoder->piLRPhaseDiffs, + (const Word32 *) psLCLDEncoder->piMSPredCoefs, + iNumMSBands, + pBits ) ); } - iBitsWritten += WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ); + iBitsWritten = L_add( iBitsWritten, WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ) ); - iBitsWritten += WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ); + iBitsWritten = L_add( iBitsWritten, WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ) ); - iBitsWritten += WriteRMSEnvelope( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ); + iBitsWritten = L_add( iBitsWritten, WriteRMSEnvelope( psLCLDEncoder->iChannels, (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ) ); - if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) + IF( EQ_32( psLCLDEncoder->iChannels, 2 ) && EQ_32( psLCLDEncoder->iCommonGrouping, 1 ) ) { - int32_t k; - for ( k = 0; k < psLCLDEncoder->piNumGroups[0]; k++ ) + Word32 k; + FOR( k = 0; k < psLCLDEncoder->piNumGroups[0]; k++ ) { - PerceptualModelStereo( psLCLDEncoder->iNumBands, - psLCLDEncoder->piMSFlags, - psLCLDEncoder->pppiRMSEnvelope[0][k], - psLCLDEncoder->pppiRMSEnvelope[1][k], - psLCLDEncoder->pppiExcitation[0][k], - psLCLDEncoder->pppiExcitation[1][k], - psLCLDEncoder->pppiSMR[0][k], - psLCLDEncoder->pppiSMR[1][k] ); + PerceptualModelStereo_fx( psLCLDEncoder->iNumBands, + psLCLDEncoder->piMSFlags, + psLCLDEncoder->pppiRMSEnvelope[0][k], + psLCLDEncoder->pppiRMSEnvelope[1][k], + psLCLDEncoder->pppiExcitation[0][k], + psLCLDEncoder->pppiExcitation[1][k], + psLCLDEncoder->pppiSMR[0][k], + psLCLDEncoder->pppiSMR[1][k] ); } } - else + ELSE { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - int32_t k; - for ( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ ) + Word32 k; + FOR( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ ) { - PerceptualModel( psLCLDEncoder->iNumBands, - psLCLDEncoder->pppiRMSEnvelope[n][k], - psLCLDEncoder->pppiExcitation[n][k], - psLCLDEncoder->pppiSMR[n][k] ); + PerceptualModel_fx( psLCLDEncoder->iNumBands, + psLCLDEncoder->pppiRMSEnvelope[n][k], + psLCLDEncoder->pppiExcitation[n][k], + psLCLDEncoder->pppiSMR[n][k] ); } } } @@ -713,14 +728,16 @@ int32_t EncodeLCLDFrame( fprintf( fid, "%d %d\n", psLCLDEncoder->psPredictionEncoder->iSubSetId, psLCLDEncoder->psPredictionEncoder->piPredChanEnable[n] ); } #endif - iAvailableBits -= iBitsWritten; + iAvailableBits = L_sub( iAvailableBits, iBitsWritten ); + ComputeAllocation( psLCLDEncoder->iChannels, - (const int32_t *) psLCLDEncoder->piNumGroups, + (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, psLCLDEncoder->iNumBands, psLCLDEncoder->piBandwidths, - pppfLCLDReal, - pppfLCLDImag, + pppfLCLDReal_fx, + pppfLCLDImag_fx, + *q_final, psLCLDEncoder->pppiSMR, iAvailableBits, &psLCLDEncoder->iAllocOffset, @@ -731,30 +748,42 @@ int32_t EncodeLCLDFrame( psLCLDEncoder->pppiLCLDSignImag, psLCLDEncoder->psPredictionEncoder ); - iBitsWritten += WriteAllocInformation( psLCLDEncoder->iAllocOffset, - pBits ); + iBitsWritten = L_add( iBitsWritten, WriteAllocInformation( psLCLDEncoder->iAllocOffset, + pBits ) ); iAudioBitsWritten = iBitsWritten; - iBitsWritten += WriteLCLDData( psLCLDEncoder->piNumGroups, - psLCLDEncoder->ppiGroupLengths, - psLCLDEncoder->iNumBands, - psLCLDEncoder->iChannels, - psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable, - psLCLDEncoder->psPredictionEncoder->iNumSubSets, - psLCLDEncoder->psPredictionEncoder->iSubSetId, - psLCLDEncoder->pppiAlloc, - psLCLDEncoder->pppiLCLDSignReal, - psLCLDEncoder->pppiLCLDSignImag, - psLCLDEncoder->pppiQLCLDReal, - psLCLDEncoder->pppiQLCLDImag, - pBits ); + iBitsWritten = L_add( iBitsWritten, WriteLCLDData( psLCLDEncoder->piNumGroups, + psLCLDEncoder->ppiGroupLengths, + psLCLDEncoder->iNumBands, + psLCLDEncoder->iChannels, + psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable, + psLCLDEncoder->psPredictionEncoder->iNumSubSets, + psLCLDEncoder->psPredictionEncoder->iSubSetId, + psLCLDEncoder->pppiAlloc, + psLCLDEncoder->pppiLCLDSignReal, + psLCLDEncoder->pppiLCLDSignImag, + psLCLDEncoder->pppiQLCLDReal, + psLCLDEncoder->pppiQLCLDImag, + pBits ) ); *piBitsWritten = iBitsWritten; - iAudioBitsWritten = iBitsWritten - iAudioBitsWritten; + move32(); + iAudioBitsWritten = L_sub( iBitsWritten, iAudioBitsWritten ); UpdatePredictionSubSetId( psLCLDEncoder->psPredictionEncoder ); return 0; } +/*------------------------------------------------------------------------------------------* + * Function GetNumGroups() + * + * + *------------------------------------------------------------------------------------------*/ + +Word32 GetNumGroups( LCLDEncoder *psLCLDEncoder ) +{ + return psLCLDEncoder->piNumGroups[0]; +} + /*------------------------------------------------------------------------------------------* * Local functions @@ -776,82 +805,87 @@ enum MS_BS_TYPES MS_SOME = 2, MS_PRED = 3 }; - -static int32_t MSModeCalculation( - const int32_t iNumBlocks, - const int32_t iNumBands, - const int32_t *piBandwidths, - float ***pppfReal, - float ***pppfImag, - int32_t *piMSMode, - int32_t *piLRPhaseDiffs, - int32_t *piMSPredCoefs, - const int32_t iAllowSidePred, - const int32_t iRealOnlyOut, - int32_t *piMSFlags ) +static Word32 MSModeCalculation_fx( + const Word32 iNumBlocks, + const Word32 iNumBands, + const Word32 *piBandwidths, + /*float ***pppfReal, + float ***pppfImag,*/ + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + Word16 Q_in, + Word32 *piMSMode, + Word32 *piLRPhaseDiffs, + Word32 *piMSPredCoefs, + const Word32 iAllowSidePred, + const Word32 iRealOnlyOut, + Word32 *piMSFlags ) { - int32_t b; - int32_t iFBOffset; - int32_t iNumMSBands; - int32_t iMSPredType; - float fMSBitGain = 0.0f; - float pfMSPredBitGain[3]; - float fPred; - int32_t piMSPredFlags0[MAX_BANDS]; - int32_t piMSPredFlags1[MAX_BANDS]; - int32_t piMSPredFlags2[MAX_BANDS]; - int32_t *ppiMSPredFlags[3]; - int32_t piMSPredCoefs0[MAX_BANDS]; - int32_t piMSPredCoefs1[MAX_BANDS]; - int32_t piMSPredCoefs2[MAX_BANDS]; - int32_t *ppiMSPredCoefs[3]; - int32_t piMSPredPhase0[MAX_BANDS]; - int32_t piMSPredPhase1[MAX_BANDS]; - int32_t piMSPredPhase2[MAX_BANDS]; - int32_t *ppiMSPredPhase[3]; - int32_t iMsInfoBits; - int32_t piMsPredInfoBits[3]; - - const float feps = 1e-12f; - float fBitsFactor = 3.32192809488736f; /* = 1/log10(2), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */ - - set_zero( pfMSPredBitGain, 3 ); - set_l( piMsPredInfoBits, 0, 3 ); - - set_l( piMSPredFlags0, 0, MAX_BANDS ); - set_l( piMSPredFlags1, 0, MAX_BANDS ); - set_l( piMSPredFlags2, 0, MAX_BANDS ); - set_l( piMSPredCoefs0, 0, MAX_BANDS ); - set_l( piMSPredCoefs1, 0, MAX_BANDS ); - set_l( piMSPredCoefs2, 0, MAX_BANDS ); - set_l( piMSPredPhase0, 0, MAX_BANDS ); - set_l( piMSPredPhase1, 0, MAX_BANDS ); - set_l( piMSPredPhase2, 0, MAX_BANDS ); - - if ( iNumBlocks < LCLD_BLOCKS_PER_FRAME ) + Word32 b; + Word32 iFBOffset; + Word32 iNumMSBands; + Word32 iMSPredType; + /*float fMSBitGain = 0.0f; + float pfMSPredBitGain[3] = { 0.0f }; + float fPred;*/ + Word32 fMSBitGain_fx = 0; + Word32 pfMSPredBitGain_fx[3] = { 0 }; + Word32 fPred_fx; + Word32 piMSPredFlags0[MAX_BANDS] = { 0 }; + Word32 piMSPredFlags1[MAX_BANDS] = { 0 }; + Word32 piMSPredFlags2[MAX_BANDS] = { 0 }; + Word32 *ppiMSPredFlags[3]; + Word32 piMSPredCoefs0[MAX_BANDS] = { 0 }; + Word32 piMSPredCoefs1[MAX_BANDS] = { 0 }; + Word32 piMSPredCoefs2[MAX_BANDS] = { 0 }; + Word32 *ppiMSPredCoefs[3]; + Word32 piMSPredPhase0[MAX_BANDS] = { 0 }; + Word32 piMSPredPhase1[MAX_BANDS] = { 0 }; + Word32 piMSPredPhase2[MAX_BANDS] = { 0 }; + Word32 *ppiMSPredPhase[3]; + Word32 iMsInfoBits; + Word32 piMsPredInfoBits[3] = { 0 }; + + // const float feps = 1e-12f; + // float fBitsFactor = 3.32192809488736f; /* = 1/log10(2), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */ + const Word32 feps_fx = 1; // is this correct? + move32(); + Word32 fBitsFactor_fx = 1783446565; /* = 1/log10(2) (Q29), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */ + move32(); + IF( LT_32( iNumBlocks, LCLD_BLOCKS_PER_FRAME ) ) { - fBitsFactor *= ( 0.7f + (float) ( iNumBlocks - 4 ) / (float) ( LCLD_BLOCKS_PER_FRAME - 4 ) * ( 1.0f - 0.7f ) ); /* Tuning for relatively higher side rate due to shorter frame length */ + // fBitsFactor *= ( 0.7f + (float) ( iNumBlocks - 4 ) / (float) ( LCLD_BLOCKS_PER_FRAME - 4 ) * ( 1.0f - 0.7f ) ); /* Tuning for relatively higher side rate due to shorter frame length */ + fBitsFactor_fx = Mpy_32_32( fBitsFactor_fx, L_add( 1503238553, W_extract_l( W_mult0_32_32( L_sub( iNumBlocks, 4 ), 596523235 ) ) ) ); /* Tuning for relatively higher side rate due to shorter frame length */ } ppiMSPredFlags[0] = piMSPredFlags0; + move32(); ppiMSPredFlags[1] = piMSPredFlags1; + move32(); ppiMSPredFlags[2] = piMSPredFlags2; - + move32(); ppiMSPredCoefs[0] = piMSPredCoefs0; + move32(); ppiMSPredCoefs[1] = piMSPredCoefs1; + move32(); ppiMSPredCoefs[2] = piMSPredCoefs2; - + move32(); ppiMSPredPhase[0] = piMSPredPhase0; + move32(); ppiMSPredPhase[1] = piMSPredPhase1; + move32(); ppiMSPredPhase[2] = piMSPredPhase2; - + move32(); *piMSMode = MS_OFF; + move32(); iFBOffset = 0; + move32(); iNumMSBands = 0; - for ( b = 0; b < iNumBands; b++ ) + move32(); + FOR( b = 0; b < iNumBands; b++ ) { - int32_t n; - float fLeftEnergy; + Word32 n; + /*float fLeftEnergy; float fRightEnergy; float fMidEnergy; float fSideEnergy; @@ -861,171 +895,303 @@ static int32_t MSModeCalculation( float fMidEnergyPred; float fSideEnergyPred; float fLRCovReal = 0.0f; - float fLRCovImag = 0.0f; - int32_t iPhase; - int32_t iPred; - int32_t tabIdx = 0; - float fNumLines = (float) ( iRealOnlyOut == 1 ? iNumBlocks * piBandwidths[b] * 4 : iNumBlocks * piBandwidths[b] * 2 ); /* per band per channel */ - float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */ - fLeftEnergy = 0.0f; - fRightEnergy = 0.0f; - fMidEnergy = 0.0f; - fSideEnergy = 0.0f; - - for ( n = 0; n < piBandwidths[b]; n++ ) + float fLRCovImag = 0.0f;*/ + Word32 fLeftEnergy_fx; + Word32 fRightEnergy_fx; + Word32 fMidEnergy_fx; + Word32 fSideEnergy_fx; + Word64 fLeftEnergy_fx64; + Word64 fRightEnergy_fx64; + Word64 fMidEnergy_fx64; + Word64 fSideEnergy_fx64; + Word32 fLRRatio_fx; + Word32 fMSRatio_fx; + Word32 pfMSPredRatio_fx[3] = { 0 }; + Word32 fMidEnergyPred_fx; + Word32 fSideEnergyPred_fx; + Word32 fLRCovReal_fx = 0; + Word32 fLRCovImag_fx = 0; + Word64 fLRCovReal_fx64 = 0; + Word64 fLRCovImag_fx64 = 0; + Word32 iPhase; + Word32 iPred; + Word32 tabIdx = 0; + // float fNumLines = (float)(iRealOnlyOut == 1 ? iNumBlocks * piBandwidths[b] * 4 : iNumBlocks * piBandwidths[b] * 2); /* per band per channel */ + // float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */ + Word32 fNumLines_fx = iRealOnlyOut == 1 ? L_shl( iNumBlocks * piBandwidths[b], 2 ) : L_shl( iNumBlocks * piBandwidths[b], 1 ); /* per band per channel */ + Word32 fLevelToSMRdBFactor_fx = L_shl( c_aiDefaultTheta48[b], 23 ); /* frequency dependent SMR slope in psy model Q23:sub(Q31, PERCEPTUAL_MODEL_SLGAIN_SHIFT) */ + fLeftEnergy_fx = 0; + fRightEnergy_fx = 0; + fMidEnergy_fx = 0; + fSideEnergy_fx = 0; + fLeftEnergy_fx64 = 0; + fRightEnergy_fx64 = 0; + fMidEnergy_fx64 = 0; + fSideEnergy_fx64 = 0; + Word16 Q_en_tmp = 63; + + FOR( n = 0; n < piBandwidths[b]; n++ ) { - int32_t k; - for ( k = 0; k < iNumBlocks; k++ ) + Word32 k; + FOR( k = 0; k < iNumBlocks; k++ ) { - float fMidReal; + /*float fMidReal; float fMidImag; float fSideReal; - float fSideImag; - - fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); - fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); - fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); - fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); - - fLeftEnergy += ( pppfReal[0][k][iFBOffset] * pppfReal[0][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[0][k][iFBOffset] ); - fRightEnergy += ( pppfReal[1][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[1][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); - fMidEnergy += ( fMidReal * fMidReal + fMidImag * fMidImag ); - fSideEnergy += ( fSideReal * fSideReal + fSideImag * fSideImag ); - - fLRCovReal += ( pppfReal[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); - fLRCovImag += ( pppfImag[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] - pppfImag[1][k][iFBOffset] * pppfReal[0][k][iFBOffset] ); + float fSideImag;*/ + Word32 fMidReal_fx; + Word32 fMidImag_fx; + Word32 fSideReal_fx; + Word32 fSideImag_fx; + + // fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fMidReal_fx = L_shr( L_add( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 ); + // fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fMidImag_fx = L_shr( L_add( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 ); + // fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fSideReal_fx = L_shr( L_sub( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 ); + // fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + fSideImag_fx = L_shr( L_sub( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 ); + + // fLeftEnergy += ( pppfReal[0][k][iFBOffset] * pppfReal[0][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[0][k][iFBOffset] ); + fLeftEnergy_fx64 = W_add( fLeftEnergy_fx64, W_add( W_mult0_32_32( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[0][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[0][k][iFBOffset] ) ) ); + // fRightEnergy += ( pppfReal[1][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[1][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); + fRightEnergy_fx64 = W_add( fRightEnergy_fx64, W_add( W_mult0_32_32( pppfReal_fx[1][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[1][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ) ) ); + // fMidEnergy += ( fMidReal * fMidReal + fMidImag * fMidImag ); + fMidEnergy_fx64 = W_add( fMidEnergy_fx64, W_add( W_mult0_32_32( fMidReal_fx, fMidReal_fx ), W_mult0_32_32( fMidImag_fx, fMidImag_fx ) ) ); + // fSideEnergy += ( fSideReal * fSideReal + fSideImag * fSideImag ); + fSideEnergy_fx64 = W_add( fSideEnergy_fx64, W_add( W_mult0_32_32( fSideReal_fx, fSideReal_fx ), W_mult0_32_32( fSideImag_fx, fSideImag_fx ) ) ); + + // fLRCovReal += ( pppfReal[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); + fLRCovReal_fx64 = W_add( fLRCovReal_fx64, W_add( W_mult0_32_32( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ) ) ); + // fLRCovImag += ( pppfImag[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] - pppfImag[1][k][iFBOffset] * pppfReal[0][k][iFBOffset] ); + fLRCovImag_fx64 = W_add( fLRCovImag_fx64, W_sub( W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[1][k][iFBOffset], pppfReal_fx[0][k][iFBOffset] ) ) ); } iFBOffset++; } - + Q_en_tmp = min( Q_en_tmp, W_norm( fLeftEnergy_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fRightEnergy_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fMidEnergy_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fSideEnergy_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fLRCovReal_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fLRCovImag_fx64 ) ); + Q_en_tmp = sub( Q_en_tmp, 2 ); + fLeftEnergy_fx = W_extract_h( W_shl( fLeftEnergy_fx64, Q_en_tmp ) ); + fRightEnergy_fx = W_extract_h( W_shl( fRightEnergy_fx64, Q_en_tmp ) ); + fMidEnergy_fx = W_extract_h( W_shl( fMidEnergy_fx64, Q_en_tmp ) ); + fSideEnergy_fx = W_extract_h( W_shl( fSideEnergy_fx64, Q_en_tmp ) ); + fLRCovReal_fx = W_extract_h( W_shl( fLRCovReal_fx64, Q_en_tmp ) ); + fLRCovImag_fx = W_extract_h( W_shl( fLRCovImag_fx64, Q_en_tmp ) ); + Word16 Q_en = add( shl( Q_in, 1 ), sub( Q_en_tmp, 32 ) ) /*2 * Q_in - 31 - 2*/; /* M/S prediction without phase alignment*/ - fPred = 0.25f * ( fLeftEnergy - fRightEnergy ) / ( fMidEnergy + feps ); - iPred = quantPred( fPred ); - fPred = dequantPred( iPred ); - fSideEnergyPred = fSideEnergy + ( fPred * fPred * fMidEnergy - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + // fPred = 0.25f * ( fLeftEnergy - fRightEnergy ) / ( fMidEnergy + feps ); + // iPred = quantPred(fPred); + // fPred = dequantPred(iPred); + Word16 exp; + fPred_fx = BASOP_Util_Divide3232_Scale( L_sub( fLeftEnergy_fx, fRightEnergy_fx ), L_add( fMidEnergy_fx, feps_fx ), &exp ); + exp = sub( exp, 2 ); //*0.25f + fPred_fx = L_shl( fPred_fx, 16 ); + iPred = quantPred_fx( fPred_fx, exp ); + fPred_fx = dequantPred_fx( iPred ); // Q31 + // fSideEnergyPred = fSideEnergy + ( fPred * fPred * fMidEnergy - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + fSideEnergyPred_fx = L_add( fSideEnergy_fx, + L_sub( Mpy_32_32( Mpy_32_32( fPred_fx, fPred_fx ), fMidEnergy_fx ), + L_shr( Mpy_32_32( fPred_fx, L_sub( fLeftEnergy_fx, fRightEnergy_fx ) ), 1 ) ) ); + fSideEnergyPred_fx = max( fSideEnergyPred_fx, 0 ); ppiMSPredCoefs[MS_PRED_ONLY][b] = iPred; + move32(); ppiMSPredPhase[MS_PRED_ONLY][b] = 0; - pfMSPredRatio[MS_PRED_ONLY] = log10f( ( fMidEnergy + feps ) / ( fSideEnergyPred + feps ) ); + move32(); + // pfMSPredRatio[MS_PRED_ONLY] = log10f( ( fMidEnergy + feps ) / ( fSideEnergyPred + feps ) ); + pfMSPredRatio_fx[MS_PRED_ONLY] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergy_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25 + // printf("%f ", (float)pfMSPredRatio_fx[MS_PRED_ONLY] / (1 << 25)); /* Phase alignment*/ iPhase = 0; - if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) + move32(); + // if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) + IF( GT_32( L_add( Mpy_32_32( fLRCovReal_fx, fLRCovReal_fx ), Mpy_32_32( fLRCovImag_fx, fLRCovImag_fx ) ), L_shr( Mpy_32_32( fLeftEnergy_fx, fRightEnergy_fx ), 1 ) ) ) { - float fPhase = atan2f( fLRCovImag, fLRCovReal ); - iPhase = quantPhase( fPhase ); + // float fPhase = atan2f( fLRCovImag, fLRCovReal ); + Word32 fPhase_fx = BASOP_util_atan2( fLRCovImag_fx, fLRCovReal_fx, 0 ); + exp = sub( 18, norm_l( fPhase_fx ) ); + fPhase_fx = L_shl( fPhase_fx, norm_l( fPhase_fx ) ); // Q31 + // iPhase = quantPhase( fPhase ); + iPhase = quantPhase_fx( fPhase_fx, exp ); } /* adjust covariance */ - tabIdx = iPhase - PHASE_MIN_VAL; - cplxmult_lcld( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); + tabIdx = L_sub( iPhase, PHASE_MIN_VAL ); + // cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); + cplxmult_fx( &fLRCovReal_fx, &fLRCovImag_fx, c_afRotRealImag_fx[tabIdx][0], -c_afRotRealImag_fx[tabIdx][1] ); /* compute MS prediction coefficient based on adjusted covariance */ - fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); - fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal ); + // fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); + fMidEnergyPred_fx = L_add( L_add( L_shr_r( fLeftEnergy_fx, 2 ), L_shr_r( fRightEnergy_fx, 2 ) ), L_shr( fLRCovReal_fx, 1 ) ); // Q_en + // fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal ); + fSideEnergyPred_fx = L_sub( L_add( L_shr_r( fLeftEnergy_fx, 2 ), L_shr_r( fRightEnergy_fx, 2 ) ), L_shr( fLRCovReal_fx, 1 ) ); // Q_en + fSideEnergyPred_fx = L_max( fSideEnergyPred_fx, 0 ); /* M/S with LR phase alignment but without prediction */ ppiMSPredCoefs[MS_PHASE_ONLY][b] = 0; + move32(); ppiMSPredPhase[MS_PHASE_ONLY][b] = iPhase; - pfMSPredRatio[MS_PHASE_ONLY] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + move32(); + // pfMSPredRatio[MS_PHASE_ONLY] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + pfMSPredRatio_fx[MS_PHASE_ONLY] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergyPred_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25 + // printf("%f ", (float)pfMSPredRatio_fx[MS_PHASE_ONLY] / (1 << 25)); /* M/S with LR phase alignment and prediction */ - fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred; - iPred = quantPred( fPred ); - fPred = dequantPred( iPred ); - fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + // fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred; + fPred_fx = fMidEnergyPred_fx == 0 ? 0 : BASOP_Util_Divide3232_Scale( L_sub( fLeftEnergy_fx, fRightEnergy_fx ), fMidEnergyPred_fx, &exp ); + exp = sub( exp, 2 ); //*0.25f + fPred_fx = L_shl( fPred_fx, 16 ); + // iPred = quantPred( fPred ); + iPred = quantPred_fx( fPred_fx, exp ); + // fPred = dequantPred( iPred ); + fPred_fx = dequantPred_fx( iPred ); + // fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + fSideEnergyPred_fx = L_add( fSideEnergyPred_fx, + L_sub( Mpy_32_32( Mpy_32_32( fPred_fx, fPred_fx ), fMidEnergyPred_fx ), + L_shr( Mpy_32_32( fPred_fx, L_sub( fLeftEnergy_fx, fRightEnergy_fx ) ), 1 ) ) ); + fSideEnergyPred_fx = max( fSideEnergyPred_fx, 0 ); /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */ ppiMSPredCoefs[MS_PHASE_AND_PRED][b] = iPred; + move32(); ppiMSPredPhase[MS_PHASE_AND_PRED][b] = iPhase; - pfMSPredRatio[MS_PHASE_AND_PRED] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + move32(); + // pfMSPredRatio[MS_PHASE_AND_PRED] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + pfMSPredRatio_fx[MS_PHASE_AND_PRED] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergyPred_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25 + // printf("%f ", (float)pfMSPredRatio_fx[MS_PHASE_AND_PRED] / (1 << 25)); /* Plain M/S */ - fLeftEnergy = log10f( fLeftEnergy + feps ); - fRightEnergy = log10f( fRightEnergy + feps ); - fMidEnergy = log10f( fMidEnergy + feps ); - fSideEnergy = log10f( fSideEnergy + feps ); - - fLRRatio = ( fLeftEnergy > fRightEnergy ? fLeftEnergy - fRightEnergy : fRightEnergy - fLeftEnergy ); - fMSRatio = ( fMidEnergy > fSideEnergy ? fMidEnergy - fSideEnergy : fSideEnergy - fMidEnergy ); - - if ( fMSRatio > fLRRatio ) + // fLeftEnergy = log10f( fLeftEnergy + feps ); + exp = sub( 31, Q_en ); // 31 - Q + fLeftEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fLeftEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25 + // fRightEnergy = log10f( fRightEnergy + feps ); + fRightEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fRightEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25 + // fMidEnergy = log10f( fMidEnergy + feps ); + fMidEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fMidEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25 + // fSideEnergy = log10f( fSideEnergy + feps ); + fSideEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fSideEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25 + + // fLRRatio = ( fLeftEnergy > fRightEnergy ? fLeftEnergy - fRightEnergy : fRightEnergy - fLeftEnergy ); + fLRRatio_fx = ( fLeftEnergy_fx > fRightEnergy_fx ? L_sub( fLeftEnergy_fx, fRightEnergy_fx ) : L_sub( fRightEnergy_fx, fLeftEnergy_fx ) ); // Q25 + // fMSRatio = ( fMidEnergy > fSideEnergy ? fMidEnergy - fSideEnergy : fSideEnergy - fMidEnergy ); + fMSRatio_fx = ( fMidEnergy_fx > fSideEnergy_fx ? L_sub( fMidEnergy_fx, fSideEnergy_fx ) : L_sub( fSideEnergy_fx, fMidEnergy_fx ) ); // Q25 + + // if ( fMSRatio > fLRRatio ) + IF( GT_32( fMSRatio_fx, fLRRatio_fx ) ) { iNumMSBands++; piMSFlags[b] = 1; - fMSBitGain += fNumLines * ( fMSRatio - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + move32(); + // fMSBitGain += fNumLines * ( fMSRatio - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + fMSBitGain_fx = L_add( fMSBitGain_fx, W_extract_l( W_shr( W_mult0_32_32( fNumLines_fx, Mpy_32_32( Mpy_32_32( L_sub( fMSRatio_fx, fLRRatio_fx ), fLevelToSMRdBFactor_fx ), fBitsFactor_fx ) ), 7 ) ) ); // Q16 } - else + ELSE { piMSFlags[b] = 0; + move32(); } piLRPhaseDiffs[b] = 0; + move32(); piMSPredCoefs[b] = 0; + move32(); /* MSPred bit gains based on increase of level ratio compared to L/R ratio and the level dependent psy-model */ - for ( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) + FOR( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) { - if ( pfMSPredRatio[iMSPredType] > fLRRatio ) + // if ( pfMSPredRatio[iMSPredType] > fLRRatio ) + IF( GT_32( pfMSPredRatio_fx[iMSPredType], fLRRatio_fx ) ) { ppiMSPredFlags[iMSPredType][b] = 1; - pfMSPredBitGain[iMSPredType] += fNumLines * ( pfMSPredRatio[iMSPredType] - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + move32(); + // pfMSPredBitGain[iMSPredType] += fNumLines * ( pfMSPredRatio[iMSPredType] - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + pfMSPredBitGain_fx[iMSPredType] = L_add( pfMSPredBitGain_fx[iMSPredType], + W_extract_l( W_shr( W_mult0_32_32( fNumLines_fx, + Mpy_32_32( Mpy_32_32( L_sub( pfMSPredRatio_fx[iMSPredType], fLRRatio_fx ), fLevelToSMRdBFactor_fx ), + fBitsFactor_fx ) ), + 7 ) ) ); // Q16 } } } - + Word16 q_fMSBitGain_fx = Q16; + move16(); + Word16 q_pfMSPredBitGain_fx = Q16; // Q23-7 + move16(); /* remove signalling cost from bit gains */ - for ( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) + FOR( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) { piMsPredInfoBits[iMSPredType] = CountMSBits( iNumBands, MS_PRED, ppiMSPredFlags[iMSPredType], ppiMSPredPhase[iMSPredType], ppiMSPredCoefs[iMSPredType] ); - pfMSPredBitGain[iMSPredType] = max( pfMSPredBitGain[iMSPredType] - piMsPredInfoBits[iMSPredType], 0.0f ); + // pfMSPredBitGain[iMSPredType] = max( pfMSPredBitGain[iMSPredType] - piMsPredInfoBits[iMSPredType], 0.0f ); + pfMSPredBitGain_fx[iMSPredType] = max( pfMSPredBitGain_fx[iMSPredType] - L_shl( piMsPredInfoBits[iMSPredType], q_pfMSPredBitGain_fx ), 0 ); } /* find the best M/S Pred type */ - if ( iRealOnlyOut == 1 ) + IF( EQ_32( iRealOnlyOut, 1 ) ) { iMSPredType = MS_PRED_ONLY; + move32(); } - else + ELSE { iMSPredType = MS_PHASE_AND_PRED; - iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); - iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); + move32(); + // iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); + iMSPredType = ( pfMSPredBitGain_fx[MS_PRED_ONLY] > pfMSPredBitGain_fx[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); + // iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); + iMSPredType = ( pfMSPredBitGain_fx[MS_PHASE_ONLY] > pfMSPredBitGain_fx[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); } /* plain M/S */ iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL ); - fMSBitGain = max( fMSBitGain - iMsInfoBits, 0.0f ); - if ( iAllowSidePred && pfMSPredBitGain[iMSPredType] > 1.1f * fMSBitGain ) + // fMSBitGain = max( fMSBitGain - iMsInfoBits, 0.0f ); + fMSBitGain_fx = L_max( L_sub( fMSBitGain_fx, L_shl( iMsInfoBits, q_fMSBitGain_fx ) ), 0 ); // Q_en -2 + // if ( iAllowSidePred && pfMSPredBitGain[iMSPredType] > 1.1f * fMSBitGain ) + test(); + IF( iAllowSidePred && GT_32( L_shr_r( pfMSPredBitGain_fx[iMSPredType], sub( q_pfMSPredBitGain_fx, q_fMSBitGain_fx ) ), L_add( fMSBitGain_fx, Mpy_32_32( fMSBitGain_fx, 214748364 ) ) ) ) { *piMSMode = MS_PRED; + move32(); iNumMSBands = 0; - for ( b = 0; b < iNumBands; b++ ) + move32(); + FOR( b = 0; b < iNumBands; b++ ) { piMSFlags[b] = ppiMSPredFlags[iMSPredType][b]; - if ( piMSFlags[b] == 1 ) + IF( EQ_32( piMSFlags[b], 1 ) ) { piMSPredCoefs[b] = ppiMSPredCoefs[iMSPredType][b]; + move32(); piLRPhaseDiffs[b] = ppiMSPredPhase[iMSPredType][b]; + move32(); iNumMSBands++; } - else + ELSE { piMSPredCoefs[b] = 0; + move32(); piLRPhaseDiffs[b] = 0; + move32(); } } } - else if ( iNumMSBands == iNumBands ) + ELSE IF( EQ_32( iNumMSBands, iNumBands ) ) { *piMSMode = MS_ALL; + move32(); } - else if ( iNumMSBands > 0 ) + ELSE IF( GT_32( iNumMSBands, 0 ) ) { *piMSMode = MS_SOME; + move32(); } - else + ELSE { *piMSMode = MS_OFF; + move32(); } #ifdef DEBUG_WRITE_MS_PRED { @@ -1036,54 +1202,71 @@ static int32_t MSModeCalculation( fprintf( fid, "%d %d %d %d %d\n", iMsInfoBits, piMsPredInfoBits[MS_PHASE_AND_PRED], piMsPredInfoBits[MS_PRED_ONLY], piMsPredInfoBits[MS_PHASE_ONLY], iActualInfoBits ); } #endif - if ( *piMSMode != MS_OFF ) + IF( NE_32( *piMSMode, MS_OFF ) ) { iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) + move32(); + FOR( b = 0; b < iNumBands; b++ ) { - if ( piMSFlags[b] == 1 ) + IF( EQ_32( piMSFlags[b], 1 ) ) { - int32_t n; - int32_t phaseIdx; - phaseIdx = piLRPhaseDiffs[b] - PHASE_MIN_VAL; - fPred = dequantPred( piMSPredCoefs[b] ); - for ( n = 0; n < piBandwidths[b]; n++ ) + Word32 n; + Word32 phaseIdx; + phaseIdx = L_sub( piLRPhaseDiffs[b], PHASE_MIN_VAL ); + // fPred = dequantPred( piMSPredCoefs[b] ); + fPred_fx = dequantPred_fx( piMSPredCoefs[b] ); // Q31 + FOR( n = 0; n < piBandwidths[b]; n++ ) { - int32_t k; - for ( k = 0; k < iNumBlocks; k++ ) + Word32 k; + FOR( k = 0; k < iNumBlocks; k++ ) { - float fMidReal; + /*float fMidReal; float fMidImag; float fSideReal; - float fSideImag; + float fSideImag;*/ + Word32 fMidReal_fx; + Word32 fMidImag_fx; + Word32 fSideReal_fx; + Word32 fSideImag_fx; - if ( *piMSMode == MS_PRED ) + IF( EQ_32( *piMSMode, MS_PRED ) ) { - cplxmult_lcld( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); + // cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); + cplxmult_fx( &pppfReal_fx[1][k][iFBOffset], &pppfImag_fx[1][k][iFBOffset], c_afRotRealImag_fx[phaseIdx][0], c_afRotRealImag_fx[phaseIdx][1] ); } - fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); - fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); - fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); - fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + // fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fMidReal_fx = L_shr( L_add( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 ); + // fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fMidImag_fx = L_shr( L_add( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 ); + // fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fSideReal_fx = L_shr( L_sub( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 ); + // fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + fSideImag_fx = L_shr( L_sub( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 ); - if ( *piMSMode == MS_PRED ) + IF( EQ_32( *piMSMode, MS_PRED ) ) { - fSideReal -= fPred * fMidReal; - fSideImag -= fPred * fMidImag; + // fSideReal -= fPred * fMidReal; + fSideReal_fx = L_sub( fSideReal_fx, Mpy_32_32( fPred_fx, fMidReal_fx ) ); + // fSideImag -= fPred * fMidImag; + fSideImag_fx = L_sub( fSideImag_fx, Mpy_32_32( fPred_fx, fMidImag_fx ) ); } - pppfReal[0][k][iFBOffset] = fMidReal; - pppfReal[1][k][iFBOffset] = fSideReal; - pppfImag[0][k][iFBOffset] = fMidImag; - pppfImag[1][k][iFBOffset] = fSideImag; + pppfReal_fx[0][k][iFBOffset] = fMidReal_fx; + move32(); + pppfReal_fx[1][k][iFBOffset] = fSideReal_fx; + move32(); + pppfImag_fx[0][k][iFBOffset] = fMidImag_fx; + move32(); + pppfImag_fx[1][k][iFBOffset] = fSideImag_fx; + move32(); } iFBOffset++; } } - else + ELSE { - iFBOffset += piBandwidths[b]; + iFBOffset = L_add( iFBOffset, piBandwidths[b] ); } } } @@ -1095,7 +1278,7 @@ static int32_t MSModeCalculation( writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); } #endif - if ( *piMSMode == MS_PRED ) + IF( EQ_32( *piMSMode, MS_PRED ) ) { /* Differential Coding of Phase Data*/ PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands ); @@ -1115,35 +1298,53 @@ static int32_t MSModeCalculation( return iNumMSBands; } - - static void RemoveRMSEnvelope( - const int32_t iNumBands, - const int32_t *piBandwidths, - const int32_t iNumGroups, - const int32_t *piGroupLengths, - int32_t **ppiRMSEnvelope, - float **ppfReal, - float **ppfImag ) + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 iNumGroups, + const Word32 *piGroupLengths, + Word32 **ppiRMSEnvelope, + Word32 **ppfReal_fx, + Word32 **ppfImag_fx ) { - int32_t k, n, b, iFBOffset, m, iRMSEnv; - int32_t iBlockOffset; - float fGain; - + Word32 k, n, b, iFBOffset, m, iRMSEnv; + Word32 iBlockOffset; + Word32 fGain_fx; + Word16 fGain_exp; iBlockOffset = 0; - for ( n = 0; n < iNumGroups; n++ ) + move32(); + Word64 tmp; + FOR( n = 0; n < iNumGroups; n++ ) { - for ( k = 0; k < piGroupLengths[n]; k++ ) + FOR( k = 0; k < piGroupLengths[n]; k++ ) { iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) + move32(); + FOR( b = 0; b < iNumBands; b++ ) { iRMSEnv = ppiRMSEnvelope[n][b]; - fGain = c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_CENTER - iRMSEnv]; - for ( m = 0; m < piBandwidths[b]; m++ ) + IF( EQ_32( L_add( ENV_RECONSTRUCT_TABLE_CENTER, iRMSEnv ) % 2, 0 ) ) { - ppfReal[iBlockOffset][iFBOffset] *= fGain; - ppfImag[iBlockOffset][iFBOffset] *= fGain; + fGain_fx = 1073741824; // 2 ^ 30 + move32(); + } + ELSE + { + fGain_fx = 1518500249; // sqrt(2) * 2 ^ 30 + move32(); + } + fGain_exp = c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_CENTER - iRMSEnv]; + move16(); + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + tmp = W_mult_32_32( fGain_fx, ppfReal_fx[iBlockOffset][iFBOffset] ); + tmp = W_shr( tmp, sub( fGain_exp, 8 ) ); // Q to (input_q -9) + ppfReal_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp ); + move32(); + tmp = W_mult_32_32( fGain_fx, ppfImag_fx[iBlockOffset][iFBOffset] ); + tmp = W_shr( tmp, sub( fGain_exp, 8 ) ); // Q to (input_q -9) + ppfImag_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp ); + move32(); iFBOffset++; } } @@ -1153,109 +1354,126 @@ static void RemoveRMSEnvelope( return; } - static void QuantizeSpectrumDPCM_Opt( - const int32_t iNumGroups, - const int32_t *piGroupLengths, - const int32_t iNumBands, - const int32_t *piBandwidths, - int32_t **ppiAlloc, - float **ppfReal, - float **ppfImag, - int32_t **ppiQReal, - int32_t **ppiQImag, - int32_t **ppiSignReal, - int32_t **ppiSignImag, - const int32_t iNumSubSets, - const int32_t iSubSetId, - const int32_t *piPredEnable, - float *pfA1Real, - float *pfA1Imag, - float *pfPredStateReal, - float *pfPredStateImag ) + const Word32 iNumGroups, + const Word32 *piGroupLengths, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 **ppiAlloc, + Word32 **ppfReal_fx, + Word32 **ppfImag_fx, + Word16 q_final, + Word32 **ppiQReal, + Word32 **ppiQImag, + Word32 **ppiSignReal, + Word32 **ppiSignImag, + Word32 iNumSubSets, + Word32 iSubSetId, + Word32 *piPredEnable, + Word32 *pfA1Real_fx, + Word32 *pfA1Imag_fx, + Word32 *pfPredStateReal_fx, + Word32 *pfPredStateImag_fx ) { - int32_t b, n; - int32_t iFBOffset; - int32_t k, iAlloc, iMaxQuantVal; - float fSCFGain, fInvSCFGain; - + Word32 b, n; + Word32 iFBOffset; + Word32 k, iAlloc; + Word32 iMaxQuantVal_fx; + Word32 fSCFGain_fx, fInvSCFGain_fx; iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) + Word32 ppiQReal_fx, ppiQImag_fx; + FOR( b = 0; b < iNumBands; b++ ) { - int32_t m; - for ( m = 0; m < piBandwidths[b]; m++ ) + Word32 m; + FOR( m = 0; m < piBandwidths[b]; m++ ) { - int32_t iBlockOffset = 0; - if ( piPredEnable[iFBOffset] == 1 ) + Word32 iBlockOffset = 0; + IF( EQ_32( piPredEnable[iFBOffset], 1 ) ) { - float fReal; - float fImag; - int32_t iSubset = iFBOffset % iNumSubSets; - float fPrevReal = 0.0f; - float fPrevImag = 0.0f; - if ( iSubset != iSubSetId ) + Word32 fReal_fx; + Word32 fImag_fx; + Word32 iSubset = iFBOffset % iNumSubSets; + Word32 fPrevReal_fx = 0; + Word32 fPrevImag_fx = 0; + IF( NE_32( iSubset, iSubSetId ) ) { /* run predictors across sub-frames */ - fPrevReal = pfPredStateReal[iFBOffset]; - fPrevImag = pfPredStateImag[iFBOffset]; + fPrevReal_fx = pfPredStateReal_fx[iFBOffset]; + move32(); + fPrevImag_fx = pfPredStateImag_fx[iFBOffset]; + move32(); } - for ( n = 0; n < iNumGroups; n++ ) + FOR( n = 0; n < iNumGroups; n++ ) { iAlloc = ppiAlloc[n][b]; - iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; - fSCFGain = c_afScaleFactor[iAlloc]; - fInvSCFGain = c_afInvScaleFactor[iAlloc]; - for ( k = 0; k < piGroupLengths[n]; k++ ) + iMaxQuantVal_fx = c_aiQuantMaxValues_fx[iAlloc]; + fSCFGain_fx = c_afScaleFactor_fx[iAlloc]; + fInvSCFGain_fx = c_afInvScaleFactor_fx[iAlloc]; + FOR( k = 0; k < piGroupLengths[n]; k++ ) { /* prediction */ - fReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; - fImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; - - ppiQReal[iBlockOffset][iFBOffset] = Quantize( ppfReal[iBlockOffset][iFBOffset] + fReal, /* quantize residual */ - fSCFGain, - &ppiSignReal[iBlockOffset][iFBOffset], - iMaxQuantVal ); - - ppiQImag[iBlockOffset][iFBOffset] = Quantize( ppfImag[iBlockOffset][iFBOffset] + fImag, - fSCFGain, - &ppiSignImag[iBlockOffset][iFBOffset], - iMaxQuantVal ); - - fPrevReal = UnQuantize( ppiQReal[iBlockOffset][iFBOffset], - fInvSCFGain, - ppiSignReal[iBlockOffset][iFBOffset] ) - - fReal; /* add prediction to quantized residual = reconstructed sample */ - - fPrevImag = UnQuantize( ppiQImag[iBlockOffset][iFBOffset], - fInvSCFGain, - ppiSignImag[iBlockOffset][iFBOffset] ) - - fImag; - + fReal_fx = L_sub( Mpy_32_32( pfA1Real_fx[iFBOffset], fPrevReal_fx ), Mpy_32_32( pfA1Imag_fx[iFBOffset], fPrevImag_fx ) ); + fImag_fx = L_add( Mpy_32_32( pfA1Real_fx[iFBOffset], fPrevImag_fx ), Mpy_32_32( pfA1Imag_fx[iFBOffset], fPrevReal_fx ) ); + ppiQReal_fx = Quantize_fx( L_add_sat( L_shr_r_sat( ppfReal_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), fReal_fx ), /* quantize residual */ + fSCFGain_fx, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal_fx ); + ppiQImag_fx = Quantize_fx( L_add_sat( L_shr_r_sat( ppfImag_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), fImag_fx ), + fSCFGain_fx, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal_fx ); + ppiQReal[iBlockOffset][iFBOffset] = L_shr( ppiQReal_fx, 21 ); + + ppiQImag[iBlockOffset][iFBOffset] = L_shr( ppiQImag_fx, 21 ); + + ppiQReal_fx = L_shl( ppiQReal[iBlockOffset][iFBOffset], 21 ); + fPrevReal_fx = L_sub( L_shl( UnQuantize_fx( ppiQReal_fx, + fInvSCFGain_fx, + ppiSignReal[iBlockOffset][iFBOffset] ), + 9 ), + fReal_fx ); + /* add prediction to quantized residual = reconstructed sample */ + + ppiQImag_fx = L_shl( ppiQImag[iBlockOffset][iFBOffset], 21 ); + fPrevImag_fx = L_sub( L_shl( UnQuantize_fx( ppiQImag_fx, + fInvSCFGain_fx, + ppiSignImag[iBlockOffset][iFBOffset] ), + 9 ), + fImag_fx ); iBlockOffset++; } /* group length */ } /* groups */ - pfPredStateReal[iFBOffset] = fPrevReal; - pfPredStateImag[iFBOffset] = fPrevImag; + pfPredStateReal_fx[iFBOffset] = fPrevReal_fx; + move32(); + pfPredStateImag_fx[iFBOffset] = fPrevImag_fx; + move32(); } /* predEnable */ - else + ELSE { /* no prediction */ - for ( n = 0; n < iNumGroups; n++ ) + FOR( n = 0; n < iNumGroups; n++ ) { iAlloc = ppiAlloc[n][b]; - iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; - fSCFGain = c_afScaleFactor[iAlloc]; - fInvSCFGain = c_afInvScaleFactor[iAlloc]; - for ( k = 0; k < piGroupLengths[n]; k++ ) + move32(); + iMaxQuantVal_fx = c_aiQuantMaxValues_fx[iAlloc]; + move32(); + fSCFGain_fx = c_afScaleFactor_fx[iAlloc]; + move32(); + fInvSCFGain_fx = c_afInvScaleFactor_fx[iAlloc]; + move32(); + FOR( k = 0; k < piGroupLengths[n]; k++ ) { - ppiQReal[iBlockOffset][iFBOffset] = Quantize( ppfReal[iBlockOffset][iFBOffset], - fSCFGain, - &ppiSignReal[iBlockOffset][iFBOffset], - iMaxQuantVal ); + ppiQReal_fx = Quantize_fx( L_shr_r_sat( ppfReal_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), + fSCFGain_fx, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal_fx ); + ppiQImag_fx = Quantize_fx( L_shr_r_sat( ppfImag_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), + fSCFGain_fx, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal_fx ); + + ppiQReal[iBlockOffset][iFBOffset] = L_shr( ppiQReal_fx, 21 ); - ppiQImag[iBlockOffset][iFBOffset] = Quantize( ppfImag[iBlockOffset][iFBOffset], - fSCFGain, - &ppiSignImag[iBlockOffset][iFBOffset], - iMaxQuantVal ); + ppiQImag[iBlockOffset][iFBOffset] = L_shr( ppiQImag_fx, 21 ); iBlockOffset++; } /* group length */ @@ -1263,89 +1481,96 @@ static void QuantizeSpectrumDPCM_Opt( } /* predEnable */ iFBOffset++; } /* bandwidth */ - } /* bands */ + } } - -static int32_t CountLCLDBits( - const int32_t iNumGroups, - const int32_t *piGroupLengths, - const int32_t iNumBands, - const int32_t *piBandwidths, - const int32_t *piPredEnable, - int32_t **ppiAlloc, - int32_t **ppiQReal, - int32_t **ppiQImag ) +static Word32 CountLCLDBits( + const Word32 iNumGroups, + const Word32 *piGroupLengths, + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 *piPredEnable, + Word32 **ppiAlloc, + Word32 **ppiQReal, + Word32 **ppiQImag ) { - int32_t k, n, b, iFBOffset; - int32_t iBits, iBlockOffest; - int32_t m, iAlloc, iHuffDim, iHuffMod; + Word32 k, n, b, iFBOffset; + Word32 iBits, iBlockOffest; + Word32 m, iAlloc, iHuffDim, iHuffMod; iBits = 0; + move32(); iBlockOffest = 0; - for ( n = 0; n < iNumGroups; n++ ) + move32(); + FOR( n = 0; n < iNumGroups; n++ ) { - for ( k = 0; k < piGroupLengths[n]; k++ ) + FOR( k = 0; k < piGroupLengths[n]; k++ ) { iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) + move32(); + FOR( b = 0; b < iNumBands; b++ ) { iAlloc = ppiAlloc[n][b]; + move32(); iHuffDim = c_aiHuffmanDim[iAlloc]; + move32(); iHuffMod = c_aiHuffmanMod[iAlloc]; + move32(); - if ( iAlloc > 0 ) + IF( GT_32( iAlloc, 0 ) ) { - const uint16_t( *pauiHuffmanTable )[2] = NULL; - const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; + const UWord16( *pauiHuffmanTable )[2] = NULL; + const UWord16( *pauiHuffmanTableDPCM )[2] = NULL; pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; - for ( m = 0; m < piBandwidths[b]; m++ ) + FOR( m = 0; m < piBandwidths[b]; m++ ) { - int32_t iQuantValue1; - int32_t iQuantValue2; + Word32 iQuantValue1; + Word32 iQuantValue2; iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; + move32(); iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; + move32(); - iBits += ( iQuantValue1 > 0 ) ? 1 : 0; /* Sign bit for vals > 0 */ - iBits += ( iQuantValue2 > 0 ) ? 1 : 0; /* Sign bit for vals > 0 */ + iBits = L_add( iBits, GT_32( iQuantValue1, 0 ) ? 1 : 0 ); /* Sign bit for vals > 0 */ + iBits = L_add( iBits, GT_32( iQuantValue2, 0 ) ? 1 : 0 ); /* Sign bit for vals > 0 */ - if ( piPredEnable[iFBOffset] == 1 ) + IF( EQ_32( piPredEnable[iFBOffset], 1 ) ) { - if ( iHuffDim == 2 ) + IF( EQ_32( iHuffDim, 2 ) ) { iQuantValue1 *= iHuffMod; - iQuantValue1 += iQuantValue2; - iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; + iQuantValue1 = L_add( iQuantValue1, iQuantValue2 ); + iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue1][0] ); } - else + ELSE { - iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; - iBits += pauiHuffmanTableDPCM[iQuantValue2][0]; + iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue1][0] ); + iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue2][0] ); } } - else + ELSE { - if ( iHuffDim == 2 ) + IF( EQ_32( iHuffDim, 2 ) ) { iQuantValue1 *= iHuffMod; - iQuantValue1 += iQuantValue2; - iBits += pauiHuffmanTable[iQuantValue1][0]; + iQuantValue1 = L_add( iQuantValue1, iQuantValue2 ); + iBits = L_add( iBits, pauiHuffmanTable[iQuantValue1][0] ); } - else + ELSE { - iBits += pauiHuffmanTable[iQuantValue1][0]; - iBits += pauiHuffmanTable[iQuantValue2][0]; + iBits = L_add( iBits, pauiHuffmanTable[iQuantValue1][0] ); + iBits = L_add( iBits, pauiHuffmanTable[iQuantValue2][0] ); } } iFBOffset++; } } - else + ELSE { - iFBOffset += piBandwidths[b]; + iFBOffset = L_add( iFBOffset, piBandwidths[b] ); } } @@ -1358,114 +1583,124 @@ static int32_t CountLCLDBits( /* Currently only the number of bands in frame */ -static int32_t WriteHeaderInformation( - const int32_t iNumBands, +static Word32 WriteHeaderInformation( + const Word32 iNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsWritten; + Word32 iBitsWritten; iBitsWritten = 0; + move32(); ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumBands, 5 ); - iBitsWritten += 5; + iBitsWritten = L_add( iBitsWritten, 5 ); return iBitsWritten; } -static int32_t WriteMSInformation( - const int32_t iNumBands, - const int32_t iMSMode, - const int32_t *piMSFlags, - const int32_t *piLRPhaseDiff, - const int32_t *piMSPredCoef, - int32_t iNumMSPredBands, +static Word32 WriteMSInformation( + const Word32 iNumBands, + const Word32 iMSMode, + const Word32 *piMSFlags, + const Word32 *piLRPhaseDiff, + const Word32 *piMSPredCoef, + Word32 iNumMSPredBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsWritten; - int32_t iMSPredAll = ( iNumMSPredBands == iNumBands ); + Word32 iBitsWritten; + Word32 iMSPredAll = (Word32) EQ_32( iNumMSPredBands, iNumBands ); + move32(); #ifdef DEBUG_WRITE_MS_PRED - int32_t iBitsWrittenTmp = 0; + Word32 iBitsWrittenTmp = 0; + move32(); #endif iBitsWritten = 0; + move32(); ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSMode, 2 ); - iBitsWritten += 2; + iBitsWritten = L_add( iBitsWritten, 2 ); - if ( iMSMode == 3 ) + IF( EQ_32( iMSMode, 3 ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSPredAll, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } - if ( iMSMode == 2 || ( iMSMode == 3 && !iMSPredAll ) ) + test(); + test(); + IF( EQ_32( iMSMode, 2 ) || ( EQ_32( iMSMode, 3 ) && !iMSPredAll ) ) { - int32_t n; - for ( n = 0; n < iNumBands; n++ ) + Word32 n; + FOR( n = 0; n < iNumBands; n++ ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSFlags[n], 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } } #ifdef DEBUG_WRITE_MS_PRED iBitsWrittenTmp = iBitsWritten; #endif - if ( iMSMode == 3 ) + IF( EQ_32( iMSMode, 3 ) ) { - int32_t b; - int32_t anyNonZero; + Word32 b; + Word32 anyNonZero; anyNonZero = 0; - for ( b = 0; b < iNumMSPredBands; b++ ) + move32(); + FOR( b = 0; b < iNumMSPredBands; b++ ) { - if ( piLRPhaseDiff[b] != 0 ) + IF( NE_32( piLRPhaseDiff[b], 0 ) ) { anyNonZero = 1; - break; + move32(); + BREAK; } } ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); iBitsWritten++; - if ( anyNonZero ) + IF( anyNonZero ) { - ISAR_SPLIT_REND_BITStream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS ); - iBitsWritten += PHASE_BAND0_BITS; - for ( b = 1; b < iNumMSPredBands; b++ ) + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( piLRPhaseDiff[0], PHASE_MIN_VAL ), PHASE_BAND0_BITS ); + iBitsWritten = L_add( iBitsWritten, PHASE_BAND0_BITS ); + FOR( b = 1; b < iNumMSPredBands; b++ ) { - int32_t tabIdx = piLRPhaseDiff[b] - ENV_DELTA_MIN; + Word32 tabIdx = L_sub( piLRPhaseDiff[b], ENV_DELTA_MIN ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); - iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] ); } } anyNonZero = 0; - for ( b = 0; b < iNumMSPredBands; b++ ) + move32(); + FOR( b = 0; b < iNumMSPredBands; b++ ) { - if ( piMSPredCoef[b] != 0 ) + IF( NE_32( piMSPredCoef[b], 0 ) ) { anyNonZero = 1; - break; + move32(); + BREAK; } } ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); iBitsWritten++; - if ( anyNonZero ) + IF( anyNonZero ) { - ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSPredCoef[0] - PRED_MIN_VAL, PRED_BAND0_BITS ); - iBitsWritten += PRED_BAND0_BITS; - for ( b = 1; b < iNumMSPredBands; b++ ) + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( piMSPredCoef[0], PRED_MIN_VAL ), PRED_BAND0_BITS ); + iBitsWritten = L_add( iBitsWritten, PRED_BAND0_BITS ); + FOR( b = 1; b < iNumMSPredBands; b++ ) { - int32_t tabIdx = piMSPredCoef[b] - ENV_DELTA_MIN; + Word32 tabIdx = L_sub( piMSPredCoef[b], ENV_DELTA_MIN ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); - iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] ); } } } #ifdef DEBUG_WRITE_MS_PRED { static FILE *fid = 0; - if ( !fid ) + IF( !fid ) { fid = fopen( "ms_pred_bitrate.txt", "wt" ); } @@ -1477,73 +1712,75 @@ static int32_t WriteMSInformation( } -static int32_t WriteGroupInformation( - const int32_t iChannels, - const int32_t iCommonGrouping, - const int32_t *piNumGroups, - int32_t **ppiGroupLengths, +static Word32 WriteGroupInformation( + const Word32 iChannels, + const Word32 iCommonGrouping, + const Word32 *piNumGroups, + Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t c, k, n, iBitsWritten; + Word32 c, k, n, iBitsWritten; iBitsWritten = 0; - if ( iChannels == 2 && iCommonGrouping == 1 ) + move32(); + test(); + IF( EQ_32( iChannels, 2 ) && EQ_32( iCommonGrouping, 1 ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); - for ( n = 0; n < piNumGroups[0]; n++ ) + FOR( n = 0; n < piNumGroups[0]; n++ ) { - for ( k = 1; k < ppiGroupLengths[0][n]; k++ ) + FOR( k = 1; k < ppiGroupLengths[0][n]; k++ ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } - if ( n < ( piNumGroups[0] - 1 ) ) + IF( LT_32( n, L_sub( piNumGroups[0], 1 ) ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } } } - else if ( iChannels == 2 ) + ELSE IF( EQ_32( iChannels, 2 ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); - for ( c = 0; c < iChannels; c++ ) + FOR( c = 0; c < iChannels; c++ ) { - for ( n = 0; n < piNumGroups[c]; n++ ) + FOR( n = 0; n < piNumGroups[c]; n++ ) { - for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) + FOR( k = 1; k < ppiGroupLengths[c][n]; k++ ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } - if ( n < ( piNumGroups[c] - 1 ) ) + IF( LT_32( n, L_sub( piNumGroups[c], 1 ) ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } } } } - else + ELSE { - for ( c = 0; c < iChannels; c++ ) + FOR( c = 0; c < iChannels; c++ ) { - for ( n = 0; n < piNumGroups[c]; n++ ) + FOR( n = 0; n < piNumGroups[c]; n++ ) { - for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) + FOR( k = 1; k < ppiGroupLengths[c][n]; k++ ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } - if ( n < ( piNumGroups[c] - 1 ) ) + IF( LT_32( n, L_sub( piNumGroups[c], 1 ) ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } } } @@ -1553,42 +1790,49 @@ static int32_t WriteGroupInformation( } -static int32_t WriteRMSEnvelope( - const int32_t iChannels, - const int32_t *piNumGroups, - const int32_t iNumBands, - int32_t ***pppiRMSEnvelope, +static Word32 WriteRMSEnvelope( + const Word32 iChannels, + const Word32 *piNumGroups, + const Word32 iNumBands, + Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t k, n; - int32_t iBitsWritten; + Word32 k, n; + Word32 iBitsWritten; iBitsWritten = 0; - for ( n = 0; n < iChannels; n++ ) + move32(); + FOR( n = 0; n < iChannels; n++ ) { - for ( k = 0; k < piNumGroups[n]; k++ ) + FOR( k = 0; k < piNumGroups[n]; k++ ) { - int32_t b; - int32_t iLastRMSVal; + Word32 b; + Word32 iLastRMSVal; iLastRMSVal = pppiRMSEnvelope[n][k][0]; - iLastRMSVal = ( iLastRMSVal > ENV_MIN ) ? iLastRMSVal : ENV_MIN; - iLastRMSVal = ( iLastRMSVal < ENV_MAX ) ? iLastRMSVal : ENV_MAX; - ISAR_SPLIT_REND_BITStream_write_int32( pBits, ( iLastRMSVal - ENV_MIN ), ENV0_BITS ); - iBitsWritten += ENV0_BITS; - - for ( b = 1; b < iNumBands; b++ ) + move32(); + iLastRMSVal = GT_32( iLastRMSVal, ENV_MIN ) ? iLastRMSVal : ENV_MIN; + move32(); + iLastRMSVal = LT_32( iLastRMSVal, ENV_MAX ) ? iLastRMSVal : ENV_MAX; + move32(); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iLastRMSVal, ENV_MIN ), ENV0_BITS ); + iBitsWritten = L_add( iBitsWritten, ENV0_BITS ); + + FOR( b = 1; b < iNumBands; b++ ) { - int32_t iDelta; - - iDelta = pppiRMSEnvelope[n][k][b] - iLastRMSVal; - iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN; - iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX; - iDelta -= ENV_DELTA_MIN; + Word32 iDelta; + + iDelta = L_sub( pppiRMSEnvelope[n][k][b], iLastRMSVal ); + iDelta = GT_32( iDelta, ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN; + move32(); + iDelta = LT_32( iDelta, ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX; + move32(); + iDelta = L_sub( iDelta, ENV_DELTA_MIN ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] ); - iBitsWritten += c_aaiRMSEnvHuffEnc[iDelta][0]; + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[iDelta][0] ); iLastRMSVal = pppiRMSEnvelope[n][k][b]; + move32(); } } } @@ -1597,143 +1841,155 @@ static int32_t WriteRMSEnvelope( } -static int32_t WriteAllocInformation( - const int32_t iAllocOffset, +static Word32 WriteAllocInformation( + const Word32 iAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsWritten; + Word32 iBitsWritten; iBitsWritten = 0; + move32(); - if ( iAllocOffset < MIN_ALLOC_OFFSET || iAllocOffset > MAX_ALLOC_OFFSET ) + IF( LT_32( iAllocOffset, MIN_ALLOC_OFFSET ) || GT_32( iAllocOffset, MAX_ALLOC_OFFSET ) ) { printf( "Serious error\n" ); } - ISAR_SPLIT_REND_BITStream_write_int32( pBits, ( iAllocOffset - MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS ); - iBitsWritten += ALLOC_OFFSET_BITS; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iAllocOffset, MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS ); + iBitsWritten = L_add( iBitsWritten, ALLOC_OFFSET_BITS ); return iBitsWritten; } -static int32_t WriteLCLDData( - const int32_t *piNumGroups, - int32_t **ppiGroupLengths, - const int32_t iNumBands, - const int32_t iNumChannels, - int32_t **ppiPredEnable, - const int32_t iNumSubSets, - const int32_t iSubSetId, - int32_t ***pppiAlloc, - int32_t ***pppiSignReal, - int32_t ***pppiSignImag, - int32_t ***pppiQReal, - int32_t ***pppiQImag, + +static Word32 WriteLCLDData( + const Word32 *piNumGroups, + Word32 **ppiGroupLengths, + const Word32 iNumBands, + const Word32 iNumChannels, + Word32 **ppiPredEnable, + const Word32 iNumSubSets, + const Word32 iSubSetId, + Word32 ***pppiAlloc, + Word32 ***pppiSignReal, + Word32 ***pppiSignImag, + Word32 ***pppiQReal, + Word32 ***pppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsWritten; - int32_t iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; - int32_t s; - int32_t iSet = iSubSetId; + Word32 iBitsWritten; + Word32 iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; + Word32 s; + Word32 iSet = iSubSetId; iBitsWritten = 0; - for ( s = 0; s < iNumSubSets; s++, iSet-- ) + move32(); + FOR( s = 0; s < iNumSubSets; ( s++, iSet-- ) ) { - int32_t ch; - if ( iSet < 0 ) + Word32 ch; + IF( LT_32( iSet, 0 ) ) { - iSet = iNumSubSets - 1; + iSet = L_sub( iNumSubSets, 1 ); } - for ( ch = 0; ch < iNumChannels; ch++ ) + FOR( ch = 0; ch < iNumChannels; ch++ ) { - int32_t iBlockOffest = 0; - int32_t n; - for ( n = 0; n < piNumGroups[ch]; n++ ) + Word32 iBlockOffest = 0; + move32(); + Word32 n; + FOR( n = 0; n < piNumGroups[ch]; n++ ) { - int32_t k; - for ( k = 0; k < ppiGroupLengths[ch][n]; k++ ) + Word32 k; + FOR( k = 0; k < ppiGroupLengths[ch][n]; k++ ) { - int32_t iFBOffset; - for ( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) + Word32 iFBOffset; + FOR( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) { - int32_t b; - int32_t iAlloc; - int32_t iHuffDim; - int32_t iHuffMod; + Word32 b; + Word32 iAlloc; + Word32 iHuffDim; + Word32 iHuffMod; b = c_aiBandIdPerLcldBand[iFBOffset]; + move32(); iAlloc = pppiAlloc[ch][n][b]; + move32(); iHuffDim = c_aiHuffmanDim[iAlloc]; + move32(); iHuffMod = c_aiHuffmanMod[iAlloc]; + move32(); - if ( iAlloc > 0 ) + IF( GT_32( iAlloc, 0 ) ) { - const uint16_t( *pauiHuffmanTable )[2] = NULL; - const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; - int32_t iQuantValue1; - int32_t iQuantValue2; + const UWord16( *pauiHuffmanTable )[2] = NULL; + const UWord16( *pauiHuffmanTableDPCM )[2] = NULL; + Word32 iQuantValue1; + Word32 iQuantValue2; pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; iQuantValue1 = pppiQReal[ch][iBlockOffest][iFBOffset]; + move32(); iQuantValue2 = pppiQImag[ch][iBlockOffest][iFBOffset]; + move32(); #ifdef LCLD_HANDLE_PRED_START_SAMPLE - if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) + IF( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) #else - if ( ppiPredEnable[ch][iFBOffset] == 1 ) + IF( EQ_32( ppiPredEnable[ch][iFBOffset], 1 ) ) #endif { - if ( iHuffDim == 2 ) + IF( EQ_32( iHuffDim, 2 ) ) { - int32_t iSymbol; + Word32 iSymbol; iSymbol = iQuantValue1; + move32(); iSymbol *= iHuffMod; - iSymbol += iQuantValue2; + iSymbol = L_add( iSymbol, iQuantValue2 ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iSymbol][0]; + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iSymbol][0] ); } - else + ELSE { ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iQuantValue1][0]; + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iQuantValue1][0] ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iQuantValue2][0]; + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iQuantValue2][0] ); } } - else + ELSE { - if ( iHuffDim == 2 ) + IF( EQ_32( iHuffDim, 2 ) ) { - int32_t iSymbol; + Word32 iSymbol; iSymbol = iQuantValue1; + move32(); iSymbol *= iHuffMod; - iSymbol += iQuantValue2; + iSymbol = L_add( iSymbol, iQuantValue2 ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] ); - iBitsWritten += pauiHuffmanTable[iSymbol][0]; + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iSymbol][0] ); } - else + ELSE { ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] ); - iBitsWritten += pauiHuffmanTable[iQuantValue1][0]; + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iQuantValue1][0] ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] ); - iBitsWritten += pauiHuffmanTable[iQuantValue2][0]; + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iQuantValue2][0] ); } } - if ( iQuantValue1 > 0 ) + IF( GT_32( iQuantValue1, 0 ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignReal[ch][iBlockOffest][iFBOffset], 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } - if ( iQuantValue2 > 0 ) + IF( GT_32( iQuantValue2, 0 ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignImag[ch][iBlockOffest][iFBOffset], 1 ); - iBitsWritten += 1; + iBitsWritten = L_add( iBitsWritten, 1 ); } } } @@ -1745,70 +2001,74 @@ static int32_t WriteLCLDData( return iBitsWritten; } - -static int32_t ComputeAllocation( - const int32_t iChannels, - const int32_t *piNumGroups, - int32_t **ppiGroupLengths, - const int32_t iNumBands, - const int32_t *piBandwidths, - float ***pppfReal, - float ***pppfImag, - int32_t ***pppiSMR, - const int32_t iAvailableBits, - int32_t *piAllocOffset, - int32_t ***pppiAlloc, - int32_t ***pppiQReal, - int32_t ***pppiQImag, - int32_t ***pppiSignReal, - int32_t ***pppiSignImag, +static Word32 ComputeAllocation( + const Word32 iChannels, + const Word32 *piNumGroups, + Word32 **ppiGroupLengths, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + Word16 q_final, + Word32 ***pppiSMR, + const Word32 iAvailableBits, + Word32 *piAllocOffset, + Word32 ***pppiAlloc, + Word32 ***pppiQReal, + Word32 ***pppiQImag, + Word32 ***pppiSignReal, + Word32 ***pppiSignImag, PredictionEncoder *psPredictionEncoder ) { - int32_t iBitsUsed, iDone, iDelta; - int32_t b, k, n; - int32_t iLimitAllocOffset; + Word32 iBitsUsed, iDone, iDelta; + Word32 b, k, n; + Word32 iLimitAllocOffset; iBitsUsed = ALLOC_OFFSET_BITS; /* Bits used for Alloc Offset */ - + move32(); iDone = 0; + move32(); iDelta = -MIN_ALLOC_OFFSET; + move32(); *piAllocOffset = 0; - - while ( iDone == 0 ) + move32(); + WHILE( EQ_32( iDone, 0 ) ) { iBitsUsed = ALLOC_OFFSET_BITS; - + move32(); iLimitAllocOffset = *piAllocOffset; - iLimitAllocOffset = ( iLimitAllocOffset > MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET; - iLimitAllocOffset = ( iLimitAllocOffset < MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET; + move32(); + iLimitAllocOffset = GT_32( iLimitAllocOffset, MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET; + iLimitAllocOffset = LT_32( iLimitAllocOffset, MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET; - for ( n = 0; n < iChannels; n++ ) + FOR( n = 0; n < iChannels; n++ ) { - for ( k = 0; k < piNumGroups[n]; k++ ) + FOR( k = 0; k < piNumGroups[n]; k++ ) { - for ( b = 0; b < iNumBands; b++ ) + FOR( b = 0; b < iNumBands; b++ ) { - int32_t iAlloc; - iAlloc = ( ( pppiSMR[n][k][b] + iLimitAllocOffset * ALLOC_OFFSET_SCALE ) >> 5 ); - iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC; - iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC; + Word32 iAlloc; + iAlloc = ( L_shr( L_add( pppiSMR[n][k][b], L_mult0( extract_l( iLimitAllocOffset ), ALLOC_OFFSET_SCALE ) ), 5 ) ); + iAlloc = GT_32( iAlloc, MIN_ALLOC ) ? iAlloc : MIN_ALLOC; + iAlloc = LT_32( iAlloc, MAX_ALLOC ) ? iAlloc : MAX_ALLOC; pppiAlloc[n][k][b] = iAlloc; + move32(); } } - - if ( psPredictionEncoder->iNumSubSets > 1 ) + IF( psPredictionEncoder->iNumSubSets > 1 ) { - mvr2r( psPredictionEncoder->ppfPredStateReal[n], psPredictionEncoder->ppfPredStateRealTmp[n], LCLD_BANDS ); - mvr2r( psPredictionEncoder->ppfPredStateImag[n], psPredictionEncoder->ppfPredStateImagTmp[n], LCLD_BANDS ); + mvl2l( psPredictionEncoder->ppfPredStateReal_fx[n], psPredictionEncoder->ppfPredStateRealTmp_fx[n], LCLD_BANDS ); + mvl2l( psPredictionEncoder->ppfPredStateImag_fx[n], psPredictionEncoder->ppfPredStateImagTmp_fx[n], LCLD_BANDS ); } QuantizeSpectrumDPCM_Opt( piNumGroups[n], - (const int32_t *) ppiGroupLengths[n], + (const Word32 *) ppiGroupLengths[n], iNumBands, piBandwidths, pppiAlloc[n], - pppfReal[n], - pppfImag[n], + pppfReal_fx[n], + pppfImag_fx[n], + q_final, pppiQReal[n], pppiQImag[n], pppiSignReal[n], @@ -1816,78 +2076,68 @@ static int32_t ComputeAllocation( psPredictionEncoder->iNumSubSets, psPredictionEncoder->iSubSetId, psPredictionEncoder->ppiPredBandEnable[n], - psPredictionEncoder->ppfA1Real[n], - psPredictionEncoder->ppfA1Imag[n], - psPredictionEncoder->ppfPredStateRealTmp[n], - psPredictionEncoder->ppfPredStateImagTmp[n] ); - - iBitsUsed += CountLCLDBits( piNumGroups[n], - (const int32_t *) ppiGroupLengths[n], - iNumBands, - piBandwidths, - (const int32_t *) psPredictionEncoder->ppiPredBandEnable[n], - pppiAlloc[n], - pppiQReal[n], - pppiQImag[n] ); + psPredictionEncoder->ppfA1Real_fx[n], + psPredictionEncoder->ppfA1Imag_fx[n], + psPredictionEncoder->ppfPredStateRealTmp_fx[n], + psPredictionEncoder->ppfPredStateImagTmp_fx[n] ); + iBitsUsed = L_add( iBitsUsed, CountLCLDBits( piNumGroups[n], + (const Word32 *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + (const Word32 *) psPredictionEncoder->ppiPredBandEnable[n], + pppiAlloc[n], + pppiQReal[n], + pppiQImag[n] ) ); } - if ( *piAllocOffset <= MIN_ALLOC_OFFSET && iBitsUsed > iAvailableBits ) + IF( LE_32( *piAllocOffset, MIN_ALLOC_OFFSET ) && GT_32( iBitsUsed, iAvailableBits ) ) { #ifdef DEBUG_VERBOSE printf( "Frame can not be coded with the number of bits available\n" ); #endif - /* iLastError = ENC_ERROR_STREAM_FAILURE;*/ + // iLastError = ENC_ERROR_STREAM_FAILURE; return -1; } - else if ( *piAllocOffset >= MAX_ALLOC_OFFSET && iBitsUsed < iAvailableBits ) + ELSE IF( GE_32( *piAllocOffset, MAX_ALLOC_OFFSET ) && LT_32( iBitsUsed, iAvailableBits ) ) { *piAllocOffset = MAX_ALLOC_OFFSET; iDone++; } - else + ELSE { - if ( iDelta == 0 && iBitsUsed > iAvailableBits ) + IF( EQ_32( iDelta, 0 ) && GT_32( iBitsUsed, iAvailableBits ) ) { iDelta = 1; } - else if ( iDelta == 0 && iBitsUsed < iAvailableBits ) + ELSE IF( EQ_32( iDelta, 0 ) && LT_32( iBitsUsed, iAvailableBits ) ) { iDone++; } - else if ( iBitsUsed == iAvailableBits ) + ELSE IF( EQ_32( iBitsUsed, iAvailableBits ) ) { iDone++; } - if ( iBitsUsed > iAvailableBits ) + IF( GT_32( iBitsUsed, iAvailableBits ) ) { *piAllocOffset -= iDelta; - iDelta >>= 1; + iDelta = L_shr( iDelta, 1 ); } - else if ( iBitsUsed < iAvailableBits ) + ELSE IF( LT_32( iBitsUsed, iAvailableBits ) ) { *piAllocOffset += iDelta; - iDelta >>= 1; + iDelta = L_shr( iDelta, 1 ); } } } - - if ( psPredictionEncoder->iNumSubSets > 1 ) + IF( GT_32( psPredictionEncoder->iNumSubSets, 1 ) ) { - for ( n = 0; n < iChannels; n++ ) + FOR( n = 0; n < iChannels; n++ ) { - mvr2r( psPredictionEncoder->ppfPredStateRealTmp[n], psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS ); - mvr2r( psPredictionEncoder->ppfPredStateImagTmp[n], psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS ); + mvl2l( psPredictionEncoder->ppfPredStateRealTmp_fx[n], psPredictionEncoder->ppfPredStateReal_fx[n], LCLD_BANDS ); + mvl2l( psPredictionEncoder->ppfPredStateImagTmp_fx[n], psPredictionEncoder->ppfPredStateImag_fx[n], LCLD_BANDS ); } } - - /* - printf("%d\n",*piAllocOffset); - printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]); - - printf("%d\t%d\t%d\t%d\n",*piAllocOffset,iAvailableBits,iBitsUsed,iAvailableBits - iBitsUsed); - */ - return iBitsUsed; } #endif diff --git a/lib_isar/isar_lcld_prot.h b/lib_isar/isar_lcld_prot.h index d3ce8cc96..a37134857 100644 --- a/lib_isar/isar_lcld_prot.h +++ b/lib_isar/isar_lcld_prot.h @@ -35,78 +35,95 @@ #include "options.h" #ifdef SPLIT_REND_WITH_HEAD_ROT +#include "typedef.h" #include "common_api_types.h" -#include "isar_rom_lcld_tables.h" - +#include "isar_lcld_rom_tables.h" +// #include "prot.h" /* clang-format off */ typedef struct LCLD_ENCODER LCLDEncoder; ivas_error CreateLCLDEncoder( LCLDEncoder **psLCLDEncoder_out, - const int32_t iSampleRate, - const int32_t iChannels, - const int32_t iTargetBitRate, - const int32_t iAllowSidePred, - const int16_t iNumBlocks, - const int16_t iNumSubSets, - const int32_t iRealOnlyOut - ); - + const Word32 iSampleRate, + const Word32 iChannels, + const Word32 iTargetBitRate, + const Word32 iAllowSidePred, + const Word16 iNumBlocks, + const Word16 iNumSubSets, + const Word32 iRealOnlyOut); void DeleteLCLDEncoder( LCLDEncoder *psLCLDEncoder ); -int32_t EncodeLCLDFrame( +Word32 EncodeLCLDFrame( LCLDEncoder *psLCLDEncoder, - float ***pppfLCLDReal, - float ***pppfLCLDImag, - int32_t *piNumiBites, - const int32_t available_bits, - ISAR_SPLIT_REND_BITS_HANDLE pBits ); + Word32 ***pppfLCLDReal_fx, + Word32 ***pppfLCLDImag_fx, + Word32 *piNumiBites, + const Word32 available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word16 *q_final); + +Word32 GetNumGroups( + LCLDEncoder *psLCLDEncoder +); typedef struct LCLD_DECODER LCLDDecoder; ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, - const int32_t iSampleRate, - const int32_t iChannels, - const int32_t iNumBlocks, - const int32_t iRealOnlyOut); + const Word32 iSampleRate, + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iRealOnlyOut); + void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ); -int32_t DecodeLCLDFrame( +Word32 DecodeLCLDFrame( LCLDDecoder *psLCLDDecoder, ISAR_SPLIT_REND_BITS_HANDLE pBits, - float ***pppfLCLDReal, - float ***pppfLCLDImag + Word32 ***pppfLCLDReal_fx, + Word32 ***pppfLCLDImag_fx, + Word16 Q_in, + Word16 *Q_out ); - /*----------------------------------------------------------------------------------* * MSPred prototypes *----------------------------------------------------------------------------------*/ +Word32 quantPhase_fx( + Word32 phase, + Word16 exp); int32_t quantPhase( float phase ); -void cplxmult_lcld( +void cplxmult( float *pr1, float *pi1, - const float r2, - const float i2 + float r2, + float i2 +); +void cplxmult_fx( + Word32 *pr1, + Word32 *pi1, + Word32 r2, + Word32 i2 ); - -int32_t requantPhase( - int32_t phaseQ +Word32 requantPhase( + Word32 phaseQ ); +Word32 quantPred_fx( + const Word32 pred, + Word16 exp); int32_t quantPred( const float pred ); @@ -118,33 +135,35 @@ float dequantPhase( float dequantPred( int32_t predQ ); - -int32_t PrepEncode( - int32_t *piQuant, - const int32_t *piMSFlags, - const int32_t numBands +Word32 dequantPred_fx( + Word32 predQ +); +Word32 PrepEncode( + Word32 *piQuant, + const Word32 *piMSFlags, + const Word32 numBands ); void EncodePhase( - int32_t *phaseQuant, - const int32_t numMSBands, - const int32_t diffDim + Word32 *phaseQuant, + const Word32 numMSBands, + const Word32 diffDim ); void DecodePhase( - int32_t *phaseQuant, - const int32_t numMSBands, - const int32_t diffDim + Word32 *phaseQuant, + const Word32 numMSBands, + const Word32 diffDim ); -int32_t EncodePredCoef( - int32_t *predQuant, - const int32_t numMSBands +Word32 EncodePredCoef( + Word32 *predQuant, + const Word32 numMSBands ); void DecodePredCoef( - int32_t *phaseQuant, - const int32_t numMSBands + Word32 *phaseQuant, + const Word32 numMSBands ); void writeMSPred( @@ -157,12 +176,12 @@ void writeMSPred( int32_t *piMsFlags ); -int32_t CountMSBits( - int32_t iNumBands, - const int32_t iMSMode, - const int32_t *piMSFlags, - const int32_t *piLRPhaseDiff, - const int32_t *piMSPredCoef +Word32 CountMSBits( + Word32 iNumBands, + const Word32 iMSMode, + const Word32 *piMSFlags, + const Word32 *piLRPhaseDiff, + const Word32 *piMSPredCoef ); @@ -192,7 +211,16 @@ inline float GetNoise( NoiseGen *psNoiseGen ) return fNoiseSample; } +inline Word32 GetNoise_fx( NoiseGen *psNoiseGen ) +{ + Word32 fNoiseSample; + fNoiseSample = (Word32) (psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex]* (1<<14)); + psNoiseGen->iNoiseBufferIndex++; + psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask; + + return fNoiseSample; +} /*----------------------------------------------------------------------------------* * PereptualModel prototypes @@ -204,7 +232,23 @@ extern void PerceptualModel( int32_t *piExcitation, int32_t *piSMR ); +extern void PerceptualModel_fx( + const Word32 iMaxQuantBands, + const Word32 *piRMSEnvelope, + Word32 *piExcitation, + Word32 *piSMR +); +extern void PerceptualModelStereo_fx( + const Word32 iMaxQuantBands, + const Word32 *piMSFlags, + const Word32 *piRMSEnvelope0, + const Word32 *piRMSEnvelope1, + Word32 *piExcitation0, + Word32 *piExcitation1, + Word32 *piSMR0, + Word32 *piSMR1 +); extern void PerceptualModelStereo( const int32_t iMaxQuantBands, const int32_t *piMSFlags, @@ -229,6 +273,14 @@ typedef struct PREDICTION_ENCODER int32_t iSubSetId; int32_t iNumSubSets; int32_t iMaxNumPredBands; + Word32 ***pppfInpBufReal_fx; /* channels, LCLD_PRED_WIN_LEN, bands */ + Word32 ***pppfInpBufImag_fx; + Word32 **ppfPredStateReal_fx; /* channels, bands */ + Word32 **ppfPredStateImag_fx; + Word32 **ppfPredStateRealTmp_fx; + Word32 **ppfPredStateImagTmp_fx; + Word32 **ppfInpPrevReal_fx; /* channels, bands */ + Word32 **ppfInpPrevImag_fx; float ***pppfInpBufReal; /* channels, LCLD_PRED_WIN_LEN, bands */ float ***pppfInpBufImag; float **ppfPredStateReal; /* channels, bands */ @@ -237,6 +289,8 @@ typedef struct PREDICTION_ENCODER float **ppfPredStateImagTmp; float **ppfInpPrevReal; /* channels, bands */ float **ppfInpPrevImag; + Word32 pfRxxReal_fx[2]; + Word32 pfRxxImag_fx[2]; float pfRxxReal[2]; float pfRxxImag[2]; @@ -244,6 +298,8 @@ typedef struct PREDICTION_ENCODER int32_t *piNumPredBands; int32_t **ppiPredBandEnable; + Word32 **ppfA1Real_fx; + Word32 **ppfA1Imag_fx; float **ppfA1Real; float **ppfA1Imag; @@ -251,6 +307,15 @@ typedef struct PREDICTION_ENCODER int32_t **ppiA1Phase; } PredictionEncoder; +ivas_error CreatePredictionEncoder_fx( + PredictionEncoder **psPredictionEncoder_out, + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iNumSubSets, + const Word32 iMaxNumPredBands ); + +void DeletePredictionEncoder_fx( + PredictionEncoder *psPredictionEncoder ); ivas_error CreatePredictionEncoder( PredictionEncoder **psPredictionEncoder_out, const int32_t iChannels, @@ -268,12 +333,15 @@ void ComputePredictors( float ***pppfReal, float ***pppfImag ); +void ComputePredictors_fx( + PredictionEncoder *psPredictionEncoder, + Word32 ***pppfReal_fx, //Q12? + Word32 ***pppfImag_fx); //Q12? -int32_t WritePredictors( +Word32 WritePredictors( PredictionEncoder *psPredictionEncoder, - ISAR_SPLIT_REND_BITS_HANDLE pBits -); + ISAR_SPLIT_REND_BITS_HANDLE pBits ); typedef struct PREDICTION_DECODER { @@ -281,42 +349,39 @@ typedef struct PREDICTION_DECODER int32_t iNumBlocks; int32_t iSubSetId; int32_t iNumSubSets; - float **ppfPredStateReal; - float **ppfPredStateImag; + Word32 **ppfPredStateReal_fx; + Word32 **ppfPredStateImag_fx; int32_t *piPredChanEnable; int32_t **ppiPredBandEnable; - - /* PLC_IMPROVEMENT */ + /* PLC_IMPROVEMENT */ int32_t **ppiDecodingUnresolved; int32_t **ppiDecodingFailed; int32_t **ppiDecodingFailedPrev; - - float **ppfA1Real; - float **ppfA1Imag; + Word32 **ppfA1Real_fx; /* Q31 */ + Word32 **ppfA1Imag_fx; /* Q31 */ int32_t **ppiA1Mag; int32_t **ppiA1Phase; - float pfMagLUT[1 << PRED_QUNAT_FILTER_MAG_BITS]; - float pfP2RRealLUT[1 << PRED_QUANT_FILTER_PHASE_BITS]; - float pfP2RImagLUT[1 << PRED_QUANT_FILTER_PHASE_BITS]; + Word32 pfMagLUT_fx[1 << PRED_QUNAT_FILTER_MAG_BITS]; /* Q31 */ + Word32 pfP2RRealLUT_fx[1 << PRED_QUANT_FILTER_PHASE_BITS]; /* Q31 */ + Word32 pfP2RImagLUT_fx[1 << PRED_QUANT_FILTER_PHASE_BITS]; /* Q31 */ } PredictionDecoder; -ivas_error CreatePredictionDecoder( + +ivas_error CreatePredictionDecoder_fx( PredictionDecoder **psPredictionDecoder_out, - const int32_t iChannels, - const int32_t iNumBlocks -); + const Word32 iChannels, + const Word32 iNumBlocks ); -void DeletePredictionDecoder( - PredictionDecoder *psPredictionDecoder -); +void DeletePredictionDecoder_fx( + PredictionDecoder *psPredictionDecoder ); -int32_t ReadPredictors( +Word32 ReadPredictors_fx( PredictionDecoder *psPredictionDecoder, - ISAR_SPLIT_REND_BITS_HANDLE pBits + ISAR_SPLIT_REND_BITS_HANDLE pBits ); /* PLC_IMPROVEMENT */ @@ -353,10 +418,10 @@ void UpdateDecodingFailedStatus( int32_t AnyDecodingUnresolved( PredictionDecoder *psPredictionDecoder); -void ApplyInversePredictors( +void ApplyInversePredictors_fx( PredictionDecoder *psPredictionDecoder, - float ***pppfReal, - float ***pppfImag + Word32 ***pppfReal, + Word32 ***pppfImag ); @@ -373,20 +438,19 @@ RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( void DeleteRMSEnvelopeGrouping( RMSEnvelopeGrouping *psRMSEnvelopeGrouping ); - void ComputeEnvelopeGrouping( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, const int32_t iChannels, const int32_t iNumBands, const int32_t *piBandwidths, - float ***pppfReal, - float ***pppfImag, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, int32_t *piNumGroups, int32_t *piGroupLengths, - int32_t ***pppiRMSEnvelope + int32_t ***pppiRMSEnvelope , + Word16 q_final ); - #endif /* clang-format on */ diff --git a/lib_isar/isar_rom_lcld_tables.c b/lib_isar/isar_lcld_rom_tables.c similarity index 80% rename from lib_isar/isar_rom_lcld_tables.c rename to lib_isar/isar_lcld_rom_tables.c index bd2487404..d101c0eac 100644 --- a/lib_isar/isar_rom_lcld_tables.c +++ b/lib_isar/isar_lcld_rom_tables.c @@ -30,12 +30,13 @@ *******************************************************************************************************/ -#include "isar_rom_lcld_tables.h" +#include "isar_lcld_rom_tables.h" #include "options.h" #ifdef SPLIT_REND_WITH_HEAD_ROT #include "wmc_auto.h" #include "prot.h" #include "isar_lcld_prot.h" +#include /* clang-format off */ const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48] = { @@ -46,7 +47,6 @@ const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22 }; - /* phi = (-12:12)'/12 *pi; tmp = [cos(phi),sin(phi)]; tmp = tmp';sprintf('{%.8ff, %.8ff},\n',tmp(:)) */ const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = { @@ -77,6 +77,36 @@ const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = { -1.00000000f, 0.00000000f } }; +const Word32 c_afRotRealImag_fx[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = /*Q31*/ +{ + {-2147483647,0,}, + {-2074309888,-555809664,}, + {-1859775360,-1073741824,}, + {-1518500224,-1518500224,}, + {-1073741824,-1859775360,}, + {-555809664,-2074309888,}, + {0,-2147483647,}, + {555809664,-2074309888,}, + {1073741824,-1859775360,}, + {1518500224,-1518500224,}, + {1859775360,-1073741824,}, + {2074309888,-555809664,}, + {2147483647,0,}, + {2074309888,555809664,}, + {1859775360,1073741824,}, + {1518500224,1518500224,}, + {1073741824,1859775360,}, + {555809664,2074309888,}, + {0,2147483647,}, + {-555809664,2074309888,}, + {-1073741824,1859775360,}, + {-1518500224,1518500224,}, + {-1859775360,1073741824,}, + {-2074309888,555809664,}, + {-2147483647,0,}, + +}; +/* Move this to perceptual model ? */ const int32_t c_aiBandwidths48[MAX_BANDS_48] = { 1, @@ -139,7 +169,41 @@ const float c_afScaleFactor[ALLOC_TABLE_SIZE] = { 53.817370576237735f, 64.000000000000000f, }; - +const Word32 c_afScaleFactor_fx[ALLOC_TABLE_SIZE] = { + //Q24 + 0, + 5931641, + 7053950, + 8388608, + 9975792, + 11863283, + 14107901, + 16777216, + 19951584, + 23726566, + 28215802, + 33554432, + 39903168, + 47453132, + 56431604, + 67108864, + 79806336, + 94906264, + 112863208, + 134217728, + 159612672, + 189812528, + 225726416, + 268435456, + 319225344, + 379625056, + 451452832, + 536870912, + 638450688, + 759250112, + 902905664, + 1073741824, +}; const float c_afInvScaleFactor[ALLOC_TABLE_SIZE] = { 0.0f, 2.367513562373095f, @@ -174,7 +238,41 @@ const float c_afInvScaleFactor[ALLOC_TABLE_SIZE] = { 0.018581361171918f, 0.015625000000000f, }; - +const Word32 c_afInvScaleFactor_fx[ALLOC_TABLE_SIZE] = { + //Q29 + 0, + 1271049216, + 1098656512, + 953429056, + 824873408, + 710310720, + 608222976, + 518509920, + 440957952, + 373180800, + 315573664, + 266180592, + 224478672, + 189073424, + 159021648, + 133895608, + 112641984, + 94778304, + 79738992, + 67055176, + 56401524, + 47453132, + 39903168, + 33554432, + 28215802, + 23726566, + 19951584, + 16777216, + 14107901, + 11863283, + 9975792, + 8388608, +}; const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE] = { 2.32830644e-10f, 3.29272254e-10f, @@ -307,6 +405,45 @@ const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE] = { 4.29496730e+09f, }; +const int16_t c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_SIZE] = +{ + 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40, 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, -1, -1, -2 +}; +const Word32 c_aiQuantMaxValues_fx[ALLOC_TABLE_SIZE] = { + //Q21 + 0, +6291456, +6291456, +8388608, +10485760, +10485760, +12582912, +14680064, +16777216, +18874368, +25165824, +27262976, +33554432, +35651584, +39845888, +48234496, +54525952, +54525952, +56623104, +58720256, +65011712, +75497472, +79691776, +94371840, +113246208, +134217728, +159383552, +188743680, +226492416, +268435456, +318767104, +377487360, +}; const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE] = { 0, 3, @@ -341,6 +478,75 @@ const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE] = { 152, 180, }; +const Word32 c_aiHuffmanDim_fx[ALLOC_TABLE_SIZE] = { + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, +}; + +const Word32 c_aiHuffmanMod_fx[ALLOC_TABLE_SIZE] = { + 0, + 4, + 4, + 5, + 6, + 6, + 7, + 8, + 9, + 10, + 13, + 14, + 17, + 18, + 20, + 24, + 27, + 27, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, +}; const int32_t c_aiHuffmanDim[ALLOC_TABLE_SIZE] = { 2, @@ -411,7 +617,6 @@ const int32_t c_aiHuffmanMod[ALLOC_TABLE_SIZE] = { 1, 1, }; - const int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE] = { 1, 16, @@ -10940,150 +11145,8420 @@ const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36, 100, 169, 196, 289, 324, 400, 576, 729, 729, 28, 29, 32, 37, 39, 46, 55, 65, 77, 91, 109, 129, 153, 181 }; +#ifdef USE_DEMOD_TABLES +const int32_t c_aaiHuffDemod1[16][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, +}; -const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH] = { - 0x40, - 0x40, - 0x3F, - 0x3F, - 0x3E, - 0x3E, - 0x3D, - 0x3D, - 0x3C, - 0x3C, - 0x3B, - 0x3B, - 0x3A, - 0x3A, - 0x39, - 0x39, - 0x38, - 0x38, - 0x37, - 0x37, - 0x37, - 0x36, - 0x36, - 0x35, - 0x35, - 0x34, - 0x34, - 0x33, - 0x33, - 0x33, - 0x32, - 0x32, - 0x31, - 0x31, - 0x31, - 0x30, - 0x30, - 0x2F, - 0x2F, - 0x2F, - 0x2E, - 0x2E, - 0x2D, - 0x2D, - 0x2D, - 0x2C, - 0x2C, - 0x2B, - 0x2B, - 0x2B, - 0x2A, - 0x2A, - 0x2A, - 0x29, - 0x29, - 0x29, - 0x28, - 0x28, - 0x27, - 0x27, - 0x27, - 0x26, - 0x26, - 0x26, - 0x25, - 0x25, - 0x25, - 0x24, - 0x24, - 0x24, - 0x23, - 0x23, - 0x23, - 0x23, - 0x22, - 0x22, - 0x22, - 0x21, - 0x21, - 0x21, - 0x20, - 0x20, - 0x20, - 0x20, - 0x1F, - 0x1F, - 0x1F, - 0x1E, - 0x1E, - 0x1E, - 0x1E, - 0x1D, - 0x1D, - 0x1D, - 0x1C, - 0x1C, - 0x1C, - 0x1C, - 0x1B, - 0x1B, - 0x1B, - 0x1B, - 0x1A, - 0x1A, - 0x1A, - 0x1A, - 0x19, - 0x19, - 0x19, - 0x19, - 0x18, - 0x18, - 0x18, - 0x18, - 0x18, - 0x17, - 0x17, - 0x17, - 0x17, - 0x16, - 0x16, - 0x16, - 0x16, - 0x16, - 0x15, - 0x15, - 0x15, - 0x15, - 0x15, - 0x14, - 0x14, - 0x14, - 0x14, - 0x14, - 0x13, - 0x13, - 0x13, - 0x13, - 0x13, - 0x13, - 0x12, - 0x12, +const int32_t c_aaiHuffDemod2[16][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, +}; + +const int32_t c_aaiHuffDemod3[25][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, +}; + +const int32_t c_aaiHuffDemod4[36][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, +}; + +const int32_t c_aaiHuffDemod5[36][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, +}; + +const int32_t c_aaiHuffDemod6[49][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, +}; + +const int32_t c_aaiHuffDemod7[64][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, +}; + +const int32_t c_aaiHuffDemod8[81][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, +}; + +const int32_t c_aaiHuffDemod9[100][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, +}; + +const int32_t c_aaiHuffDemod10[169][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, +}; + +const int32_t c_aaiHuffDemod11[196][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, +}; + +const int32_t c_aaiHuffDemod12[289][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, +}; + +const int32_t c_aaiHuffDemod13[324][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, +}; + +const int32_t c_aaiHuffDemod14[400][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, +}; + +const int32_t c_aaiHuffDemod15[576][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, +}; + +const int32_t c_aaiHuffDemod16[729][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 0, + 24, + 0, + 25, + 0, + 26, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 1, + 24, + 1, + 25, + 1, + 26, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 2, + 24, + 2, + 25, + 2, + 26, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 3, + 24, + 3, + 25, + 3, + 26, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 4, + 24, + 4, + 25, + 4, + 26, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 5, + 24, + 5, + 25, + 5, + 26, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 6, + 24, + 6, + 25, + 6, + 26, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 7, + 24, + 7, + 25, + 7, + 26, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 8, + 24, + 8, + 25, + 8, + 26, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 9, + 24, + 9, + 25, + 9, + 26, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 10, + 24, + 10, + 25, + 10, + 26, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 11, + 24, + 11, + 25, + 11, + 26, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 12, + 24, + 12, + 25, + 12, + 26, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 13, + 24, + 13, + 25, + 13, + 26, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 14, + 24, + 14, + 25, + 14, + 26, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 15, + 24, + 15, + 25, + 15, + 26, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 16, + 24, + 16, + 25, + 16, + 26, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 17, + 24, + 17, + 25, + 17, + 26, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 18, + 24, + 18, + 25, + 18, + 26, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 19, + 24, + 19, + 25, + 19, + 26, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 20, + 24, + 20, + 25, + 20, + 26, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 21, + 24, + 21, + 25, + 21, + 26, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 22, + 24, + 22, + 25, + 22, + 26, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, + 23, + 24, + 23, + 25, + 23, + 26, + 24, + 0, + 24, + 1, + 24, + 2, + 24, + 3, + 24, + 4, + 24, + 5, + 24, + 6, + 24, + 7, + 24, + 8, + 24, + 9, + 24, + 10, + 24, + 11, + 24, + 12, + 24, + 13, + 24, + 14, + 24, + 15, + 24, + 16, + 24, + 17, + 24, + 18, + 24, + 19, + 24, + 20, + 24, + 21, + 24, + 22, + 24, + 23, + 24, + 24, + 24, + 25, + 24, + 26, + 25, + 0, + 25, + 1, + 25, + 2, + 25, + 3, + 25, + 4, + 25, + 5, + 25, + 6, + 25, + 7, + 25, + 8, + 25, + 9, + 25, + 10, + 25, + 11, + 25, + 12, + 25, + 13, + 25, + 14, + 25, + 15, + 25, + 16, + 25, + 17, + 25, + 18, + 25, + 19, + 25, + 20, + 25, + 21, + 25, + 22, + 25, + 23, + 25, + 24, + 25, + 25, + 25, + 26, + 26, + 0, + 26, + 1, + 26, + 2, + 26, + 3, + 26, + 4, + 26, + 5, + 26, + 6, + 26, + 7, + 26, + 8, + 26, + 9, + 26, + 10, + 26, + 11, + 26, + 12, + 26, + 13, + 26, + 14, + 26, + 15, + 26, + 16, + 26, + 17, + 26, + 18, + 26, + 19, + 26, + 20, + 26, + 21, + 26, + 22, + 26, + 23, + 26, + 24, + 26, + 25, + 26, + 26, +}; + +const int32_t c_aaiHuffDemod17[729][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 0, + 24, + 0, + 25, + 0, + 26, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 1, + 24, + 1, + 25, + 1, + 26, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 2, + 24, + 2, + 25, + 2, + 26, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 3, + 24, + 3, + 25, + 3, + 26, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 4, + 24, + 4, + 25, + 4, + 26, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 5, + 24, + 5, + 25, + 5, + 26, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 6, + 24, + 6, + 25, + 6, + 26, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 7, + 24, + 7, + 25, + 7, + 26, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 8, + 24, + 8, + 25, + 8, + 26, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 9, + 24, + 9, + 25, + 9, + 26, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 10, + 24, + 10, + 25, + 10, + 26, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 11, + 24, + 11, + 25, + 11, + 26, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 12, + 24, + 12, + 25, + 12, + 26, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 13, + 24, + 13, + 25, + 13, + 26, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 14, + 24, + 14, + 25, + 14, + 26, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 15, + 24, + 15, + 25, + 15, + 26, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 16, + 24, + 16, + 25, + 16, + 26, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 17, + 24, + 17, + 25, + 17, + 26, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 18, + 24, + 18, + 25, + 18, + 26, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 19, + 24, + 19, + 25, + 19, + 26, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 20, + 24, + 20, + 25, + 20, + 26, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 21, + 24, + 21, + 25, + 21, + 26, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 22, + 24, + 22, + 25, + 22, + 26, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, + 23, + 24, + 23, + 25, + 23, + 26, + 24, + 0, + 24, + 1, + 24, + 2, + 24, + 3, + 24, + 4, + 24, + 5, + 24, + 6, + 24, + 7, + 24, + 8, + 24, + 9, + 24, + 10, + 24, + 11, + 24, + 12, + 24, + 13, + 24, + 14, + 24, + 15, + 24, + 16, + 24, + 17, + 24, + 18, + 24, + 19, + 24, + 20, + 24, + 21, + 24, + 22, + 24, + 23, + 24, + 24, + 24, + 25, + 24, + 26, + 25, + 0, + 25, + 1, + 25, + 2, + 25, + 3, + 25, + 4, + 25, + 5, + 25, + 6, + 25, + 7, + 25, + 8, + 25, + 9, + 25, + 10, + 25, + 11, + 25, + 12, + 25, + 13, + 25, + 14, + 25, + 15, + 25, + 16, + 25, + 17, + 25, + 18, + 25, + 19, + 25, + 20, + 25, + 21, + 25, + 22, + 25, + 23, + 25, + 24, + 25, + 25, + 25, + 26, + 26, + 0, + 26, + 1, + 26, + 2, + 26, + 3, + 26, + 4, + 26, + 5, + 26, + 6, + 26, + 7, + 26, + 8, + 26, + 9, + 26, + 10, + 26, + 11, + 26, + 12, + 26, + 13, + 26, + 14, + 26, + 15, + 26, + 16, + 26, + 17, + 26, + 18, + 26, + 19, + 26, + 20, + 26, + 21, + 26, + 22, + 26, + 23, + 26, + 24, + 26, + 25, + 26, + 26, +}; + +const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2] = { + NULL, + c_aaiHuffDemod1, + c_aaiHuffDemod2, + c_aaiHuffDemod3, + c_aaiHuffDemod4, + c_aaiHuffDemod5, + c_aaiHuffDemod6, + c_aaiHuffDemod7, + c_aaiHuffDemod8, + c_aaiHuffDemod9, + c_aaiHuffDemod10, + c_aaiHuffDemod11, + c_aaiHuffDemod12, + c_aaiHuffDemod13, + c_aaiHuffDemod14, + c_aaiHuffDemod15, + c_aaiHuffDemod16, + c_aaiHuffDemod17, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; +#endif +const Word16 c_aiLogAddTable_fx[LOG_ADD_TABLE_LENGTH] = { + 0x40, + 0x40, + 0x3F, + 0x3F, + 0x3E, + 0x3E, + 0x3D, + 0x3D, + 0x3C, + 0x3C, + 0x3B, + 0x3B, + 0x3A, + 0x3A, + 0x39, + 0x39, + 0x38, + 0x38, + 0x37, + 0x37, + 0x37, + 0x36, + 0x36, + 0x35, + 0x35, + 0x34, + 0x34, + 0x33, + 0x33, + 0x33, + 0x32, + 0x32, + 0x31, + 0x31, + 0x31, + 0x30, + 0x30, + 0x2F, + 0x2F, + 0x2F, + 0x2E, + 0x2E, + 0x2D, + 0x2D, + 0x2D, + 0x2C, + 0x2C, + 0x2B, + 0x2B, + 0x2B, + 0x2A, + 0x2A, + 0x2A, + 0x29, + 0x29, + 0x29, + 0x28, + 0x28, + 0x27, + 0x27, + 0x27, + 0x26, + 0x26, + 0x26, + 0x25, + 0x25, + 0x25, + 0x24, + 0x24, + 0x24, + 0x23, + 0x23, + 0x23, + 0x23, + 0x22, + 0x22, + 0x22, + 0x21, + 0x21, + 0x21, + 0x20, + 0x20, + 0x20, + 0x20, + 0x1F, + 0x1F, + 0x1F, + 0x1E, + 0x1E, + 0x1E, + 0x1E, + 0x1D, + 0x1D, + 0x1D, + 0x1C, + 0x1C, + 0x1C, + 0x1C, + 0x1B, + 0x1B, + 0x1B, + 0x1B, + 0x1A, + 0x1A, + 0x1A, + 0x1A, + 0x19, + 0x19, + 0x19, + 0x19, + 0x18, + 0x18, + 0x18, + 0x18, + 0x18, + 0x17, + 0x17, + 0x17, + 0x17, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x14, + 0x14, + 0x14, + 0x14, + 0x14, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x12, + 0x12, + 0x12, + 0x12, + 0x12, + 0x11, + 0x11, + 0x11, + 0x11, + 0x11, + 0x11, + 0x10, + 0x10, + 0x10, + 0x10, + 0x10, + 0x10, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; +const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH] = { + 0x40, + 0x40, + 0x3F, + 0x3F, + 0x3E, + 0x3E, + 0x3D, + 0x3D, + 0x3C, + 0x3C, + 0x3B, + 0x3B, + 0x3A, + 0x3A, + 0x39, + 0x39, + 0x38, + 0x38, + 0x37, + 0x37, + 0x37, + 0x36, + 0x36, + 0x35, + 0x35, + 0x34, + 0x34, + 0x33, + 0x33, + 0x33, + 0x32, + 0x32, + 0x31, + 0x31, + 0x31, + 0x30, + 0x30, + 0x2F, + 0x2F, + 0x2F, + 0x2E, + 0x2E, + 0x2D, + 0x2D, + 0x2D, + 0x2C, + 0x2C, + 0x2B, + 0x2B, + 0x2B, + 0x2A, + 0x2A, + 0x2A, + 0x29, + 0x29, + 0x29, + 0x28, + 0x28, + 0x27, + 0x27, + 0x27, + 0x26, + 0x26, + 0x26, + 0x25, + 0x25, + 0x25, + 0x24, + 0x24, + 0x24, + 0x23, + 0x23, + 0x23, + 0x23, + 0x22, + 0x22, + 0x22, + 0x21, + 0x21, + 0x21, + 0x20, + 0x20, + 0x20, + 0x20, + 0x1F, + 0x1F, + 0x1F, + 0x1E, + 0x1E, + 0x1E, + 0x1E, + 0x1D, + 0x1D, + 0x1D, + 0x1C, + 0x1C, + 0x1C, + 0x1C, + 0x1B, + 0x1B, + 0x1B, + 0x1B, + 0x1A, + 0x1A, + 0x1A, + 0x1A, + 0x19, + 0x19, + 0x19, + 0x19, + 0x18, + 0x18, + 0x18, + 0x18, + 0x18, + 0x17, + 0x17, + 0x17, + 0x17, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x14, + 0x14, + 0x14, + 0x14, + 0x14, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x12, + 0x12, 0x12, 0x12, 0x12, @@ -11455,8 +19930,33 @@ const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH] = { 0x00, 0x00, }; - +const Word16 c_aiBandwidthAdjust48_fx[MAX_BANDS_48] = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 64, + 64, + 64, + 64, + 101, + 101, + 128, + 165, + 165, + 180, + 213, +}; const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48] = { + 0, 0, 0, @@ -11482,6 +19982,31 @@ const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48] = { 213, }; +const Word16 c_aiAbsoluteThresh48_fx[MAX_BANDS_48] = { + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1782, + -1761, + -1737, + -1679, + -1638, + -1613, + -1590, + -1568, + -1516, + -1459, + -1395, + -1289, + -671, + -409, + -401, +}; const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48] = { -1787, -1787, @@ -11507,62 +20032,617 @@ const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48] = { -409, -401, }; - - -#if PERCEPTUAL_MODEL_SLGAIN_SHIFT == 4 -const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = { - 7, - 7, - 6, - 5, - 5, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, -}; -#elif PERCEPTUAL_MODEL_SLGAIN_SHIFT == 8 -const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = { - 112, - 112, - 96, - 80, - 80, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, -}; -#endif - +#if PERCEPTUAL_MODEL_SLGAIN_SHIFT == 4 +const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = { + 7, + 7, + 6, + 5, + 5, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, +}; +#elif PERCEPTUAL_MODEL_SLGAIN_SHIFT == 8 +const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48] = { + + 112, + 112, + 96, + 80, + 80, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, +}; +#endif +const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = { + + 112, + 112, + 96, + 80, + 80, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, +}; +const Word16 c_aaiSpreadFunction48_fx[MAX_BANDS_48 * MAX_BANDS_48] = { + 0, + -1561, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -289, + -4, + -1234, + -2295, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -569, + -229, + -8, + -905, + -1705, + -2324, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -789, + -445, + -173, + -16, + -656, + -1271, + -1765, + -2172, + -2520, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -961, + -616, + -340, + -136, + -28, + -488, + -976, + -1382, + -1729, + -2032, + -2305, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1088, + -743, + -465, + -257, + -148, + -31, + -371, + -769, + -1114, + -1417, + -1689, + -2054, + -2483, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1198, + -852, + -574, + -364, + -209, + -148, + -42, + -300, + -635, + -936, + -1207, + -1572, + -2000, + -2376, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1293, + -948, + -669, + -458, + -301, + -183, + -145, + -56, + -258, + -547, + -816, + -1179, + -1606, + -1982, + -2311, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1375, + -1029, + -750, + -539, + -381, + -260, + -180, + -142, + -68, + -231, + -487, + -846, + -1272, + -1647, + -1976, + -2261, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1444, + -1099, + -820, + -608, + -449, + -328, + -233, + -194, + -138, + -77, + -213, + -555, + -978, + -1352, + -1681, + -1966, + -2268, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1501, + -1155, + -876, + -665, + -505, + -383, + -287, + -210, + -193, + -130, + -79, + -298, + -711, + -1083, + -1411, + -1696, + -1997, + -2288, + -2550, + -2552, + -2552, + -2552, + -2552, + -1567, + -1221, + -942, + -730, + -570, + -448, + -351, + -272, + -206, + -189, + -151, + -72, + -349, + -713, + -1039, + -1324, + -1625, + -1915, + -2177, + -2448, + -2552, + -2552, + -2552, + -1650, + -1304, + -1025, + -813, + -653, + -530, + -432, + -352, + -285, + -227, + -177, + -163, + -69, + -297, + -613, + -895, + -1195, + -1485, + -1746, + -2017, + -2238, + -2401, + -2545, + -1727, + -1381, + -1102, + -890, + -730, + -607, + -509, + -428, + -360, + -301, + -249, + -180, + -153, + -72, + -257, + -527, + -824, + -1112, + -1373, + -1643, + -1865, + -2028, + -2171, + -1798, + -1452, + -1173, + -960, + -800, + -677, + -579, + -498, + -430, + -370, + -317, + -246, + -192, + -145, + -76, + -224, + -505, + -790, + -1050, + -1320, + -1540, + -1703, + -1847, + -1860, + -1514, + -1234, + -1022, + -862, + -738, + -640, + -559, + -490, + -430, + -377, + -306, + -224, + -197, + -136, + -81, + -242, + -515, + -771, + -1040, + -1260, + -1422, + -1566, + -1923, + -1577, + -1297, + -1085, + -925, + -801, + -703, + -621, + -553, + -492, + -439, + -367, + -284, + -213, + -198, + -144, + -83, + -235, + -479, + -744, + -963, + -1125, + -1268, + -1986, + -1640, + -1360, + -1148, + -988, + -864, + -766, + -684, + -615, + -555, + -501, + -429, + -345, + -273, + -211, + -204, + -146, + -89, + -216, + -465, + -680, + -841, + -984, + -2043, + -1697, + -1417, + -1205, + -1044, + -921, + -822, + -741, + -672, + -611, + -557, + -485, + -401, + -328, + -264, + -211, + -205, + -140, + -93, + -227, + -430, + -588, + -729, + -2104, + -1758, + -1479, + -1266, + -1106, + -982, + -884, + -802, + -733, + -673, + -619, + -546, + -461, + -388, + -324, + -269, + -212, + -211, + -151, + -100, + -195, + -336, + -472, + -2163, + -1817, + -1537, + -1324, + -1164, + -1040, + -942, + -860, + -791, + -731, + -676, + -604, + -519, + -445, + -380, + -325, + -268, + -226, + -219, + -147, + -114, + -167, + -280, + -2203, + -1857, + -1577, + -1365, + -1205, + -1081, + -982, + -901, + -831, + -771, + -717, + -644, + -559, + -485, + -420, + -364, + -306, + -252, + -239, + -206, + -132, + -122, + -163, + -2224, + -1878, + -1598, + -1386, + -1225, + -1102, + -1003, + -921, + -852, + -792, + -737, + -665, + -580, + -505, + -441, + -385, + -326, + -271, + -222, + -224, + -176, + -121, + -114, +}; const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48] = { 0, -1561, @@ -12094,4 +21174,34 @@ const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48] = { -121, -114, }; + +const Word32 c_pfMagLUT[8] = /* Q31 */ +{ + 0, 394599072, 775760576, 1130504448, 1446750336, 1713728896, 1922348544, 2065504896 +}; + +const Word32 c_pfP2RRealLUT[32] = /* Q31 */ +{ + INT_MIN, -2106220416, -1984016384, -1785567488, -1518500224, -1193078272, + -821806592, -418953280, -94, 418953088, 821806400, 1193077888, + 1518500224, 1785567360, 1984016128, 2106220288, 2147483647, 2106220288, + 1984016128, 1785567360, 1518500224, 1193077888, 821806400, 418953088, + -94, -418953280, -821806592, -1193078272, -1518500224, -1785567488, + -1984016384, -2106220416 +}; + +const Word32 c_pfP2RImagLUT[32] = /* Q31 */ +{ + 188, -418953248, -821806080, -1193077888, -1518500224, -1785567232, + -1984016128, -2106220288, INT_MIN, -2106220416, -1984016128, -1785567488, + -1518500224, -1193078016, -821806464, -418953280, 0, 418953280, + 821806464, 1193078016, 1518500224, 1785567488, 1984016128, 2106220416, + 2147483647, 2106220288, 1984016128, 1785567232, 1518500224, 1193077888, + 821806080, 418953248 +}; + +const Word32 c_pfWindowLUT[LCLD_PRED_WIN_LEN] = /* Q31 */ +{ + 190779840, 338280192, 610825408, 966922816, 1352359680, 1708457216, 1981002240, 2128502656, 2128502528, 1981002240, 1708456960, 1352359808, 966922624, 610825152, 338280192, 190779776 +}; #endif diff --git a/lib_isar/isar_rom_lcld_tables.h b/lib_isar/isar_lcld_rom_tables.h similarity index 73% rename from lib_isar/isar_rom_lcld_tables.h rename to lib_isar/isar_lcld_rom_tables.h index 974e57af0..4f1e80583 100644 --- a/lib_isar/isar_rom_lcld_tables.h +++ b/lib_isar/isar_lcld_rom_tables.h @@ -30,16 +30,16 @@ *******************************************************************************************************/ -#ifndef ISAR_ROM_LCLD_TABLES_H -#define ISAR_ROM_LCLD_TABLES_H +#ifndef _ISAR_LCLD_ROM_TABLES_H_ +#define _ISAR_LCLD_ROM_TABLES_H_ #include #include "options.h" - -#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "typedef.h" #ifndef M_PI -#define M_PI 3.14159265358979323846264338327950288f +#define M_PI 3.14159265358979323846264338327950288f // todo: replace by EVS_PI +#define M_ONE_BY_PI_FX 10430 // 1/pi in Q15 #endif @@ -57,8 +57,10 @@ #define ENV0_BITS ( 7 ) -#define ENV_DELTA_MIN ( -32 ) -#define ENV_DELTA_MAX ( 31 ) +#define ENV_DELTA_MIN ( -32 ) +#define ENV_DELTA_MIN_FX ( -1073741824 ) +#define ENV_DELTA_MAX ( 31 ) +#define ENV_DELTA_MAX_FX ( 1040187392 ) #define ENV_RECONSTRUCT_TABLE_SIZE ( 129 ) @@ -80,40 +82,59 @@ #ifndef _PI_ #define _PI_ ( 3.14159265358979f ) #endif -#define PRED_MAX_VAL ( 12 ) -#define PRED_MIN_VAL ( -PRED_MAX_VAL ) -#define PRED_QUANT_FACTOR ( (float) PRED_MAX_VAL ) -#define PRED_BAND0_BITS ( 5 ) - -#define PHASE_MAX_VAL ( 12 ) -#define PHASE_MIN_VAL ( -PHASE_MAX_VAL ) -#define PHASE_QUANT_FACTOR ( (float) PHASE_MAX_VAL / _PI_ ) -#define PHASE_DIFF_DIM ( 2 ) -#define PHASE_BAND0_BITS ( 5 ) +#define PRED_MAX_VAL ( 12 ) +#define PRED_MIN_VAL ( -PRED_MAX_VAL ) +#define PRED_QUANT_FACTOR ( (float) PRED_MAX_VAL ) +#define PRED_QUANT_FACTOR_FX ( PRED_MAX_VAL ) +#define PRED_BAND0_BITS ( 5 ) + +#define PHASE_MAX_VAL ( 12 ) +#define PHASE_MIN_VAL ( -PHASE_MAX_VAL ) +#define PHASE_QUANT_FACTOR ( (float) PHASE_MAX_VAL / _PI_ ) +#define PHASE_QUANT_FACTOR_FX_Q29 ( 2050695826 ) +#define PHASE_DIFF_DIM ( 2 ) +#define PHASE_BAND0_BITS ( 5 ) #define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) +// #define USE_DEMOD_TABLES + #define HUFF_DEC_TABLE_SIZE ( 16 ) extern const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48]; extern const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS]; extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; +extern const Word32 c_afRotRealImag_fx[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; +extern const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48]; extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; extern const float c_afScaleFactor[ALLOC_TABLE_SIZE]; extern const float c_afInvScaleFactor[ALLOC_TABLE_SIZE]; +extern const Word32 c_afInvScaleFactor_fx[ALLOC_TABLE_SIZE]; extern const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE]; +extern const int16_t c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_SIZE]; extern const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE]; extern const int32_t c_aiHuffmanDim[ALLOC_TABLE_SIZE]; extern const int32_t c_aiHuffmanMod[ALLOC_TABLE_SIZE]; +extern const Word32 c_aiHuffmanDim_fx[ALLOC_TABLE_SIZE]; +extern const Word32 c_aiHuffmanMod_fx[ALLOC_TABLE_SIZE]; +extern const Word32 c_afScaleFactor_fx[ALLOC_TABLE_SIZE]; +extern const Word32 c_aiQuantMaxValues_fx[ALLOC_TABLE_SIZE]; extern const int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE]; #define LOG_ADD_TABLE_LENGTH ( 512 ) extern const int32_t c_aiBandwidths48[MAX_BANDS_48]; +extern const Word16 c_aiLogAddTable_fx[LOG_ADD_TABLE_LENGTH]; +extern const Word16 c_aiBandwidthAdjust48_fx[MAX_BANDS_48]; extern const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH]; extern const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48]; + + +extern const Word16 c_aiAbsoluteThresh48_fx[MAX_BANDS_48]; +extern const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48]; +extern const Word16 c_aaiSpreadFunction48_fx[MAX_BANDS_48 * MAX_BANDS_48]; extern const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48]; extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; extern const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48]; @@ -190,8 +211,35 @@ extern const uint16_t c_aauiLCLDHuffEnc62[153][2]; extern const uint16_t c_aauiLCLDHuffEnc63[181][2]; extern const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2]; extern const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE]; + +#ifdef USE_DEMOD_TABLES +extern const int32_t c_aaiHuffDemod1[16][2]; +extern const int32_t c_aaiHuffDemod2[16][2]; +extern const int32_t c_aaiHuffDemod3[25][2]; +extern const int32_t c_aaiHuffDemod4[36][2]; +extern const int32_t c_aaiHuffDemod5[36][2]; +extern const int32_t c_aaiHuffDemod6[49][2]; +extern const int32_t c_aaiHuffDemod7[64][2]; +extern const int32_t c_aaiHuffDemod8[81][2]; +extern const int32_t c_aaiHuffDemod9[100][2]; +extern const int32_t c_aaiHuffDemod10[169][2]; +extern const int32_t c_aaiHuffDemod11[196][2]; +extern const int32_t c_aaiHuffDemod12[289][2]; +extern const int32_t c_aaiHuffDemod13[324][2]; +extern const int32_t c_aaiHuffDemod14[400][2]; +extern const int32_t c_aaiHuffDemod15[576][2]; +extern const int32_t c_aaiHuffDemod16[729][2]; +extern const int32_t c_aaiHuffDemod17[729][2]; +extern const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2]; +#endif + extern const uint32_t c_aaiRMSEnvHuffEnc[64][2]; extern const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE]; -#endif /*SPLIT_REND_WITH_HEAD_ROT*/ -#endif /* ISAR_ROM_LCLD_TABLES_H_ */ +extern const Word32 c_pfMagLUT[8]; /* Q31 */ +extern const Word32 c_pfP2RRealLUT[32]; /* Q31 */ +extern const Word32 c_pfP2RImagLUT[32]; /* Q31 */ +extern const Word32 c_pfWindowLUT[LCLD_PRED_WIN_LEN]; /* Q31 */ + + +#endif /* _TABLES_H_ */ diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h index 43248926d..24f93b283 100644 --- a/lib_isar/isar_prot.h +++ b/lib_isar/isar_prot.h @@ -42,53 +42,16 @@ #include "options.h" #include "ivas_error.h" #include "lib_isar_post_rend.h" +#include "enh64.h" -ivas_error isar_splitBinPreRendOpen( - ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - , - const int32_t output_Fs -#endif -); - -ivas_error split_renderer_open_lc3plus( - SPLIT_REND_WRAPPER *hSplitRendWrapper, - const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t OutSampleRate, -#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - const IVAS_RENDER_FRAMESIZE ivas_frame_size -#else - const int16_t num_subframes -#endif -); - -void isar_splitBinPreRendClose( - ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ); - -void lc3plusTimeAlignCldfbPoseCorr( - SPLIT_REND_WRAPPER *hSplitBin, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ); - -ivas_error splitRendLc3plusEncodeAndWrite( - SPLIT_REND_WRAPPER *hSplitBin, - ISAR_SPLIT_REND_BITS_HANDLE pBits, -#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - const int32_t available_bits, -#else - const int32_t SplitRendBitRate, -#endif - float *in[] ); - -int32_t ISAR_SPLIT_REND_BITStream_read_int32( +Word32 ISAR_SPLIT_REND_BITStream_read_int32( ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t bits ); + const Word32 bits ); void ISAR_SPLIT_REND_BITStream_write_int32( ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t val, - const int32_t bits ); + const Word32 val, + const Word32 bits ); ivas_error isar_splitBinLCLDEncOpen( ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, @@ -100,47 +63,47 @@ ivas_error isar_splitBinLCLDEncOpen( ivas_error isar_splitBinRendPLCOpen( ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, - const int16_t iNumSubSets ); + int16_t iNumSubSets ); void isar_splitBinRendPLCClose( ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC ); - ivas_error isar_splitBinLCLDDecOpen( ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, - const int32_t iSampleRate, - const int16_t iChannels, - const int16_t iNumBlocks, - const int16_t iNumIterations ); - + const Word32 iSampleRate, + const Word16 iChannels, + const Word16 iNumBlocks, + const Word16 iNumIterations ); void isar_splitBinLCLDDecClose( ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ); void isar_splitBinRendPLCsaveState( ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs, const int16_t iNumBlocks, const int16_t iNumIterations ); -void isar_splitBinRendPLC_xf( +void isar_splitBinRendPLC_xf_fx( ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs, - const int16_t iNumBlocks, - const int16_t iNumIterations, - int32_t **ppiDecodingFailed, - int32_t **ppiDecodingFailedPrev ); + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations, + Word32 **ppiDecodingFailed, + Word32 **ppiDecodingFailedPrev, + Word16 exp ); void isar_splitBinRendPLC( ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs, - const int16_t iNumBlocks, - const int16_t iNumIterations, - int32_t **ppiDecodingFailed ); + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations, + Word32 **ppiDecodingFailed, + Word16 exp ); #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG void isar_log_cldfb2wav_data( @@ -155,27 +118,41 @@ void isar_log_cldfb2wav_data( const char *filename ); #endif +void isar_SplitRenderer_PostRenderer( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + const IVAS_QUATERNION Quaternion_act ); + void isar_splitBinLCLDDecProcess( ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, ISAR_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t bfi ); + Word32 Cldfb_Out_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_cldfb_final, + const Word16 bfi ); +void set_fix_rotation_mat_fx( + Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); void set_fix_rotation_mat( float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); void isar_splitBinLCLDEncClose( ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ); - void isar_splitBinLCLDEncProcess( ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, - float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int32_t available_bits, - ISAR_SPLIT_REND_BITS_HANDLE pBits ); + Word32 Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word32 available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word16 *q_final ); +void set_pose_types_fx( + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); void set_pose_types( ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); @@ -192,11 +169,41 @@ void isar_splitBinPostRendClose( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ); void isar_SplitRenderer_getdiagdiff( - int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - const int16_t sign, - const int16_t min_val, - const int16_t max_val ); + Word16 in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const Word16 sign, + const Word16 min_val, + const Word16 max_val ); + +void isar_renderSplitGetMultiBinPoseData_fx( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis ); +void isar_renderSplitGetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis ); + +void isar_split_rend_get_quant_params_fx( + const Word16 num_md_bands, + Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + const Word16 ro_flag, +#endif + Word16 *num_quant_strats +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + , + Word16 *num_complex_bands +#endif +); void isar_split_rend_get_quant_params( const int16_t num_md_bands, @@ -209,24 +216,16 @@ void isar_split_rend_get_quant_params( int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], -#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - const int16_t ro_flag, -#endif - int16_t *num_quant_strats -#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - , - int16_t *num_complex_bands -#endif -); + int16_t *num_quant_strats, + int16_t *num_complex_bands ); -void isar_splitBinPostRendMdDec( +void isar_splitBinPostRendMdDec_fx( ISAR_SPLIT_REND_BITS_HANDLE pBits, ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + , BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend -#else - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData #endif ); @@ -237,7 +236,7 @@ void Quat2EulerDegree( float *roll /* o : roll */ ); -void isar_mat_mult_2by2_complex( +void ivas_mat_mult_2by2_complex( float in_re1[2][2], float in_im1[2][2], float in_re2[2][2], @@ -245,140 +244,178 @@ void isar_mat_mult_2by2_complex( float out_re2[2][2], float out_im2[2][2] ); +void isar_mat_mult_2by2_complex_fx( + Word32 in_re1_fx[2][2], + Word16 exp_re1, + Word32 in_im1_fx[2][2], + Word16 exp_im1, + Word32 in_re2_fx[2][2], + Word16 exp_re2, + Word32 in_im2_fx[2][2], + Word16 exp_im2, + Word32 out_re2_fx[2][2], + Word16 *final_exp_re_1, + Word32 out_im2_fx[2][2], + Word16 *final_exp_im_1 ); + void isar_rend_CldfbSplitPostRendProcess( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const IVAS_QUATERNION QuaternionPost, - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float output[][L_FRAME48k], - const int16_t cldfb_in_flag ); + Word32 Cldfb_RealBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + Word16 Q_cldfb_in, + Word32 output_fx[][L_FRAME48k], + Word16 *Q_out, + const Word16 cldfb_in_flag ); + +void isar_init_multi_bin_pose_data_fx( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +/* Copy for encoder, to be removed */ +void isar_init_multi_bin_pose_data_fx_enc( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); +void isar_init_multi_bin_pose_data( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); void isar_rend_CldfbSplitPreRendProcess( const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, const IVAS_QUATERNION headPosition, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t target_md_bits, - const int16_t low_res_pre_rend_rot, - const int16_t ro_md_flag ); - -ivas_error isar_renderMultiTDBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, -#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - const int16_t isar_frame_size_ms, -#endif - const int16_t codec_frame_size_ms, + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re, + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im, ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int16_t max_bands, - float *in[], - const int16_t low_res_pre_rend_rot, - const int16_t pcm_out_flag, - const int16_t ro_md_flag ); - -void isar_init_multi_bin_pose_data( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); - -void isar_renderSplitGetMultiBinPoseData( - const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const ISAR_SPLIT_REND_ROT_AXIS rot_axis ); + const Word32 target_md_bits, + const Word16 low_res_pre_rend_rot, + const Word16 ro_md_flag ); #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS -int16_t isar_renderSplitGetRot_axisNumBits( - const int16_t dof ); +Word16 isar_renderSplitGetRot_axisNumBits( + const Word16 dof ); ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( - const int16_t dof, - const int16_t code ); + const Word16 dof, + const Word16 code ); -int16_t isar_renderSplitGetCodeFromRot_axis( - const int16_t dof, +Word16 isar_renderSplitGetCodeFromRot_axis( + const Word16 dof, const ISAR_SPLIT_REND_ROT_AXIS rot_axis, - int16_t *num_bits ); + Word16 *num_bits ); #endif void isar_init_split_post_rend_handles( ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ); -void isar_set_split_rend_ht_setup( +ivas_error isar_splitBinPreRendOpen( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs +#else + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#endif +); + +void isar_splitBinPreRendClose( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ); + +void isar_set_split_rend_ht_setup_fx( SPLIT_REND_WRAPPER *hSplitrend, IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], - float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ); + Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ); + #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS -int32_t isar_get_lc3plus_bitrate( - const int32_t SplitRendBitRate, +Word32 isar_get_lc3plus_bitrate( + const Word32 SplitRendBitRate, const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ); + const Word16 split_prerender_frame_size_ms ); #endif ivas_error isar_split_rend_validate_config( const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int16_t pcm_out_flag ); + const Word16 is_pcm_out ); -int32_t isar_get_lcld_bitrate( - const int32_t SplitRendBitRate, +Word32 isar_get_lcld_bitrate( + const Word32 SplitRendBitRate, const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ); #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS -int8_t isar_get_lc3plus_bitrate_id( - const int32_t SplitRendBitRate ); +Word8 isar_get_lc3plus_bitrate_id( + const Word32 SplitRendBitRate ); #endif -int32_t isar_get_split_rend_md_target_brate( +ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE pBits, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int32_t available_bits, +#else const int32_t SplitRendBitRate, - const int16_t pcm_out_flag ); +#endif + Word32 *in[], + Word16 Q_sig ); #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS ivas_error isar_framesize_to_ms( const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */ - int16_t *ms /* o : frame size in ms */ + Word16 *ms /* o : frame size in ms */ ); #endif +Word32 isar_get_split_rend_md_target_brate( + const Word32 SplitRendBitRate, + const Word16 pcm_out_flag ); ivas_error isar_split_rend_choose_default_codec( ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */ + Word16 *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */ #endif - int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ - const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ - const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ - const int16_t num_subframes /* i : number of subframes */ + Word16 *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const Word16 cldfb_in_flag, /* i : flag indicating rendering in TD */ + const Word16 pcm_out_flag, /* i : flag to indicate PCM output */ + const Word16 num_subframes /* i : number of subframes */ ); void ISAR_SPLIT_REND_BITStream_init( ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t buf_len_bytes, - uint8_t *pbuf ); + const Word32 buf_len_bytes, + UWord8 *pbuf ); void isar_split_rend_huffman_dec_init_min_max_len( isar_split_rend_huffman_cfg_t *p_huff_cfg ); -int16_t wrap_a( - int16_t val, - const int16_t min_val, - const int16_t max_val ); - +Word16 wrap_a( + Word16 val, + const Word16 min_val, + const Word16 max_val ); #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS -int32_t isar_get_lc3plus_size_from_id( - const int8_t SplitRendBitRateId, +Word32 isar_get_lc3plus_size_from_id( + const Word8 SplitRendBitRateId, const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ); + const Word16 split_prerender_frame_size_ms ); #endif void isar_renderSplitUpdateNoCorrectionPoseData( const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); -int32_t get_bit( - const int32_t state, - const int32_t bit_id ); +Word32 get_bit( + const Word32 state, + const Word32 bit_id ); + +ivas_error split_renderer_open_lc3plus( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const Word32 OutSampleRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE ivas_frame_size +#else + const int16_t num_subframes +#endif +); ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( const IVAS_AUDIO_CONFIG config ); @@ -386,8 +423,43 @@ ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( void isar_init_split_rend_handles( SPLIT_REND_WRAPPER *hSplitRendWrapper ); +ivas_error isar_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const Word32 SplitRendBitRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const Word16 isar_frame_size_ms, +#endif + const Word16 codec_frame_size_ms, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word16 max_bands, + // float *in[], + Word32 *in_fx[], // Q11 + Word16 Q_sig, + const Word16 low_res_pre_rend_rot, + const Word16 pcm_out_flag, + const Word16 ro_md_flag ); + +void lc3plusTimeAlignCldfbPoseCorr( SPLIT_REND_WRAPPER *hSplitBin, + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_in ); + #endif +void set16_fx( + Word16 y[], /* i/o: Vector to set */ + const Word16 a, /* i : Value to set the vector to */ + const Word16 N /* i : Lenght of the vector */ +); + +void set32_fx( + Word32 y[], /* i/o: Vector to set */ + const Word32 a, /* i : Value to set the vector to */ + const Word16 N /* i : Lenght of the vector */ +); +Word16 ceil_log_2( + UWord64 val ); /* clang-format on */ -#endif /* ISAR_PROT_H */ +#endif /* IVAS_PROT_REND_H */ diff --git a/lib_isar/isar_rom_post_rend.c b/lib_isar/isar_rom_post_rend.c index 31c8429d9..13a786b16 100644 --- a/lib_isar/isar_rom_post_rend.c +++ b/lib_isar/isar_rom_post_rend.c @@ -35,7 +35,9 @@ #ifdef DEBUGGING #include "debug.h" #endif +#include "cnst.h" #include "isar_cnst.h" +#include #include "wmc_auto.h" /* clang-format off */ @@ -47,29 +49,38 @@ *-----------------------------------------------------------------------*/ /* rotations in this array are relative to ref rotation */ -const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; -const float isar_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; -const float isar_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; -const float isar_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; - -const float isar_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; -const float isar_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; -const float isar_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; -const float isar_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; +const Word32 ivas_split_rend_relative_yaw_pos_angles_fx[SPLIT_REND_MAX_YAW_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */ +const Word32 ivas_split_rend_relative_pitch_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { 41943040, 41943040 }; /* Q22 */ +const Word32 ivas_split_rend_relative_roll_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { 41943040, 41943040 }; /* Q22 */ +const float ivas_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float ivas_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float ivas_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float ivas_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +const Word32 ivas_split_rend_relative_yaw_pos_angles_hq_fx[SPLIT_REND_MAX_YAW_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */ +const Word32 ivas_split_rend_relative_pitch_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */ +const Word32 ivas_split_rend_relative_roll_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */ +const float ivas_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float ivas_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float ivas_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float ivas_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +/* Values in degrees : -30, -22.5, -15, 0, 15, 22.5 and 30 */ +const Word32 ivas_split_rend_fix_pos_rot_mat_cos_fx[4] = { ONE_IN_Q31, 2074309917, 1984016189, 1859775393 }; /* Q31 */ const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 20, 25, 30, 35, 40, 50, 60 }; -const int32_t isar_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +const int32_t ivas_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = { {0,8,252},{1,8,253},{2,7,124},{3,6,60},{4,5,28},{5,4,12}, {6,3,4},{7,1,0},{8,3,5},{9,4,13},{10,5,29},{11,6,61}, {12,7,125},{13,8,254},{14,8,255} }; -const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +const int32_t ivas_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = { { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, @@ -77,7 +88,7 @@ const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS] { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } }; -const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +const int32_t ivas_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = { { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, @@ -85,7 +96,7 @@ const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } }; -const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_63QUANT_PNTS][3] = +const int32_t ivas_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_63QUANT_PNTS][3] = { {-31,11,2040}, {-30,11,2041}, @@ -152,7 +163,7 @@ const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_63QUANT_PN {31,11,2047}, }; -const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3] = +const int32_t ivas_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3] = { {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, @@ -164,7 +175,7 @@ const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PN {14,10,1022},{15,10,1023}, }; -const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3] = +const int32_t ivas_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3] = { {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, @@ -178,5 +189,8 @@ const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QU #endif +/* Tables for split renderer fixed converison */ +const Word16 fade_table_fx[4] = +{ 8192, 16384, 24576, 32767 }; /* clang-format on */ diff --git a/lib_isar/isar_rom_post_rend.h b/lib_isar/isar_rom_post_rend.h index b046263b3..2bfac9140 100644 --- a/lib_isar/isar_rom_post_rend.h +++ b/lib_isar/isar_rom_post_rend.h @@ -38,32 +38,45 @@ #ifdef DEBUGGING #include "debug.h" #endif +#include "cnst.h" #include "isar_cnst.h" - #ifdef SPLIT_REND_WITH_HEAD_ROT /*----------------------------------------------------------------------* * Binuaral split rendering ROM tables *-----------------------------------------------------------------------*/ -extern const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES]; -extern const float isar_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; -extern const float isar_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; -extern const float isar_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; -extern const float isar_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; +extern const Word32 ivas_split_rend_relative_yaw_pos_angles_fx[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const Word32 ivas_split_rend_relative_pitch_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const Word32 ivas_split_rend_relative_roll_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float ivas_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; +extern const float ivas_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; + +extern const Word32 ivas_split_rend_relative_yaw_pos_angles_hq_fx[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const Word32 ivas_split_rend_relative_pitch_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const Word32 ivas_split_rend_relative_roll_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float ivas_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; -extern const float isar_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES]; -extern const float isar_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; -extern const float isar_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +/* Values in degrees : -30, -22.5, -15, 0, 15, 22.5 and 30 */ +extern const Word32 ivas_split_rend_fix_pos_rot_mat_cos_fx[4]; /* Q31 */ extern const float ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3]; extern const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1]; -extern const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; -extern const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; -extern const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; -extern const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3]; -extern const int32_t isar_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; -extern const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t split_rend_brate_tbl[]; #endif +/* Tables for fixed point conversion */ +extern const Word16 fade_table_fx[4]; + #endif diff --git a/lib_isar/isar_splitRend_lcld_dec.c b/lib_isar/isar_splitRend_lcld_dec.c index d34cc8482..7e5c3e2bb 100644 --- a/lib_isar/isar_splitRend_lcld_dec.c +++ b/lib_isar/isar_splitRend_lcld_dec.c @@ -36,6 +36,7 @@ #include "isar_prot.h" #include "ivas_prot.h" #include "prot.h" +#include "control.h" #ifdef DEBUGGING #include "debug.h" #endif @@ -47,19 +48,18 @@ * * *------------------------------------------------------------------------*/ - ivas_error isar_splitBinLCLDDecOpen( ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, - const int32_t iSampleRate, - const int16_t iChannels, - const int16_t iNumBlocks, - const int16_t iNumIterations ) + const Word32 iSampleRate, + const Word16 iChannels, + const Word16 iNumBlocks, + const Word16 iNumIterations ) { int16_t n; ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; ivas_error error; - if ( ( splitBinLCLDDec = (ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL ) + IF( ( splitBinLCLDDec = (ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } @@ -68,32 +68,31 @@ ivas_error isar_splitBinLCLDDecOpen( splitBinLCLDDec->iChannels = iChannels; - if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks, 0 ) ) != IVAS_ERR_OK ) + IF( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks, 0 ) ) != IVAS_ERR_OK ) { return error; } - if ( ( splitBinLCLDDec->pppfDecLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == NULL ) + IF( ( splitBinLCLDDec->pppfDecLCLDReal_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - if ( ( splitBinLCLDDec->pppfDecLCLDImag = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == NULL ) + IF( ( splitBinLCLDDec->pppfDecLCLDImag_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - for ( n = 0; n < splitBinLCLDDec->iChannels; n++ ) + FOR( n = 0; n < splitBinLCLDDec->iChannels; n++ ) { - if ( ( splitBinLCLDDec->pppfDecLCLDReal[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == NULL ) + IF( ( splitBinLCLDDec->pppfDecLCLDReal_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } - if ( ( splitBinLCLDDec->pppfDecLCLDImag[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == NULL ) + IF( ( splitBinLCLDDec->pppfDecLCLDImag_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } } - #ifdef CLDFB_DEBUG splitBinLCLDDec->numFrame = 0; char cldfbFilename[50] = "cldfb_out.bin"; @@ -107,7 +106,7 @@ ivas_error isar_splitBinLCLDDecOpen( fwrite( &num_bands, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); #endif - if ( ( error = isar_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC, GetNumSubSets( splitBinLCLDDec->psLCLDDecoder ) ) ) != IVAS_ERR_OK ) + IF( ( error = isar_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC, GetNumSubSets( splitBinLCLDDec->psLCLDDecoder ) ) ) != IVAS_ERR_OK ) { return error; } @@ -119,7 +118,6 @@ ivas_error isar_splitBinLCLDDecOpen( return IVAS_ERR_OK; } - /*------------------------------------------------------------------------- * Function isar_splitBinLCLDDecClose() * @@ -129,22 +127,22 @@ ivas_error isar_splitBinLCLDDecOpen( void isar_splitBinLCLDDecClose( ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ) { - int16_t n; + Word16 n; - if ( ( *hSplitBinLCLDDec ) != NULL ) + IF( ( *hSplitBinLCLDDec ) != NULL ) { - if ( ( *hSplitBinLCLDDec )->psLCLDDecoder != NULL ) + IF( ( *hSplitBinLCLDDec )->psLCLDDecoder != NULL ) { DeleteLCLDDecoder( ( *hSplitBinLCLDDec )->psLCLDDecoder ); } - for ( n = 0; n < ( *hSplitBinLCLDDec )->iChannels; n++ ) + FOR( n = 0; n < ( *hSplitBinLCLDDec )->iChannels; n++ ) { - free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal[n] ); - free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag[n] ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal_fx[n] ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag_fx[n] ); } - free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal ); - free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal_fx ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag_fx ); #ifdef CLDFB_DEBUG if ( ( *hSplitBinLCLDDec )->cldfbOut != NULL ) @@ -161,49 +159,49 @@ void isar_splitBinLCLDDecClose( return; } - /*------------------------------------------------------------------------- * Function isar_splitBinLCLDDecProcess() * * *------------------------------------------------------------------------*/ - void isar_splitBinLCLDDecProcess( ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, ISAR_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t bfi ) + Word32 Cldfb_Out_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_cldfb_final, + const Word16 bfi ) { - int16_t k, n; - int16_t itr; + Word16 k, n; + Word16 itr; + *Q_cldfb_final = 11; push_wmops( "isar_splitBinLCLDDecProcess" ); assert( hSplitBinLCLDDec != NULL ); - assert( Cldfb_Out_Real != NULL ); - assert( Cldfb_Out_Imag != NULL ); + assert( Cldfb_Out_Real_fx != NULL ); + assert( Cldfb_Out_Imag_fx != NULL ); assert( pBits != NULL ); - #ifdef CLDFB_DEBUG printf( "Bytes read = %d\n", iBytesWritten ); #endif - if ( !bfi ) + IF( !bfi ) { - for ( itr = 0; itr < hSplitBinLCLDDec->iNumIterations; itr++ ) + FOR( itr = 0; itr < hSplitBinLCLDDec->iNumIterations; itr++ ) { /* Initialized with zeros....... */ - for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) { - for ( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) + FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) { - hSplitBinLCLDDec->pppfDecLCLDReal[n][k] = Cldfb_Out_Real[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; - hSplitBinLCLDDec->pppfDecLCLDImag[n][k] = Cldfb_Out_Imag[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; - set_f( hSplitBinLCLDDec->pppfDecLCLDReal[n][k], 0, CLDFB_NO_CHANNELS_MAX ); - set_f( hSplitBinLCLDDec->pppfDecLCLDImag[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k] = Cldfb_Out_Real_fx[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; + hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k] = Cldfb_Out_Imag_fx[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; + set_l( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + set_l( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k], 0, CLDFB_NO_CHANNELS_MAX ); } } - DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal, hSplitBinLCLDDec->pppfDecLCLDImag ); + Word16 Q_in = 14; + DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal_fx, hSplitBinLCLDDec->pppfDecLCLDImag_fx, Q_in, Q_cldfb_final ); #ifdef CLDFB_DEBUG printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); @@ -224,33 +222,61 @@ void isar_splitBinLCLDDecProcess( } } #endif - if ( AnyDecodingFailed( hSplitBinLCLDDec->psLCLDDecoder ) ) + IF( AnyDecodingFailed( hSplitBinLCLDDec->psLCLDDecoder ) ) { + IF( NE_16( *Q_cldfb_final, 11 ) ) + { + FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) + { + FOR( Word16 j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11 + hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11 + } + } + } + *Q_cldfb_final = 11; + } /* continue concealing */ - isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, - hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ) ); + isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final ); } - if ( AnyDecodingFailedPrev( hSplitBinLCLDDec->psLCLDDecoder ) ) + IF( AnyDecodingFailedPrev( hSplitBinLCLDDec->psLCLDDecoder ) ) { + IF( NE_16( *Q_cldfb_final, 11 ) ) + { + FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) + { + FOR( Word16 j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11 + hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11 + } + } + } + *Q_cldfb_final = 11; + } /* cross-fade recovered frame into good frame */ - isar_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, - hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), GetDecodingFailedPrevStatus( hSplitBinLCLDDec->psLCLDDecoder ) ); + isar_splitBinRendPLC_xf_fx( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), GetDecodingFailedPrevStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final ); } } } - else + ELSE { /* set states in decoder */ SetDecodingUnresolved( hSplitBinLCLDDec->psLCLDDecoder ); /* do PLC for lost split renderer frame */ - isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, - hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ) ); + isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final ); } /* save PLC state */ - isar_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); - + isar_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); + hSplitBinLCLDDec->hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx = *Q_cldfb_final; + move16(); pop_wmops(); return; diff --git a/lib_isar/isar_splitRend_lcld_enc.c b/lib_isar/isar_splitRend_lcld_enc.c index 7dc10787b..0f442a2f2 100644 --- a/lib_isar/isar_splitRend_lcld_enc.c +++ b/lib_isar/isar_splitRend_lcld_enc.c @@ -40,25 +40,23 @@ #endif #include "wmc_auto.h" - /*------------------------------------------------------------------------- * Function isar_splitBinLCLDEncOpen() * * *------------------------------------------------------------------------*/ - ivas_error isar_splitBinLCLDEncOpen( ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, - const int32_t iSampleRate, - const int16_t iChannels, - const int32_t iDataRate, - const int16_t iNumBlocks, - const int16_t iNumIterations ) + const Word32 iSampleRate, + const Word16 iChannels, + const Word32 iDataRate, + const Word16 iNumBlocks, + const Word16 iNumIterations ) { ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; ivas_error error; - if ( ( splitBinLCLDEnc = (ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL ) + IF( ( splitBinLCLDEnc = (ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } @@ -66,27 +64,27 @@ ivas_error isar_splitBinLCLDEncOpen( splitBinLCLDEnc->pLcld_enc = NULL; /* place holder for CLDFB encoder handle*/ splitBinLCLDEnc->iChannels = iChannels; - if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (int16_t) CLDFB_NO_COL_MAX / iNumBlocks, 0 ) ) != IVAS_ERR_OK ) + IF( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (Word16) CLDFB_NO_COL_MAX / iNumBlocks, 0 ) ) != IVAS_ERR_OK ) { return error; } - if ( ( splitBinLCLDEnc->pppfLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == NULL ) + IF( ( splitBinLCLDEnc->pppfLCLDReal_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( splitBinLCLDEnc->pppfLCLDImag = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == NULL ) + IF( ( splitBinLCLDEnc->pppfLCLDImag_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( int16_t n = 0; n < splitBinLCLDEnc->iChannels; n++ ) + FOR( Word16 n = 0; n < splitBinLCLDEnc->iChannels; n++ ) { - if ( ( splitBinLCLDEnc->pppfLCLDReal[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == NULL ) + IF( ( splitBinLCLDEnc->pppfLCLDReal_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( splitBinLCLDEnc->pppfLCLDImag[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == NULL ) + IF( ( splitBinLCLDEnc->pppfLCLDImag_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } @@ -123,18 +121,17 @@ ivas_error isar_splitBinLCLDEncOpen( void isar_splitBinLCLDEncClose( ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ) { - if ( ( *hSplitBinLCLDEnc ) != NULL ) + IF( ( *hSplitBinLCLDEnc ) != NULL ) { DeleteLCLDEncoder( ( *hSplitBinLCLDEnc )->psLCLDEncoder ); - for ( int16_t n = 0; n < ( *hSplitBinLCLDEnc )->iChannels; n++ ) + FOR( int16_t n = 0; n < ( *hSplitBinLCLDEnc )->iChannels; n++ ) { - free( ( *hSplitBinLCLDEnc )->pppfLCLDReal[n] ); - free( ( *hSplitBinLCLDEnc )->pppfLCLDImag[n] ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDReal_fx[n] ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDImag_fx[n] ); } - free( ( *hSplitBinLCLDEnc )->pppfLCLDReal ); - free( ( *hSplitBinLCLDEnc )->pppfLCLDImag ); - + free( ( *hSplitBinLCLDEnc )->pppfLCLDReal_fx ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDImag_fx ); #ifdef CLDFB_DEBUG if ( ( *hSplitBinLCLDEnc )->cldfbIn != NULL ) { @@ -149,45 +146,45 @@ void isar_splitBinLCLDEncClose( return; } - /*------------------------------------------------------------------------- * Function isar_splitBinLCLDEncProcess() * * *------------------------------------------------------------------------*/ - void isar_splitBinLCLDEncProcess( ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, - float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int32_t available_bits, - ISAR_SPLIT_REND_BITS_HANDLE pBits ) + Word32 Cldfb_In_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word32 available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word16 *q_final ) { - int32_t iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local; + Word32 iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local; push_wmops( "isar_splitBinLCLDEncProcess" ); - assert( hSplitBinLCLDEnc != NULL ); - assert( Cldfb_In_Real != NULL ); - assert( Cldfb_In_Imag != NULL ); + assert( Cldfb_In_Real_fx != NULL ); + assert( Cldfb_In_Imag_fx != NULL ); assert( pBits != NULL ); available_bits_local = available_bits; + move32(); + Word16 tmp, tmp_e; /* A conversion is needed for the 3d pointer interface here ........ */ - for ( itr = 0; itr < hSplitBinLCLDEnc->iNumIterations; itr++ ) + FOR( itr = 0; itr < hSplitBinLCLDEnc->iNumIterations; itr++ ) { - rem_itr = hSplitBinLCLDEnc->iNumIterations - itr; - available_bits_itr = available_bits_local / rem_itr; - - for ( int32_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + rem_itr = L_sub( hSplitBinLCLDEnc->iNumIterations, itr ); + tmp = BASOP_Util_Divide3232_Scale( available_bits_local, rem_itr, &tmp_e ); + available_bits_itr = shr( tmp, sub( 15, tmp_e ) ); // Q0 + // available_bits_itr = available_bits_local / rem_itr; + FOR( Word32 n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) { - for ( int32_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) + FOR( Word32 k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) { - hSplitBinLCLDEnc->pppfLCLDReal[n][k] = Cldfb_In_Real[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; - hSplitBinLCLDEnc->pppfLCLDImag[n][k] = Cldfb_In_Imag[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; + hSplitBinLCLDEnc->pppfLCLDReal_fx[n][k] = Cldfb_In_Real_fx[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; + hSplitBinLCLDEnc->pppfLCLDImag_fx[n][k] = Cldfb_In_Imag_fx[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; } } - #ifdef CLDFB_DEBUG int16_t readByte = 0; for ( int16_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) @@ -224,9 +221,9 @@ void isar_splitBinLCLDEncProcess( } } #endif - EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal, hSplitBinLCLDEnc->pppfLCLDImag, &iBitsWritten, available_bits_itr, pBits ); + EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal_fx, hSplitBinLCLDEnc->pppfLCLDImag_fx, &iBitsWritten, available_bits_itr, pBits, q_final ); - available_bits_local -= iBitsWritten; + available_bits_local = L_sub( available_bits_local, iBitsWritten ); #ifdef DEBUGGING assert( available_bits_local >= 0 ); #endif diff --git a/lib_isar/isar_splitRendererPLC.c b/lib_isar/isar_splitRendererPLC.c index 515d67188..152fe52f3 100644 --- a/lib_isar/isar_splitRendererPLC.c +++ b/lib_isar/isar_splitRendererPLC.c @@ -36,281 +36,990 @@ #include #include "ivas_prot.h" #include "prot.h" -#include "ivas_cnst.h" +#include "isar_cnst.h" #include "isar_prot.h" +#include "enh64.h" #ifdef DEBUGGING #include "debug.h" #endif #include "wmc_auto.h" - +#include "prot_fx2.h" +#include "basop_util.h" +#include "basop_mpy.h" +#include "enh64.h" /*------------------------------------------------------------------------- * Local constants *------------------------------------------------------------------------*/ - +#define PI_CONST ( 341782638 ) // Q31 +#define DO_PERTURB 1 +#define PH_PERT_ONLY 1 #define START_VAL_AVG_LEN 2 #define SR_PLC_FADE_START 10 /* start fading at this number of bad frames in row */ #define SR_PLC_MUTE 30 /* Total mute at this number of bad frames in row */ #define SR_PLC_FADE_DEGREE -3 /* fading degree per frame in dB */ #define SRHO_THRESH ( 2.f / 3.f * 0.1f ) +#define SRHO_THRESH_FX ( 143165584 ) +#define STH_THRESH_FX ( 749613227 ) #define STH_THRESH ( 2.f / 3.f * PI2 / 12 ) - +#define PLC_FADE_CNST SR_PLC_FADE_START *CLDFB_NO_COL_MAX +#define PLC_MUTE_CNST SR_PLC_MUTE *CLDFB_NO_COL_MAX +Word32 xf_alp_tab[CLDFB_PLC_XF] = { 1431655680, 715827840 }; +static Word16 find_guarded_bits_fx( Word32 n ) +{ + return n <= 1 ? 0 : n <= 2 ? 1 + : n <= 4 ? 2 + : n <= 8 ? 3 + : n <= 16 ? 4 + : n <= 32 ? 5 + : n <= 64 ? 6 + : n <= 128 ? 7 + : n <= 256 ? 8 + : n <= 512 ? 9 + : n <= 1024 ? 10 + : n <= 2048 ? 11 + : n <= 4096 ? 12 + : n <= 8192 ? 13 + : n <= 16384 ? 14 + : 15; +} /*------------------------------------------------------------------------- * Function adaptive_polar_ext_plc() * * *------------------------------------------------------------------------*/ +static void adaptive_polar_ext_plc_fx( + const Word32 *prev_real_fx, + const Word32 *prev_imag_fx, + Word32 *rec_real_fx, + Word32 *rec_imag_fx, + Word16 *rec_real_exp, + Word16 *rec_imag_exp +#if CLDFB_PLC_XF > 0 + , + Word32 xf_alp_fx[CLDFB_PLC_XF], + Word32 xf_bet_fx[CLDFB_PLC_XF] +#endif + , + Word16 exp, + const Word16 iNumCols ) -static void adaptive_polar_ext_plc( - const float *prev_real, - const float *prev_imag, - float *rec_real, - float *rec_imag, - float xf_alp[CLDFB_PLC_XF], - float xf_bet[CLDFB_PLC_XF], - const int16_t iNumCols ) { - float uth[CLDFB_NO_COL_MAX], uthu[CLDFB_NO_COL_MAX], urh[CLDFB_NO_COL_MAX]; - float ph_adj, ph_diff, ph_adj_t, quot, drho, srho, diff, dth, sth, fac_real, fac_imag; - float Ruu_real[2], Ruu_imag[2]; - float start_real, start_imag, abs_fac, abs_fac_powj, comp_fac, fac_powj_real, fac_powj_imag, temp, abs2inv; - float fac_ph_real, fac_ph_imag, rat_real, rat_imag, abs_temp; - int32_t k, j; - + /*TODO: Add basops and instrumentation where ever possible*/ + Word32 uth_fx[CLDFB_NO_COL_MAX], urh_fx[CLDFB_NO_COL_MAX]; + Word64 uthu_fx[CLDFB_NO_COL_MAX], drho_fx, srho_fx, diff_fx, dth_fx, sth_fx, ph_adj_fx, rat_real_fx, rat_imag_fx; + Word32 ph_diff_fx, ph_adj_t_fx, quot_fx, dth32, fac_real_fx, fac_imag_fx, rat_real32_fx, rat_imag32_fx, abs2inv_fx; + Word16 srho_q, sth_q, dth16, drho_q, rat_real_q, rat_imag_q, temp_16, rat_real_sum_q, rat_imag_sum_q, start_q, fac_real_q, fac_imag_q; + Word64 Ruu_real_fx[2], Ruu_imag_fx[2], abs_fac_fx; + Word32 Ruu_real_fx_1, Ruu_imag_fx_1, Ruu_real_fx_0, abs_fac_32, abs_fac_powj_32, comp_fac_fx; + Word16 Ruu_real_fx_1_q, Ruu_imag_fx_1_q, Ruu_real_fx_0_q, dth_q, urh_exp[CLDFB_NO_COL_MAX]; + Word32 fac_ph_real_fx, fac_ph_imag_fx, abs_temp_fx; + Word32 start_real_fx, start_imag_fx, fac_powj_real_fx, fac_powj_imag_fx, temp_fx; + Word32 k, j; + Word16 quot_exp[CLDFB_NO_COL_MAX]; + Word16 drho_exp[CLDFB_NO_COL_MAX]; + Word16 srho_exp[CLDFB_NO_COL_MAX]; + /* Word16 rec_real_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; + Word16 rec_imag_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF];*/ /* reset of accumulators */ - ph_adj = 0.0f; - drho = 0.0f; - srho = 0.0f; - dth = 0.0f; - sth = 0.0f; - + ph_adj_fx = 0; + drho_fx = 0; + srho_fx = 0; + dth_fx = 0; + sth_fx = 0; + Word16 sqrt_exp = 0, sqrt_exp1; + Word32 temp_32; + Word16 lshift; + Word64 temp_64, real_sum, imag_sum; /* calculate per-sample phase and magnitude evolution in preceding frame */ - for ( k = 0; k < iNumCols; k++ ) + FOR( k = 0; k < iNumCols; k++ ) { - urh[k] = sqrtf( prev_imag[k] * prev_imag[k] + prev_real[k] * prev_real[k] ); - if ( urh[k] < EPSILON ) + real_sum = W_mult_32_32( prev_real_fx[k], prev_real_fx[k] ); + rat_real_sum_q = add( shl( exp, 1 ), 1 ); + imag_sum = W_mult_32_32( prev_imag_fx[k], prev_imag_fx[k] ); + rat_imag_sum_q = add( shl( exp, 1 ), 1 ); + temp_64 = W_add( real_sum, imag_sum ); + lshift = W_norm( temp_64 ); + temp_32 = W_extract_h( W_shl( temp_64, lshift ) ); + sqrt_exp = sub( add( shl( exp, 1 ), lshift ), 31 ); + sqrt_exp = sub( 31, sqrt_exp ); + urh_fx[k] = Sqrt32( temp_32, &sqrt_exp ); + urh_exp[k] = sub( 31, sqrt_exp ); + // In Float the condition is if ( urh[k] < EPSILON ) + IF( EQ_32( urh_fx[k], 0 ) ) { /* zero encountered */ - break; + BREAK; } - uth[k] = atan2f( prev_imag[k], prev_real[k] ); + uth_fx[k] = L_shl( BASOP_util_atan2( prev_imag_fx[k], prev_real_fx[k], 0 ), 15 ); // Q28 /* phase unwrap */ - if ( k == 0 ) + IF( EQ_32( k, 0 ) ) { - uthu[0] = uth[0]; + uthu_fx[0] = uth_fx[0]; } - else + ELSE { /* phase unwrap */ - ph_diff = uth[k] - uth[k - 1]; - uthu[k] = uth[k]; - if ( fabsf( ph_diff ) >= PI2 / 2 ) + ph_diff_fx = L_sub( uth_fx[k], uth_fx[k - 1] ); + + uthu_fx[k] = uth_fx[k]; + Word32 quot_fx_durho; + Word16 s = 0, s_diff; + Word32 add_fact, quo_sq; + IF( GE_32( L_abs( ph_diff_fx ), L_shr( PI2_FX, 2 ) ) ) { - ph_adj_t = ph_diff / PI2; - if ( fabsf( ph_adj_t - truncf( ph_adj_t ) ) == 0.5f ) + temp_32 = L_deposit_h( BASOP_Util_Divide3232_Scale( ph_diff_fx, PI2_FX, &s ) ); // Q(31) + ph_adj_t_fx = ( temp_32 == ONE_IN_Q30 ) ? L_sub( ONE_IN_Q31, 1 ) : L_shl( temp_32, s ); + IF( EQ_32( L_abs( L_sub( L_add( ph_adj_t_fx, 1 ), L_shr( ph_adj_t_fx, 31 ) ) ), ONE_IN_Q30 ) ) { - ph_adj_t = truncf( ph_adj_t ); + ph_adj_t_fx = L_shr( ph_adj_t_fx, 31 ); } - ph_adj = -PI2 * roundf( ph_adj_t ) + ph_adj; + add_fact = ( L_abs( ph_adj_t_fx ) >= ONE_IN_Q30 ) ? ( ( ph_adj_t_fx < 0 ) ? 1686629713 : -1686629713 ) : 0; + ph_adj_fx = W_add( add_fact, ph_adj_fx ); // Q28 } - uthu[k] += ph_adj; /* unwrapped phase in uthu */ - + uthu_fx[k] = W_add( uthu_fx[k], ph_adj_fx ); // Q28 /* mean and stdev of per-sample magnitude ratios */ - quot = urh[k] / urh[k - 1]; - drho += quot; - srho += SQR( quot ); + s_diff = sub( urh_exp[k - 1], urh_exp[k] ); + temp_16 = BASOP_Util_Divide3232_Scale( urh_fx[k], urh_fx[k - 1], &s ); + quot_fx = L_shl( temp_16, 16 ); // Q(31-s) + quot_exp[k] = sub( sub( 31, s_diff ), s ); + quot_fx_durho = quot_fx; + drho_exp[k] = quot_exp[k]; + IF( GE_32( k, 2 ) ) + { + IF( LT_16( drho_exp[k - 1], drho_exp[k] ) ) + { + quot_fx_durho = L_shr( quot_fx_durho, sub( drho_exp[k], drho_exp[k - 1] ) ); + drho_exp[k] = drho_exp[k - 1]; + } + ELSE IF( GT_16( drho_exp[k - 1], drho_exp[k] ) ) + { + drho_fx = W_shr( drho_fx, sub( drho_exp[k - 1], drho_exp[k] ) ); + } + } + drho_fx = W_add( quot_fx_durho, drho_fx ); // Q(31-s) + srho_exp[k] = sub( 31, shl( add( s_diff, s ), 1 ) ); + quo_sq = Mpy_32_32( quot_fx, quot_fx ); + IF( GE_32( k, 2 ) ) + { + IF( LT_16( srho_exp[k - 1], srho_exp[k] ) ) + { + quo_sq = L_shr( quo_sq, sub( srho_exp[k], srho_exp[k - 1] ) ); + srho_exp[k] = srho_exp[k - 1]; + } + ELSE IF( GT_16( srho_exp[k - 1], srho_exp[k] ) ) + { + srho_fx = W_shr( srho_fx, sub( srho_exp[k - 1], srho_exp[k] ) ); + } + } + srho_fx = W_add( srho_fx, quo_sq ); // Q(31-s) + diff_fx = W_sub( uthu_fx[k], uthu_fx[k - 1] ); // Q28 /* the mean value calculation could be optimized */ + + dth_fx = W_add( dth_fx, diff_fx ); // Q28 + temp_32 = W_extract_l( diff_fx ); + sth_fx = W_add( sth_fx, (Word64) Mpy_32_32( temp_32, temp_32 ) ); // Q25 + /* mean and stdev of per-sample phase differences */ - diff = uthu[k] - uthu[k - 1]; /* the mean value calculation could be optimized */ - dth += diff; - sth += SQR( diff ); } } - if ( k == iNumCols ) + Word16 tmp_e, tmp, drho_sqr_q, temp_q; + Word32 divide_fact, drho_32, drho_sqr, dth_sqr; + IF( EQ_32( k, iNumCols ) ) { + + tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 1 ), &tmp_e ); + divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31 /* mean and stdev of per-sample magnitude ratios */ - drho *= 1.0f / ( iNumCols - 1 ); - temp = srho - ( iNumCols - 1 ) * SQR( drho ); - if ( temp > 0 ) + lshift = W_norm( drho_fx ); + tmp_e = drho_exp[k - 1]; + IF( LT_16( lshift, 32 ) ) { - srho = sqrtf( temp * ( 1.0f / ( iNumCols - 2 ) ) ); + drho_fx = W_shl( drho_fx, lshift ); + tmp_e = add( tmp_e, lshift ); } - else + drho_32 = W_extract_h( drho_fx ); // Qtmp_e-32 + drho_32 = Mpy_32_32( drho_32, divide_fact ); + drho_sqr = Mpy_32_32( drho_32, drho_32 ); // Q(2*(tmp_e -32) - 31) + temp_64 = W_mult_32_32( sub( iNumCols, 1 ), drho_sqr ); // Q(2*(tmp_e -32) - 30) + drho_sqr_q = sub( shl( sub( tmp_e, 32 ), 1 ), 30 ); + temp_q = srho_exp[k - 1]; + IF( GT_16( srho_exp[k - 1], drho_sqr_q ) ) { - srho = 0.0f; + temp_64 = W_shl( temp_64, sub( srho_exp[k - 1], drho_sqr_q ) ); + temp_q = srho_exp[k - 1]; + } + ELSE IF( GT_16( drho_sqr_q, srho_exp[k - 1] ) ) + { + srho_fx = W_shl( srho_fx, sub( drho_sqr_q, srho_exp[k - 1] ) ); + temp_q = drho_sqr_q; + } + temp_64 = W_sub( srho_fx, temp_64 ); + drho_q = sub( tmp_e, 32 ); + IF( GT_64( temp_64, 0 ) ) + { + lshift = W_norm( temp_64 ); + temp_32 = W_extract_h( W_shl( temp_64, lshift ) ); + sqrt_exp = sub( add( temp_q, lshift ), 32 ); + tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 2 ), &tmp_e ); + divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31 + temp_32 = Mpy_32_32( temp_32, divide_fact ); // Qsqrt_exp + sqrt_exp1 = sub( 31, sqrt_exp ); + srho_fx = Sqrt32( temp_32, &sqrt_exp1 ); + srho_q = sub( 31, sqrt_exp1 ); + } + ELSE + { + srho_q = 31; + srho_fx = 0; } - /* mean and stdev of per-sample phase differences */ - dth *= 1.0f / ( iNumCols - 1 ); - temp = sth - ( iNumCols - 1 ) * SQR( dth ); - if ( temp > 0 ) + tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 1 ), &tmp_e ); + divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31 + /* mean and stdev of per-sample phase differences */ + lshift = W_norm( dth_fx ); + dth_fx = W_shl( dth_fx, lshift ); // Q28+lshift + dth32 = W_extract_h( dth_fx ); // Q28+lshift-32 + dth_q = sub( add( 28, lshift ), 32 ); + dth32 = Mpy_32_32( dth32, divide_fact ); + dth_sqr = Mpy_32_32( dth32, dth32 ); // Q28+lshift-32 + temp_64 = W_mult_32_32( sub( iNumCols, 1 ), dth_sqr ); // Q(2*lshift-39) + temp_q = sub( sub( shl( lshift, 1 ), 8 ), 30 ); + // printf( "%f \t", temp ); + IF( GT_16( temp_q, 25 ) ) { - sth = sqrtf( temp * ( 1.0f / ( iNumCols - 2 ) ) ); + + sth_fx = W_shl( sth_fx, sub( temp_q, 25 ) ); } - else + ELSE IF( GT_16( 25, temp_q ) ) { - sth = 0.0f; + temp_64 = W_shl( temp_64, sub( 25, temp_q ) ); + temp_q = 25; } - /* do phase extension only if the std deviations are small */ - if ( ( srho < SRHO_THRESH ) || ( sth < STH_THRESH ) ) + temp_64 = W_sub( sth_fx, temp_64 ); + IF( GT_64( temp_64, 0 ) ) + { + lshift = W_norm( temp_64 ); + temp_32 = W_extract_h( W_shl( temp_64, lshift ) ); + sqrt_exp = sub( add( temp_q, lshift ), 32 ); + tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 2 ), &tmp_e ); + divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31 + temp_32 = Mpy_32_32( temp_32, divide_fact ); // Qsqrt_exp + sqrt_exp1 = sub( 31, sqrt_exp ); + sth_fx = Sqrt32( temp_32, &sqrt_exp1 ); + sth_q = sub( 31, sqrt_exp1 ); + } + ELSE { - /* calculate complex evolution factor */ - fac_ph_real = cosf( dth ); - fac_ph_imag = sinf( dth ); - fac_real = min( 1, drho ) * fac_ph_real; - fac_imag = min( 1, drho ) * fac_ph_imag; - - /* Calculate start value for evolution from last samples of previous frame */ - fac_powj_real = fac_real; - fac_powj_imag = fac_imag; + sth_fx = 0; + sth_q = 31; + } + + /* do phase extension only IF the std deviations are small */ + IF( LT_64( srho_fx, W_shl( SRHO_THRESH_FX, sub( srho_q, 31 ) ) ) || LT_64( sth_fx, W_shl( STH_THRESH_FX, sub( sth_q, 31 ) ) ) ) + { + dth32 = L_shl( Mpy_32_32( dth32, PI_CONST ), sub( 31, dth_q ) ); // Q28+lshift-32-16 + dth16 = extract_h( dth32 ); + fac_ph_real_fx = L_deposit_h( getCosWord16R2( dth16 ) ); + fac_ph_imag_fx = L_deposit_h( getSineWord16R2( dth16 ) ); + ///* calculate complex evolution factor */ + fac_real_fx = Mpy_32_32( min( L_shl( 1, drho_q ), drho_32 ), fac_ph_real_fx ); // Qdrho_exp + fac_imag_fx = Mpy_32_32( min( L_shl( 1, drho_q ), drho_32 ), fac_ph_imag_fx ); // Qdrho_exp +#if START_VAL_AVG_LEN > 1 + /* Calculate start value FOR evolution from last samples of previous frame */ + fac_powj_real_fx = fac_real_fx; + fac_powj_imag_fx = fac_imag_fx; + start_real_fx = prev_real_fx[iNumCols - 1]; + start_imag_fx = prev_imag_fx[iNumCols - 1]; + FOR( j = 1; j < START_VAL_AVG_LEN; j++ ) + { + start_real_fx = L_add( L_shr( start_real_fx, sub( exp, sub( add( drho_q, exp ), 31 ) ) ), L_sub( Mpy_32_32( fac_powj_real_fx, prev_real_fx[iNumCols - j - 1] ), Mpy_32_32( fac_powj_imag_fx, prev_imag_fx[iNumCols - j - 1] ) ) ); // Q(drho_q+exp-31) + start_imag_fx = L_add( L_shr( start_imag_fx, sub( exp, sub( add( drho_q, exp ), 31 ) ) ), L_add( Mpy_32_32( fac_powj_imag_fx, prev_real_fx[iNumCols - j - 1] ), Mpy_32_32( fac_powj_real_fx, prev_imag_fx[iNumCols - j - 1] ) ) ); // Q(drho_q+exp-31) + temp_fx = L_shl( L_sub( Mpy_32_32( fac_powj_real_fx, fac_real_fx ), Mpy_32_32( fac_powj_imag_fx, fac_imag_fx ) ), sub( sub( drho_q, shl( drho_q, 1 ) ), 31 ) ); // Qdrho_q + fac_powj_imag_fx = L_shl( L_add( Mpy_32_32( fac_powj_imag_fx, fac_real_fx ), Mpy_32_32( fac_powj_real_fx, fac_imag_fx ) ), sub( sub( drho_q, shl( drho_q, 1 ) ), 31 ) ); // Qdrho_q + fac_powj_real_fx = temp_fx; + } + start_q = sub( add( drho_q, exp ), 30 ); +#else + /* take last sample of previous frame as start value */ start_real = prev_real[iNumCols - 1]; start_imag = prev_imag[iNumCols - 1]; - for ( j = 1; j < START_VAL_AVG_LEN; j++ ) +#endif + +#if DO_PERTURB != 0 + + /* make evolution less static: apply per samples differences as in preceding frame */ + rat_real_fx = W_add( W_mult_32_32( prev_real_fx[1], prev_real_fx[0] ), W_mult_32_32( prev_imag_fx[1], prev_imag_fx[0] ) ); // 2*exp + rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[1], prev_imag_fx[0] ), W_mult_32_32( prev_imag_fx[1], prev_real_fx[0] ) ); // 2*exp + +#if PH_PERT_ONLY != 0 + + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx ); + rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx ); + rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + temp_32 = W_extract_h( temp_64 ); + sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + /* only phase perturbation */ + sqrt_exp = sub( 31, sqrt_exp ); + tmp_e = 0; + abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp) + + lshift = norm_l( drho_32 ); + drho_32 = L_shl( drho_32, lshift ); + drho_q = add( drho_q, lshift ); + IF( EQ_16( drho_q, 31 ) ) { - start_real += fac_powj_real * prev_real[iNumCols - j - 1] - fac_powj_imag * prev_imag[iNumCols - j - 1]; - start_imag += fac_powj_imag * prev_real[iNumCols - j - 1] + fac_powj_real * prev_imag[iNumCols - j - 1]; - temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; - fac_powj_imag = fac_powj_imag * fac_real + fac_powj_real * fac_imag; - fac_powj_real = temp; + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( L_min( ONE_IN_Q31, drho_32 ), L_max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e } - start_real *= 1.0f / START_VAL_AVG_LEN; - start_imag *= 1.0f / START_VAL_AVG_LEN; + ELSE + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( L_min( L_shl( 1, drho_q ), drho_32 ), L_max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e ); - /* make evolution less static: apply per samples differences as in preceding frame */ - rat_real = ( prev_real[1] * prev_real[0] + prev_imag[1] * prev_imag[0] ); - rat_imag = ( -prev_real[1] * prev_imag[0] + prev_imag[1] * prev_real[0] ); + rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx ); - /* only phase perturbation */ - abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); - abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); + rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx ); + rat_real_q = add( add( rat_real_q, temp_16 ), 1 ); + + rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 ); + +#else + /* phase and magnitude perturbation */ + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[0] ) + SQR( prev_imag[0] ) ) ); rat_real *= abs2inv; rat_imag *= abs2inv; - - /* apply complex evolution for first substitution sample */ - rec_real[0] = rat_real * start_real - rat_imag * start_imag; - rec_imag[0] = rat_imag * start_real + rat_real * start_imag; - for ( j = 2; j < iNumCols; j++ ) +#endif + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( rat_real_q, lshift ), 32 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( rat_imag_q, lshift ), 32 ); + + /* apply complex evolution FOR first substitution sample */ + + real_sum = W_mult_32_32( rat_real32_fx, start_real_fx ); + rat_real_sum_q = add( add( rat_real_q, start_q ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, start_imag_fx ); + rat_imag_sum_q = add( add( rat_imag_q, start_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE { - /* make evolution less static: apply per samples differences as in preceding frame */ - rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] ); - rat_imag = ( -prev_real[j] * prev_imag[j - 1] + prev_imag[j] * prev_real[j - 1] ); + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_sub( real_sum, imag_sum ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_real_fx[0] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_real_exp[0] = sub( add( sqrt_exp, lshift ), 32 ); + + real_sum = W_mult_32_32( rat_imag32_fx, start_real_fx ); + rat_real_sum_q = add( add( rat_imag_q, start_q ), 1 ); + imag_sum = W_mult_32_32( rat_real32_fx, start_imag_fx ); + rat_imag_sum_q = add( add( rat_real_q, start_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( real_sum, imag_sum ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_imag_fx[0] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_imag_exp[0] = sub( add( sqrt_exp, lshift ), 32 ); + FOR( j = 2; j < iNumCols; j++ ) + { + rat_real_fx = W_add( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ) ); // 2*exp + rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[j], prev_imag_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ) ); // 2*exp +#if PH_PERT_ONLY != 0 + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx ); + rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx ); + rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + temp_32 = W_extract_h( temp_64 ); + sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); /* only phase perturbation */ - abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); - abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); - - rat_real *= abs2inv; - rat_imag *= abs2inv; - /* apply complex evolution for further substitution samples */ - rec_real[j - 1] = rat_real * rec_real[j - 2] - rat_imag * rec_imag[j - 2]; - rec_imag[j - 1] = rat_imag * rec_real[j - 2] + rat_real * rec_imag[j - 2]; - } + sqrt_exp = sub( 31, sqrt_exp ); + tmp_e = 0; + abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp) - /* do the same for samples of crossfade region */ - for ( j = 1; j < CLDFB_PLC_XF + 2; j++ ) - { - rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] ); - rat_imag = ( -prev_real[j] * prev_imag[j - 1] + prev_imag[j] * prev_real[j - 1] ); + IF( EQ_16( drho_q, 31 ) ) + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( ONE_IN_Q31, drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + ELSE + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( L_shl( 1, drho_q ), drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e ); + + rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx ); + rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx ); + rat_real_q = add( add( rat_real_q, temp_16 ), 1 ); + rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 ); - abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); - abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); +#else + /* phase and magnitude perturbation */ + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) ); +#endif - rat_real *= abs2inv; - rat_imag *= abs2inv; - rec_real[j + iNumCols - 2] = rat_real * rec_real[j + iNumCols - 3] - rat_imag * rec_imag[j + iNumCols - 3]; - rec_imag[j + iNumCols - 2] = rat_imag * rec_real[j + iNumCols - 3] + rat_real * rec_imag[j + iNumCols - 3]; + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( rat_real_q, lshift ), 32 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( rat_imag_q, lshift ), 32 ); + + + real_sum = W_mult_32_32( rat_real32_fx, rec_real_fx[j - 2] ); + rat_real_sum_q = add( add( rat_real_q, rec_real_exp[j - 2] ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rec_imag_fx[j - 2] ); + rat_imag_sum_q = add( add( rat_imag_q, rec_imag_exp[j - 2] ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_sub( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_real_fx[j - 1] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_real_exp[j - 1] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + + real_sum = W_mult_32_32( rat_imag32_fx, rec_real_fx[j - 2] ); + rat_real_sum_q = add( add( rat_imag_q, rec_real_exp[j - 2] ), 1 ); + imag_sum = W_mult_32_32( rat_real32_fx, rec_imag_fx[j - 2] ); + rat_imag_sum_q = add( add( rat_real_q, rec_imag_exp[j - 2] ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_imag_fx[j - 1] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_imag_exp[j - 1] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); } + /* do the same FOR samples of crossfade region */ + FOR( j = 1; j < CLDFB_PLC_XF + 2; j++ ) + { + rat_real_fx = W_add( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ) ); // 2*exp + rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[j], prev_imag_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ) ); // 2*exp + +#if PH_PERT_ONLY != 0 + + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx ); + rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx ); + rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + temp_32 = W_extract_h( temp_64 ); + sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + /* only phase perturbation */ + sqrt_exp = sub( 31, sqrt_exp ); + tmp_e = 0; + abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp) + IF( EQ_16( drho_q, 31 ) ) + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( ONE_IN_Q31, drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + ELSE + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( L_shl( 1, drho_q ), drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e ); + rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx ); + rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx ); + rat_real_q = add( add( rat_real_q, temp_16 ), 1 ); + rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 ); +#else + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) ); +#endif + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( rat_real_q, lshift ), 32 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( rat_imag_q, lshift ), 32 ); + + + real_sum = W_mult_32_32( rat_real32_fx, rec_real_fx[j + iNumCols - 3] ); + rat_real_sum_q = add( add( rat_real_q, rec_real_exp[j + iNumCols - 3] ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rec_imag_fx[j + iNumCols - 3] ); + rat_imag_sum_q = add( add( rat_imag_q, rec_imag_exp[j + iNumCols - 3] ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_sub( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_real_fx[j + iNumCols - 2] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_real_exp[j + iNumCols - 2] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + + real_sum = W_mult_32_32( rat_imag32_fx, rec_real_fx[j + iNumCols - 3] ); + rat_real_sum_q = add( add( rat_imag_q, rec_real_exp[j + iNumCols - 3] ), 1 ); + imag_sum = W_mult_32_32( rat_real32_fx, rec_imag_fx[j + iNumCols - 3] ); + rat_imag_sum_q = add( add( rat_real_q, rec_imag_exp[j + iNumCols - 3] ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_imag_fx[j + iNumCols - 2] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_imag_exp[j + iNumCols - 2] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + } +#else + rec_real[0] = fac_real * start_real - fac_imag * start_imag; + rec_imag[0] = fac_imag * start_real + fac_real * start_imag; + FOR( j = 1; j < iNumCols + CLDFB_PLC_XF; j++ ) + { + rec_real[j] = fac_real * rec_real[j - 1] - fac_imag * rec_imag[j - 1]; + rec_imag[j] = fac_imag * rec_real[j - 1] + fac_real * rec_imag[j - 1]; + } +#endif + +#if CLDFB_PLC_XF > 0 /* apply crossfade */ - for ( j = 0; j < CLDFB_PLC_XF; j++ ) + FOR( j = 0; j < CLDFB_PLC_XF; j++ ) { - rec_real[iNumCols + j] *= xf_alp[j]; - rec_imag[iNumCols + j] *= xf_alp[j]; - xf_bet[j] = 1 - xf_alp[j]; + rec_real_fx[iNumCols + j] = Mpy_32_32( xf_alp_fx[j], rec_real_fx[iNumCols + j] ); + rec_imag_fx[iNumCols + j] = Mpy_32_32( xf_alp_fx[j], rec_imag_fx[iNumCols + j] ); + xf_bet_fx[j] = L_sub( ONE_IN_Q31, xf_alp_fx[j] ); } +#endif } - else + ELSE { + Word16 guard_bits = find_guarded_bits_fx( iNumCols ); /* do complex lpc combined with frame repetition */ - Ruu_real[0] = SQR( prev_real[0] ) + SQR( prev_imag[0] ); - Ruu_real[1] = 0; - Ruu_imag[1] = 0; - for ( j = 1; j < iNumCols; j++ ) + Ruu_real_fx[0] = W_add( W_shr( W_mult_32_32( prev_real_fx[0], prev_real_fx[0] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[0], prev_imag_fx[0] ), guard_bits ) ); + Ruu_real_fx[1] = 0; + Ruu_imag_fx[1] = 0; + FOR( j = 1; j < iNumCols; j++ ) { - Ruu_real[0] += SQR( prev_real[j] ) + SQR( prev_imag[j] ); - Ruu_real[1] += prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1]; - Ruu_imag[1] += prev_imag[j] * prev_real[j - 1] - prev_real[j] * prev_imag[j - 1]; + Ruu_real_fx[0] = W_add( Ruu_real_fx[0], W_add( W_shr( W_mult_32_32( prev_real_fx[j], prev_real_fx[j] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j] ), guard_bits ) ) ); + Ruu_real_fx[1] = W_add( Ruu_real_fx[1], W_add( W_shr( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ), guard_bits ) ) ); + Ruu_imag_fx[1] = W_add( Ruu_imag_fx[1], W_sub( W_shr( W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ), guard_bits ), W_shr( W_mult_32_32( prev_real_fx[j], prev_imag_fx[j - 1] ), guard_bits ) ) ); } - if ( Ruu_real[0] > EPSILON ) + // printf( "%.7f \t", Ruu_real[1] + lshift = W_norm( Ruu_real_fx[0] ); + Ruu_real_fx_0 = W_extract_h( W_shl( Ruu_real_fx[0], lshift ) ); + Ruu_real_fx_0_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 ); + lshift = W_norm( Ruu_real_fx[0] ); + Ruu_real_fx_1 = W_extract_h( W_shl( Ruu_real_fx[1], lshift ) ); + Ruu_real_fx_1_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 ); + lshift = W_norm( Ruu_real_fx[0] ); + Ruu_imag_fx_1 = W_extract_h( W_shl( Ruu_imag_fx[1], lshift ) ); + Ruu_imag_fx_1_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 ); + IF( GT_64( Ruu_real_fx[0], 0 ) ) { /* prediction coefficient */ - fac_real = Ruu_real[1] / Ruu_real[0]; - fac_imag = Ruu_imag[1] / Ruu_real[0]; + fac_real_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( Ruu_real_fx_1, Ruu_real_fx_0, &tmp_e ) ); + fac_real_q = sub( add( sub( 31, tmp_e ), Ruu_real_fx_1_q ), Ruu_real_fx_0_q ); + fac_imag_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( Ruu_imag_fx_1, Ruu_real_fx_0, &tmp_e ) ); + fac_imag_q = sub( add( sub( 31, tmp_e ), Ruu_imag_fx_1_q ), Ruu_real_fx_0_q ); } - else + ELSE { - fac_real = 0; - fac_imag = 0; + fac_imag_fx = 0; + fac_imag_q = 31; + fac_real_fx = 0; + fac_real_q = 31; } /* apply prediction using last sample of preceding frame as start value and combine with previous frame samples */ - fac_powj_real = fac_real; - fac_powj_imag = fac_imag; - abs_fac = sqrtf( SQR( fac_real ) + SQR( fac_imag ) ); - abs_fac_powj = abs_fac; - for ( j = 0; j < iNumCols; j++ ) + fac_powj_real_fx = fac_real_fx; + fac_powj_imag_fx = fac_imag_fx; + + Word16 powj_real_q = fac_real_q; + Word16 powj_imag_q = fac_imag_q; + + real_sum = W_mult_32_32( fac_real_fx, fac_real_fx ); + rat_real_sum_q = add( shl( fac_real_q, 1 ), 1 ); + imag_sum = W_mult_32_32( fac_imag_fx, fac_imag_fx ); + rat_imag_sum_q = add( shl( fac_imag_q, 1 ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE { - comp_fac = 1 - abs_fac_powj; - rec_real[j] = prev_real[iNumCols - 1] * fac_powj_real - prev_imag[iNumCols - 1] * fac_powj_imag + - prev_real[j] * comp_fac; - rec_imag[j] = prev_real[iNumCols - 1] * fac_powj_imag + prev_imag[iNumCols - 1] * fac_powj_real + - prev_imag[j] * comp_fac; - abs_fac_powj = abs_fac_powj * abs_fac; - temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; - fac_powj_imag = fac_powj_real * fac_imag + fac_powj_imag * fac_real; - fac_powj_real = temp; + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + abs_fac_fx = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( abs_fac_fx ); + abs_fac_32 = W_extract_h( W_shl( abs_fac_fx, lshift ) ); + sqrt_exp = sub( 31, ( sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ) ) ); + abs_fac_32 = Sqrt32( abs_fac_32, &sqrt_exp ); + sqrt_exp = sub( 31, sqrt_exp ); + abs_fac_32 = L_shr( abs_fac_32, sub( sqrt_exp, 31 ) ); // Q31 + sqrt_exp = 31; + abs_fac_powj_32 = L_shr( abs_fac_32, 1 ); // Q30 + sqrt_exp = 30; + + FOR( j = 0; j < iNumCols; j++ ) + { + comp_fac_fx = L_sub( L_shl( 1, sqrt_exp ), abs_fac_powj_32 ); + real_sum = W_mult_32_32( prev_real_fx[iNumCols - 1], fac_powj_real_fx ); + rat_real_sum_q = add( add( exp, powj_real_q ), 1 ); + imag_sum = W_mult_32_32( prev_imag_fx[iNumCols - 1], fac_powj_imag_fx ); + rat_imag_sum_q = add( add( exp, powj_imag_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + rat_real_sum_q = sub( rat_real_sum_q, guard_bits ); + imag_sum = W_mult_32_32( prev_real_fx[j], comp_fac_fx ); + rat_imag_sum_q = add( add( exp, sqrt_exp ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + lshift = W_norm( real_sum ); + rec_real_fx[j] = W_extract_h( W_shl( real_sum, lshift ) ); + rec_real_exp[j] = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + real_sum = W_mult_32_32( prev_real_fx[iNumCols - 1], fac_powj_imag_fx ); + rat_real_sum_q = add( add( exp, powj_imag_q ), 1 ); + imag_sum = W_mult_32_32( prev_imag_fx[iNumCols - 1], fac_powj_real_fx ); + rat_imag_sum_q = add( add( exp, powj_real_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + rat_real_sum_q = sub( rat_real_sum_q, guard_bits ); + imag_sum = W_mult_32_32( prev_imag_fx[j], comp_fac_fx ); + rat_imag_sum_q = add( add( exp, sqrt_exp ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + + lshift = W_norm( real_sum ); + rec_imag_fx[j] = W_extract_h( W_shl( real_sum, lshift ) ); + rec_imag_exp[j] = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + abs_fac_powj_32 = Mpy_32_32( abs_fac_powj_32, abs_fac_32 ); + + + real_sum = W_mult_32_32( fac_powj_real_fx, fac_real_fx ); + rat_real_sum_q = add( add( fac_real_q, powj_real_q ), 1 ); + imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_imag_fx ); + rat_imag_sum_q = add( add( fac_imag_q, powj_imag_q ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + // rat_real_sum_q = rat_real_sum_q - 1; + lshift = W_norm( real_sum ); + temp_32 = W_extract_h( W_shl( real_sum, lshift ) ); + temp_16 = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + real_sum = W_mult_32_32( fac_powj_real_fx, fac_imag_fx ); + rat_real_sum_q = fac_imag_q + powj_real_q + 1; + imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_real_fx ); + rat_imag_sum_q = fac_real_q + powj_imag_q + 1; + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + // rat_real_sum_q = rat_real_sum_q - 1; + lshift = W_norm( real_sum ); + fac_powj_imag_fx = W_extract_h( W_shl( real_sum, lshift ) ); + powj_imag_q = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + fac_powj_real_fx = temp_32; + powj_real_q = temp_16; } + /* prepare XF to next frame using prediction */ - fac_powj_real = fac_real; - fac_powj_imag = fac_imag; - abs_fac_powj = abs_fac; - for ( j = 0; j < CLDFB_PLC_XF; j++ ) + fac_powj_real_fx = fac_real_fx; + fac_powj_imag_fx = fac_imag_fx; + powj_real_q = fac_real_q; + powj_imag_q = fac_imag_q; + abs_fac_powj_32 = abs_fac_32; // Q30 + sqrt_exp = 31; +#if CLDFB_PLC_XF > 0 + guard_bits = find_guarded_bits_fx( CLDFB_PLC_XF ); + FOR( j = 0; j < CLDFB_PLC_XF; j++ ) { - xf_bet[j] = 1 - abs_fac_powj; - rec_real[j + iNumCols] = rec_real[iNumCols - 1] * fac_powj_real - rec_imag[iNumCols - 1] * fac_powj_imag; - rec_imag[j + iNumCols] = rec_real[iNumCols - 1] * fac_powj_imag + rec_imag[iNumCols - 1] * fac_powj_real; - abs_fac_powj = abs_fac_powj * abs_fac; - temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; - fac_powj_imag = fac_powj_real * fac_imag + fac_powj_imag * fac_real; - fac_powj_real = temp; + + + xf_bet_fx[j] = L_sub( ONE_IN_Q31, abs_fac_powj_32 ); + real_sum = W_mult_32_32( rec_real_fx[iNumCols - 1], fac_powj_real_fx ); + rat_real_sum_q = add( add( rec_real_exp[iNumCols - 1], powj_real_q ), 1 ); + imag_sum = W_mult_32_32( rec_imag_fx[iNumCols - 1], fac_powj_imag_fx ); + rat_imag_sum_q = add( add( rec_imag_exp[iNumCols - 1], powj_imag_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + rat_real_sum_q = sub( rat_real_sum_q, guard_bits ); + + lshift = W_norm( real_sum ); + rec_real_fx[j + iNumCols] = W_extract_h( W_shl( real_sum, lshift ) ); + rec_real_exp[j + iNumCols] = sub( add( rat_real_sum_q, lshift ), 32 ); + + real_sum = W_mult_32_32( rec_real_fx[iNumCols - 1], fac_powj_imag_fx ); + rat_real_sum_q = add( add( rec_real_exp[iNumCols - 1], powj_imag_q ), 1 ); + imag_sum = W_mult_32_32( rec_imag_fx[iNumCols - 1], fac_powj_real_fx ); + rat_imag_sum_q = add( add( rec_imag_exp[iNumCols - 1], powj_real_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + rat_real_sum_q = sub( rat_real_sum_q, guard_bits ); + + lshift = W_norm( real_sum ); + rec_imag_fx[j + iNumCols] = W_extract_h( W_shl( real_sum, lshift ) ); + rec_imag_exp[j + iNumCols] = sub( add( rat_real_sum_q, lshift ), 32 ); + + abs_fac_powj_32 = W_extract_h( W_mult_32_32( abs_fac_powj_32, abs_fac_32 ) ); // Q31 + + real_sum = W_mult_32_32( fac_powj_real_fx, fac_real_fx ); + rat_real_sum_q = add( add( fac_real_q, powj_real_q ), 1 ); + imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_imag_fx ); + rat_imag_sum_q = add( add( fac_imag_q, powj_imag_q ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + } + real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + lshift = W_norm( real_sum ); + temp_32 = W_extract_h( W_shl( real_sum, lshift ) ); + temp_16 = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + real_sum = W_mult_32_32( fac_powj_real_fx, fac_imag_fx ); + rat_real_sum_q = add( add( fac_imag_q, powj_real_q ), 1 ); + imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_real_fx ); + rat_imag_sum_q = add( add( fac_real_q, powj_imag_q ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + lshift = W_norm( real_sum ); + fac_powj_imag_fx = W_extract_h( W_shl( real_sum, lshift ) ); + powj_imag_q = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + fac_powj_real_fx = temp_32; + powj_real_q = temp_16; } +#endif } } - else + ELSE { - for ( j = 0; j < iNumCols; j++ ) + FOR( j = 0; j < iNumCols; j++ ) { - rec_real[j] = prev_real[j]; - rec_imag[j] = prev_imag[j]; + rec_real_fx[j] = prev_real_fx[j]; + rec_real_exp[j] = exp; + rec_imag_fx[j] = prev_imag_fx[j]; + rec_imag_exp[j] = exp; } - for ( j = 0; j < CLDFB_PLC_XF; j++ ) +#if CLDFB_PLC_XF > 0 + FOR( j = 0; j < CLDFB_PLC_XF; j++ ) { - xf_bet[j] = 1; - rec_real[j + iNumCols] = 0; - rec_imag[j + iNumCols] = 0; + xf_bet_fx[j] = ONE_IN_Q31; + rec_real_fx[j + iNumCols] = 0; + rec_real_exp[j + iNumCols] = 31; + rec_imag_fx[j + iNumCols] = 0; + rec_imag_exp[j + iNumCols] = 31; } +#endif } - return; } - - /*------------------------------------------------------------------------- * Function isar_splitBinRendPLCOpen() * @@ -319,13 +1028,13 @@ static void adaptive_polar_ext_plc( ivas_error isar_splitBinRendPLCOpen( ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, - const int16_t iNumSubSets ) + Word16 iNumSubSets ) { ivas_error error; ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC; error = IVAS_ERR_OK; - if ( ( hSplitRendPLC = (ISAR_SPLIT_REND_PLC_HANDLE) malloc( sizeof( SPLIT_REND_PLC_STRUCT ) ) ) == NULL ) + IF( ( hSplitRendPLC = (ISAR_SPLIT_REND_PLC_HANDLE) malloc( sizeof( SPLIT_REND_PLC_STRUCT ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split renderer PLC Module \n" ) ); } @@ -333,14 +1042,15 @@ ivas_error isar_splitBinRendPLCOpen( hSplitRendPLC->prev_bfi = 0; hSplitRendPLC->bf_count = 0; hSplitRendPLC->iNumSubSets = iNumSubSets; - set_zero( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[0][0][0], 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); - set_zero( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[0][0][0], 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); + + set_l( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[0][0][0], 0, 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); + set_l( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[0][0][0], 0, 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); + *phSplitRendPLC = hSplitRendPLC; return error; } - /*------------------------------------------------------------------------- * Function isar_splitBinRendPLCClose() * @@ -368,21 +1078,21 @@ void isar_splitBinRendPLCClose( void isar_splitBinRendPLCsaveState( ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs, - const int16_t iNumBlocks, - const int16_t iNumIterations ) + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations ) { - int16_t k, n; + Word16 k, n; /* Save Cldfb frame */ - for ( k = 0; k < ( iNumBlocks * iNumIterations ); k++ ) + FOR( k = 0; k < ( iNumBlocks * iNumIterations ); k++ ) { - for ( n = 0; n < num_chs; n++ ) + FOR( n = 0; n < num_chs; n++ ) { - mvr2r( &Cldfb_RealBuffer_Binaural[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][0], CLDFB_NO_CHANNELS_MAX ); - mvr2r( &Cldfb_ImagBuffer_Binaural[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][0], CLDFB_NO_CHANNELS_MAX ); + mvl2l( &Cldfb_RealBuffer_Binaural_fx[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][0], CLDFB_NO_CHANNELS_MAX ); + mvl2l( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][0], CLDFB_NO_CHANNELS_MAX ); } } @@ -396,38 +1106,60 @@ void isar_splitBinRendPLCsaveState( * Cross-fade of preceding bad frame into good frame *------------------------------------------------------------------------*/ -void isar_splitBinRendPLC_xf( +void isar_splitBinRendPLC_xf_fx( ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs, - const int16_t iNumBlocks, - const int16_t iNumIterations, - int32_t **ppiDecodingFailed, - int32_t **ppiDecodingFailedPrev ) + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations, + Word32 **ppiDecodingFailed, + Word32 **ppiDecodingFailedPrev, + Word16 exp ) { - int16_t n, i, k; - + Word16 n, i, k; /* Indicate that next transition will be from a good frame */ hSplitRendPLC->prev_bfi = 0; + move16(); /* Reset bf conter */ hSplitRendPLC->bf_count = 0; - + move16(); /* Do the cross fade */ - for ( n = 0; n < num_chs; n++ ) + FOR( n = 0; n < num_chs; n++ ) { - for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { - int16_t iSubSet = i % hSplitRendPLC->iNumSubSets; - if ( ppiDecodingFailedPrev[n][iSubSet] == 1 && ppiDecodingFailed[n][iSubSet] == 0 ) + Word32 iSubSet = i % hSplitRendPLC->iNumSubSets; + test(); + IF( EQ_32( ppiDecodingFailedPrev[n][iSubSet], 1 ) && EQ_32( ppiDecodingFailed[n][iSubSet], 0 ) ) { - for ( k = 0; k < CLDFB_PLC_XF; k++ ) +#if CLDFB_PLC_XF > 0 + FOR( k = 0; k < CLDFB_PLC_XF; k++ ) { - Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + ( iNumBlocks * iNumIterations )][i]; - Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + ( iNumBlocks * iNumIterations )][i]; + Word32 L_tmp; + Word64 W_tmp; + Word16 shift; + W_tmp = W_shr( W_mult_32_32( hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i][k], Cldfb_RealBuffer_Binaural_fx[n][k][i] ), 1 ); + W_tmp = W_add( W_tmp, W_shl( L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k + ( iNumBlocks * iNumIterations )][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ), 31 ) ); + + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + L_tmp = W_extract_h( W_tmp ); + L_tmp = L_shr( L_tmp, 31 + shift - 32 ); + Cldfb_RealBuffer_Binaural_fx[n][k][i] = L_tmp; + + W_tmp = W_shr( W_mult_32_32( hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i][k], Cldfb_ImagBuffer_Binaural_fx[n][k][i] ), 1 ); + W_tmp = W_add( W_tmp, W_shl( L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k + ( iNumBlocks * iNumIterations )][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ), 31 ) ); + + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + L_tmp = W_extract_h( W_tmp ); + L_tmp = L_shr( L_tmp, 31 + shift - 32 ); + Cldfb_ImagBuffer_Binaural_fx[n][k][i] = L_tmp; } +#endif } } } @@ -441,96 +1173,138 @@ void isar_splitBinRendPLC_xf( * * Conceal bad frame *------------------------------------------------------------------------*/ - void isar_splitBinRendPLC( ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs, - const int16_t iNumBlocks, - const int16_t iNumIterations, - int32_t **ppiDecodingFailed ) + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations, + int32_t **ppiDecodingFailed, + Word16 exp ) { - int32_t i, n, k; - float fade_fac; - float prev_real[CLDFB_NO_COL_MAX], prev_imag[CLDFB_NO_COL_MAX], rec_real[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; - float xf_alp[CLDFB_PLC_XF]; - int16_t iNumCols, fade_start_cntr, mute_cntr, fade_val; + Word32 i, n, k; + Word32 temp_32, fade_fac_fx; + Word16 div_exp = 0, tmp, exp_fade, frac; + Word32 prev_real_fx[CLDFB_NO_COL_MAX], prev_imag_fx[CLDFB_NO_COL_MAX], rec_real_fx[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag_fx[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; + Word16 rec_real_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; +#if CLDFB_PLC_XF > 0 + Word32 xf_alp_fx[CLDFB_PLC_XF]; +#endif + Word16 iNumCols, fade_start_cntr, mute_cntr, fade_val; - iNumCols = iNumBlocks * iNumIterations; + iNumCols = extract_l( L_mult0( iNumBlocks, iNumIterations ) ); /* Indicate that next transition will be from a bad frame */ hSplitRendPLC->prev_bfi = 1; - for ( i = 0; i < CLDFB_PLC_XF; i++ ) + +#if CLDFB_PLC_XF > 0 + FOR( i = 0; i < CLDFB_PLC_XF; i++ ) { - xf_alp[i] = 1.0f - ( i + 1.0f ) / ( CLDFB_PLC_XF + 1.0f ); + xf_alp_fx[i] = xf_alp_tab[i]; } +#endif + Word16 exp1 = exp; - for ( n = 0; n < num_chs; n++ ) + FOR( n = 0; n < num_chs; n++ ) { - for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { - int32_t iSubSet = i % hSplitRendPLC->iNumSubSets; - for ( k = 0; k < iNumCols; k++ ) + Word32 iSubSet = i % hSplitRendPLC->iNumSubSets; + FOR( k = 0; k < iNumCols; k++ ) { - prev_real[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i]; - prev_imag[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i]; + prev_real_fx[k] = L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ); + prev_imag_fx[k] = L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ); } + adaptive_polar_ext_plc_fx( + prev_real_fx, prev_imag_fx, rec_real_fx, rec_imag_fx, + rec_real_exp, rec_imag_exp +#if CLDFB_PLC_XF > 0 + , + xf_alp_fx, hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i], +#endif + exp, + iNumCols ); - adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag, - xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i], - iNumCols ); + Word16 temp16; - for ( k = 0; k < iNumCols; k++ ) + FOR( k = 0; k < iNumCols; k++ ) { - hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; - hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; - + temp16 = sub( rec_real_exp[k], exp1 ); + rec_real_fx[k] = L_shr_r_sat( rec_real_fx[k], temp16 ); + rec_real_exp[k] = sub( rec_real_exp[k], temp16 ); + + temp16 = sub( rec_imag_exp[k], exp1 ); + rec_imag_fx[k] = L_shr_r_sat( rec_imag_fx[k], temp16 ); + rec_imag_exp[k] = sub( rec_imag_exp[k], temp16 ); + // Cldfb_RealBuffer_Binaural_fx[n][k][i] = rec_real_fx[k]; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i] = rec_real_fx[k]; // exp + // Cldfb_ImagBuffer_Binaural_fx[n][k][i] = rec_imag_fx[k] ; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i] = rec_imag_fx[k]; // exp if ( ppiDecodingFailed[n][iSubSet] == 1 ) { /* only then copy to output */ - Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k]; - Cldfb_ImagBuffer_Binaural[n][k][i] = rec_imag[k]; + Cldfb_RealBuffer_Binaural_fx[n][k][i] = rec_real_fx[k]; + Cldfb_ImagBuffer_Binaural_fx[n][k][i] = rec_imag_fx[k]; } } - for ( k = iNumCols; k < iNumCols + CLDFB_PLC_XF; k++ ) +#if CLDFB_PLC_XF > 0 + FOR( k = iNumCols; k < iNumCols + CLDFB_PLC_XF; k++ ) { - hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; - hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; + + temp16 = sub( rec_real_exp[k], exp1 ); + rec_real_fx[k] = L_shr_r_sat( rec_real_fx[k], temp16 ); + rec_real_exp[k] = sub( rec_real_exp[k], temp16 ); + + temp16 = sub( rec_imag_exp[k], exp1 ); + rec_imag_fx[k] = L_shr_r_sat( rec_imag_fx[k], temp16 ); + rec_imag_exp[k] = sub( rec_imag_exp[k], temp16 ); + /*TODO: Will remove the inter conversion later*/ + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i] = rec_real_fx[k]; // exp + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i] = rec_imag_fx[k]; // exp } +#endif } } /* Check bf counter */ - fade_start_cntr = SR_PLC_FADE_START * CLDFB_NO_COL_MAX / iNumCols; - mute_cntr = SR_PLC_MUTE * CLDFB_NO_COL_MAX / iNumCols; + tmp = BASOP_Util_Divide1616_Scale( PLC_FADE_CNST, iNumCols, &div_exp ); + fade_start_cntr = shr( tmp, ( 15 - div_exp ) ); + tmp = BASOP_Util_Divide1616_Scale( PLC_MUTE_CNST, iNumCols, &div_exp ); + mute_cntr = shr( tmp, ( 15 - div_exp ) ); - if ( hSplitRendPLC->bf_count++ >= fade_start_cntr ) + IF( GE_16( hSplitRendPLC->bf_count++, fade_start_cntr ) ) { - if ( hSplitRendPLC->bf_count < mute_cntr ) + IF( LT_16( hSplitRendPLC->bf_count, mute_cntr ) ) { - fade_val = ( ( hSplitRendPLC->bf_count - fade_start_cntr ) * iNumCols ) / CLDFB_NO_COL_MAX; - fade_fac = powf( 10, fade_val * SR_PLC_FADE_DEGREE / 20.0f ); + fade_val = extract_l( L_shr( L_mult0( sub( hSplitRendPLC->bf_count, fade_start_cntr ), iNumCols ), 4 ) ); // Q0 + temp_32 = L_mult( -16328, fade_val ); // Q15 + temp_32 = L_shl( temp_32, 1 ); // Q16 + + frac = L_Extract_lc( temp_32, &exp_fade ); /* Extract exponent of temp_32 */ + fade_fac_fx = Pow2( 14, frac ); /* Put 14 as exponent so that */ + exp_fade = 31 - add( sub( exp_fade, 14 ), 16 ); + fade_fac_fx = L_shl( fade_fac_fx, 31 - exp_fade ); // Q31 - for ( n = 0; n < num_chs; n++ ) + FOR( n = 0; n < num_chs; n++ ) { - for ( k = 0; k < iNumCols; k++ ) + FOR( k = 0; k < iNumCols; k++ ) { - v_multc( &Cldfb_RealBuffer_Binaural[n][k][0], fade_fac, &Cldfb_RealBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); - v_multc( &Cldfb_ImagBuffer_Binaural[n][k][0], fade_fac, &Cldfb_ImagBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + v_multc_fixed( &Cldfb_RealBuffer_Binaural_fx[n][k][0], fade_fac_fx, &Cldfb_RealBuffer_Binaural_fx[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + v_multc_fixed( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], fade_fac_fx, &Cldfb_ImagBuffer_Binaural_fx[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); } } } - else + ELSE { - for ( n = 0; n < num_chs; n++ ) + FOR( n = 0; n < num_chs; n++ ) { - for ( k = 0; k < iNumCols; k++ ) + FOR( k = 0; k < iNumCols; k++ ) { - set_zero( &Cldfb_RealBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); - set_zero( &Cldfb_ImagBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + set_val_Word32( &Cldfb_RealBuffer_Binaural_fx[n][k][0], 0, (int16_t) CLDFB_NO_CHANNELS_MAX ); + set_val_Word32( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], 0, (int16_t) CLDFB_NO_CHANNELS_MAX ); } } hSplitRendPLC->bf_count = mute_cntr; @@ -539,5 +1313,4 @@ void isar_splitBinRendPLC( return; } - #endif diff --git a/lib_isar/isar_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c index c4d7a20d3..1bbff0b5c 100644 --- a/lib_isar/isar_splitRendererPost.c +++ b/lib_isar/isar_splitRendererPost.c @@ -44,18 +44,10 @@ #ifdef DEBUGGING #include "debug.h" #endif +#include "prot_fx2.h" #include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local function declarations - *---------------------------------------------------------------------*/ - -static void isar_SplitRenderer_PostRenderer( - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_RealBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ - float Cldfb_ImagBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ - const IVAS_QUATERNION Quaternion_act ); +#include "basop_util.h" +#define Q31_BY_360 ( 5965232 ) // Q31 /*------------------------------------------------------------------------- @@ -63,22 +55,21 @@ static void isar_SplitRenderer_PostRenderer( * * *------------------------------------------------------------------------*/ - ivas_error isar_splitBinPostRendOpen( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int32_t output_Fs ) + const Word32 output_Fs ) { ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; ivas_error error; - int16_t ch; + Word16 ch; - if ( ( hBinRend = (ISAR_BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_POST_REND ) ) ) == NULL ) + IF( ( hBinRend = (ISAR_BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_POST_REND ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split post renderer Module \n" ) ); } - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { hBinRend->cldfbSyn[ch] = NULL; hBinRend->cldfbAna[ch] = NULL; @@ -93,13 +84,13 @@ ivas_error isar_splitBinPostRendOpen( } #endif - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - if ( ( error = openCldfb( &( hBinRend->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_splitRend( &( hBinRend->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = openCldfb( &( hBinRend->cldfbAna[ch] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_splitRend( &( hBinRend->cldfbAna[ch] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -118,15 +109,14 @@ ivas_error isar_splitBinPostRendOpen( } #endif hBinRend->cf_flag = 0; - set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); - set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); + set_fix_rotation_mat_fx( hBinRend->fix_pos_rot_mat_fx, pMultiBinPoseData ); + set_pose_types_fx( hBinRend->pose_type, pMultiBinPoseData ); isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); *hBinHrSplitPostRend = hBinRend; return IVAS_ERR_OK; } - /*------------------------------------------------------------------------- * isar_splitBinPostRendClose() * @@ -136,20 +126,20 @@ ivas_error isar_splitBinPostRendOpen( void isar_splitBinPostRendClose( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ) { - int16_t ch; + Word16 ch; - if ( ( *hBinHrSplitPostRend ) != NULL ) + IF( ( *hBinHrSplitPostRend ) != NULL ) { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - if ( ( *hBinHrSplitPostRend )->cldfbSyn[ch] != NULL ) + IF( ( *hBinHrSplitPostRend )->cldfbSyn[ch] != NULL ) { - deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSyn[ch] ) ); + deleteCldfb_splitRend( &( ( *hBinHrSplitPostRend )->cldfbSyn[ch] ) ); ( *hBinHrSplitPostRend )->cldfbSyn[ch] = NULL; } - if ( ( *hBinHrSplitPostRend )->cldfbAna[ch] != NULL ) + IF( ( *hBinHrSplitPostRend )->cldfbAna[ch] != NULL ) { - deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbAna[ch] ) ); + deleteCldfb_splitRend( &( ( *hBinHrSplitPostRend )->cldfbAna[ch] ) ); ( *hBinHrSplitPostRend )->cldfbAna[ch] = NULL; } } @@ -174,151 +164,169 @@ void isar_splitBinPostRendClose( return; } - /*-----------------------------------------------------------------------------------------* - * Function isar_split_rend_huffman_decode_opt() + * Function ivas_split_rend_huffman_decode_opt() * * *-----------------------------------------------------------------------------------------*/ -static int16_t isar_split_rend_huffman_decode_opt( +static Word16 ivas_split_rend_huffman_decode_opt( isar_split_rend_huffman_cfg_t *huff_cfg, ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int16_t *idx_trav_list ) + const Word16 *idx_trav_list ) { - int32_t i, ind, code, num_bits, code_b, num_bits_read; - const int32_t *codebook; + Word32 i, ind, code, num_bits, code_b, num_bits_read; + const Word32 *codebook; codebook = huff_cfg->codebook; num_bits_read = 0; - ind = huff_cfg->codebook[0] - 1; + move32(); + ind = L_sub( huff_cfg->codebook[0], 1 ); code = 0; - for ( i = 0; i < huff_cfg->sym_len; i++ ) + move32(); + FOR( i = 0; i < huff_cfg->sym_len; i++ ) { codebook = codebook + idx_trav_list[i] * 3; num_bits = codebook[1]; + move32(); code_b = codebook[2]; - num_bits_read = num_bits - num_bits_read; - code = code << num_bits_read; - if ( num_bits_read > 0 ) + move32(); + num_bits_read = L_sub( num_bits, num_bits_read ); + code = L_shl( code, extract_l( num_bits_read ) ); + IF( GT_32( num_bits_read, 0 ) ) { - code |= ISAR_SPLIT_REND_BITStream_read_int32( pBits, num_bits_read ); + code = L_or( code, ISAR_SPLIT_REND_BITStream_read_int32( pBits, num_bits_read ) ); } - if ( code == code_b ) + IF( EQ_32( code, code_b ) ) { ind = codebook[0]; - break; + move32(); + BREAK; } num_bits_read = num_bits; + move32(); codebook = huff_cfg->codebook; } #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG assert( ind >= huff_cfg->codebook[0] ); #endif - return (int16_t) ind; + return extract_l( ind ); } /*-----------------------------------------------------------------------------------------* - * Function isar_split_rend_unquant_md() + * Function ivas_split_rend_unquant_md() * * *-----------------------------------------------------------------------------------------*/ -static void isar_split_rend_unquant_md( +static void ivas_split_rend_unquant_md_fx( ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, ISAR_SPLIT_REND_POSE_TYPE pose_type, - const int16_t real_only, - float fix_pos_rot_mat[][BINAURAL_CHANNELS], - const float pred_quant_step ) + Word16 real_only, + Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS], + const Word32 pred_quant_step ) { - int16_t ch1, ch2; - int16_t gd_idx_min; + Word16 ch1, ch2; + Word16 gd_idx_min; - if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) + test(); + IF( EQ_32( pose_type, PRED_ONLY ) || EQ_32( pose_type, PRED_ROLL_ONLY ) ) { - float quantstep; + Word32 quantstep; quantstep = pred_quant_step; + move32(); #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep; - hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2]; + hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */ + move32(); + hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( fix_pos_rot_mat[ch1][ch2], Q6 ) ); /* Q25 */ + move32(); } } #endif - if ( real_only ) + + IF( real_only ) { #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep; - hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + ( ( ch1 == ch2 ) ? 1.0f : 0.0f ); + hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */ + move32(); + hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( ( ch1 == ch2 ) ? ONE_IN_Q31 : 0, Q6 ) ); /* Q25 */ + move32(); } } #endif - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - hMd->pred_mat_im[ch1][ch2] = 0.0f; + hMd->pred_mat_im_fx[ch1][ch2] = 0; /* Q25 */ + move32(); } } } - else + ELSE { #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep; - hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2]; + hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */ + move32(); + hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( fix_pos_rot_mat[ch1][ch2], Q6 ) ); /* Q25 */ + move32(); } } #endif - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * quantstep; + hMd->pred_mat_im_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_im_idx[ch1][ch2], Q9 ) ) ); /* Q25 */ + move32(); } } } } - else if ( pose_type == COM_GAIN_ONLY ) + ELSE IF( EQ_32( pose_type, COM_GAIN_ONLY ) ) { - gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL ); - hMd->gd_idx += gd_idx_min; - hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_D_Q_STEP; + gd_idx_min = 0; + move16(); + hMd->gd_idx = add( hMd->gd_idx, gd_idx_min ); + hMd->gd_fx = Mpy_32_16_1( ISAR_SPLIT_REND_D_Q_STEP_Q31, extract_l( L_shl( hMd->gd_idx, Q9 ) ) ); /* Q25 */ } - else if ( pose_type == LR_GAIN_ONLY ) + ELSE IF( EQ_32( pose_type, LR_GAIN_ONLY ) ) { - gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PITCH_G_MIN_VAL ); - hMd->gd_idx += gd_idx_min; - hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_PITCH_G_Q_STEP; + gd_idx_min = 7; + move16(); + hMd->gd_idx = add( hMd->gd_idx, gd_idx_min ); + hMd->gd_fx = Mpy_32_16_1( ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31, extract_l( L_shl( hMd->gd_idx, Q9 ) ) ); /* Q25 */ - hMd->gd2_idx += gd_idx_min; - hMd->gd2 = hMd->gd2_idx * ISAR_SPLIT_REND_PITCH_G_Q_STEP; + hMd->gd2_idx = add( hMd->gd2_idx, gd_idx_min ); + hMd->gd2_fx = Mpy_32_16_1( ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31, extract_l( L_shl( hMd->gd2_idx, Q9 ) ) ); /* Q25 */ } - else + ELSE { - hMd->gd = 0.0f; + hMd->gd_fx = 0; /* Q25 */ + move32(); } return; } - /*-----------------------------------------------------------------------------------------* * Function isar_splitBinPostRendMdBase2Dec() * @@ -329,184 +337,207 @@ static void isar_splitBinPostRendMdBase2Dec( ISAR_SPLIT_REND_BITS_HANDLE pBits, ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int16_t num_subframes, - const int16_t pred_real_bands_yaw, - const int16_t pred_imag_bands_yaw, - const int16_t pred_quant_pnts_yaw, - const int16_t d_bands_yaw, - const int16_t bands_pitch, - const int16_t pred_real_bands_roll, - const int16_t pred_imag_bands_roll ) + const Word16 num_subframes, + const Word16 pred_real_bands_yaw, + const Word16 pred_imag_bands_yaw, + const Word16 pred_quant_pnts_yaw, + const Word16 d_bands_yaw, + const Word16 bands_pitch, + const Word16 pred_real_bands_roll, + const Word16 pred_imag_bands_roll ) { - int16_t sf_idx, pos_idx, b, ch1, ch2; - int16_t min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len; - int16_t min_pred_roll_idx, pred_roll_code_len; - int16_t pred_cb_idx; - int16_t code; + Word16 sf_idx, pos_idx, b, ch1, ch2; + Word16 min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len; + Word16 min_pred_roll_idx, pred_roll_code_len; + Word16 pred_cb_idx; + Word16 code; ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; - if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) + IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) ) { pred_cb_idx = 1; + move16(); } - else + ELSE { pred_cb_idx = 0; + move16(); } - min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0]; - min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0]; - min_gd_idx = (int16_t) pHuff_cfg->gd.codebook[0]; - min_p_gd_idx = (int16_t) pHuff_cfg->p_gd.codebook[0]; + min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] ); + min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] ); + min_gd_idx = extract_l( pHuff_cfg->gd.codebook[0] ); + min_p_gd_idx = extract_l( pHuff_cfg->p_gd.codebook[0] ); pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; + move16(); pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; + move16(); gd_code_len = pHuff_cfg->gd_base2_code_len; + move16(); p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + move16(); - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ ) { - if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) ) { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( b = 0; b < pred_real_bands_yaw; b++ ) + FOR( b = 0; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); - hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_idx ); + move16(); } } } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); - hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_idx ); + move16(); } } } #else - for ( b = 0; b < pred_imag_bands_yaw; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); - hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_idx ); + move16(); } } - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); - hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_idx ); + move16(); } } } - - for ( ; b < pred_real_bands_yaw; b++ ) + FOR( ; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); - hMd->pred_mat_re_idx[ch1][ch1] = code + min_pred_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch1] = add( code, min_pred_idx ); + move16(); } hMd->pred_mat_re_idx[0][1] = 0; + move16(); hMd->pred_mat_re_idx[1][0] = 0; + move16(); } #endif - for ( b = 0; b < d_bands_yaw; b++ ) + FOR( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, gd_code_len ); - hMd->gd_idx = code + min_gd_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, gd_code_len ) ); + hMd->gd_idx = add( code, min_gd_idx ); + move16(); } } - else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + ELSE IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], PITCH_ONLY ) ) { - for ( b = 0; b < bands_pitch; b++ ) + FOR( b = 0; b < bands_pitch; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ); - hMd->gd_idx = code + min_p_gd_idx; - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ); - hMd->gd2_idx = code + min_p_gd_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ) ); + hMd->gd_idx = add( code, min_p_gd_idx ); + move16(); + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ) ); + hMd->gd2_idx = add( code, min_p_gd_idx ); + move16(); } } - else + ELSE { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( b = 0; b < pred_real_bands_roll; b++ ) + FOR( b = 0; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); - hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_roll_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_roll_idx ); + move16(); } } } - for ( b = 0; b < pred_imag_bands_roll; b++ ) + FOR( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); - hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_roll_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_roll_idx ); + move16(); } } } #else - for ( b = 0; b < pred_imag_bands_roll; b++ ) + FOR( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); - hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_roll_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_roll_idx ); + move16(); } } - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); - hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_roll_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_roll_idx ); + move16(); } } } - - for ( ; b < pred_real_bands_roll; b++ ) + FOR( ; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); - hMd->pred_mat_re_idx[ch1][ch1] = code + min_pred_roll_idx; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch1] = add( code, min_pred_roll_idx ); + move16(); } hMd->pred_mat_re_idx[0][1] = 0; + move16(); hMd->pred_mat_re_idx[1][0] = 0; + move16(); } #endif } @@ -518,189 +549,215 @@ static void isar_splitBinPostRendMdBase2Dec( /*-----------------------------------------------------------------------------------------* - * Function isar_splitBinPostRendMdHuffDec() + * Function ivas_splitBinPostRendMdHuffDec() * * *-----------------------------------------------------------------------------------------*/ -static void isar_splitBinPostRendMdHuffDec( +static void ivas_splitBinPostRendMdHuffDec( ISAR_SPLIT_REND_BITS_HANDLE pBits, ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int16_t num_subframes, - const int16_t pred_real_bands_yaw, - const int16_t pred_imag_bands_yaw, - const int16_t pred_quant_pnts_yaw, - const int16_t d_bands_yaw, - const int16_t bands_pitch, - const int16_t pred_real_bands_roll, - const int16_t pred_imag_bands_roll ) + const Word16 num_subframes, + const Word16 pred_real_bands_yaw, + const Word16 pred_imag_bands_yaw, + const Word16 pred_quant_pnts_yaw, + const Word16 d_bands_yaw, + const Word16 bands_pitch, + const Word16 pred_real_bands_roll, + const Word16 pred_imag_bands_roll ) { - int16_t pos_idx, b, sf_idx; - int16_t ch1, ch2; - int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - int16_t min_pred_idx, max_pred_idx; - int16_t min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx; + Word16 pos_idx, b, sf_idx; + Word16 ch1, ch2; + Word16 sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 min_pred_idx, max_pred_idx; + Word16 min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx; ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; - if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) + IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) ) { pred_cb_idx = 1; + move16(); } - else + ELSE { pred_cb_idx = 0; + move16(); } - min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0]; - max_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3]; + min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] ); + max_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3] ); - min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0]; - max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; + min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] ); + max_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3] ); - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ ) { - if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) ) { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( b = 0; b < pred_real_bands_yaw; b++ ) + FOR( b = 0; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); } } isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); } } isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); } #else - for ( b = 0; b < pred_imag_bands_yaw; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); } } isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); } } isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); } - for ( ; b < pred_real_bands_yaw; b++ ) + FOR( ; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - sym_adj_idx[ch1][ch1] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + sym_adj_idx[ch1][ch1] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); } sym_adj_idx[1][0] = 0; + move16(); sym_adj_idx[0][1] = 0; + move16(); isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_idx, max_pred_idx ); } #endif - for ( b = 0; b < d_bands_yaw; b++ ) + FOR( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - hMd->gd_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav ); + hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav ); + // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits ); } } - else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + ELSE IF( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) { - for ( b = 0; b < bands_pitch; b++ ) + FOR( b = 0; b < bands_pitch; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - hMd->gd_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits ); - hMd->gd2_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + hMd->gd2_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); } } - else + ELSE { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( b = 0; b < pred_real_bands_roll; b++ ) + FOR( b = 0; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); } } isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); } - for ( b = 0; b < pred_imag_bands_roll; b++ ) + FOR( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); } } isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); } #else - for ( b = 0; b < pred_imag_bands_roll; b++ ) + FOR( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); } } isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); } } isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); } - - for ( ; b < pred_real_bands_roll; b++ ) + FOR( ; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - sym_adj_idx[ch1][ch1] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + sym_adj_idx[ch1][ch1] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); } sym_adj_idx[1][0] = 0; + move16(); sym_adj_idx[0][1] = 0; + move16(); isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); } #endif @@ -718,7 +775,7 @@ static void isar_splitBinPostRendMdHuffDec( * *-----------------------------------------------------------------------------------------*/ -void isar_splitBinPostRendMdDec( +void isar_splitBinPostRendMdDec_fx( ISAR_SPLIT_REND_BITS_HANDLE pBits, ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData @@ -728,33 +785,34 @@ void isar_splitBinPostRendMdDec( #endif ) { - int16_t pos_idx, b, sf_idx, num_subframes, ch1; - int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 pos_idx, b, sf_idx, num_subframes, ch1; + Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - int16_t num_quant_strats; + Word16 num_quant_strats; #else - int16_t num_complex_bands, num_quant_strats; + Word16 num_complex_bands, num_quant_strats; #endif - int32_t quant_strat_bits, is_huff_coding, quant_strat; - int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 quant_strat_bits, is_huff_coding, quant_strat; + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 pred_1byquantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; // Q26 + Word32 pred_quantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; // Q31 #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - int16_t ch1, ch2; + Word16 ch1, ch2; #endif ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; ISAR_SPLIT_REND_CONFIG_DATA split_rend_config; ISAR_SPLIT_REND_ROT_AXIS rot_axis; #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - int16_t ro_md_flag, num_bits, axis_code; + Word16 ro_md_flag, num_bits, axis_code; #endif hBinHrSplitPostRend->low_Res = 1; + move16(); - split_rend_config.dof = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_DOF_BITS ); - split_rend_config.hq_mode = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HQ_MODE_BITS ); + split_rend_config.dof = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_DOF_BITS ) ); + split_rend_config.hq_mode = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HQ_MODE_BITS ) ); #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS num_bits = isar_renderSplitGetRot_axisNumBits( split_rend_config.dof ); @@ -771,40 +829,44 @@ void isar_splitBinPostRendMdDec( #else rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_ROT_AXIS_BITS ); #endif + isar_renderSplitGetMultiBinPoseData_fx( &split_rend_config, pMultiBinPoseData, rot_axis ); - isar_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis ); - - set_fix_rotation_mat( hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); - set_pose_types( hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); + set_fix_rotation_mat_fx( hBinHrSplitPostRend->fix_pos_rot_mat_fx, pMultiBinPoseData ); + set_pose_types_fx( hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); - num_subframes = ( hBinHrSplitPostRend->low_Res == 0 ) ? MAX_PARAM_SPATIAL_SUBFRAMES : 1; - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + num_subframes = EQ_16( hBinHrSplitPostRend->low_Res, 0 ) ? MAX_PARAM_SPATIAL_SUBFRAMES : 1; + move16(); + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - int16_t angle; + Word16 angle; - hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; + hBinHrSplitPostRend->QuaternionsPre[sf_idx].w_fx = -12582912; /* -3.0f in Q22 */ + move32(); - angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ); - angle -= 180; - hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = (float) angle; + angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) ); + angle = sub( angle, 180 ); + hBinHrSplitPostRend->QuaternionsPre[sf_idx].x_fx = L_shl( angle, Q22 ); /* Q22 */ + move32(); - angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ); - angle -= 180; - hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = (float) angle; + angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) ); + angle = sub( angle, 180 ); + hBinHrSplitPostRend->QuaternionsPre[sf_idx].y_fx = L_shl( angle, Q22 ); /* Q22 */ + move32(); - angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ); - angle -= 180; - hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = (float) angle; + angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) ); + angle = sub( angle, 180 ); + hBinHrSplitPostRend->QuaternionsPre[sf_idx].z_fx = L_shl( angle, Q22 ); /* Q22 */ + move32(); } #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - isar_split_rend_get_quant_params( + isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, pred_quant_pnts_yaw, - pred_quantstep_yaw, - pred_1byquantstep_yaw, + pred_quantstep_yaw_fx, + pred_1byquantstep_yaw_fx, d_bands_yaw, bands_pitch, pred_real_bands_roll, @@ -812,13 +874,13 @@ void isar_splitBinPostRendMdDec( ro_md_flag, &num_quant_strats ); #else - isar_split_rend_get_quant_params( + isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, pred_quant_pnts_yaw, - pred_quantstep_yaw, - pred_1byquantstep_yaw, + pred_quantstep_yaw_fx, + pred_1byquantstep_yaw_fx, d_bands_yaw, bands_pitch, pred_real_bands_roll, @@ -826,12 +888,11 @@ void isar_splitBinPostRendMdDec( &num_quant_strats, &num_complex_bands ); #endif - - quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); + quant_strat_bits = L_deposit_l( ceil_log_2( num_quant_strats ) ); is_huff_coding = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); quant_strat = ISAR_SPLIT_REND_BITStream_read_int32( pBits, quant_strat_bits ); - if ( is_huff_coding == 0 ) + IF( EQ_32( is_huff_coding, 0 ) ) { isar_splitBinPostRendMdBase2Dec( pBits, hBinHrSplitPostRend, @@ -845,9 +906,9 @@ void isar_splitBinPostRendMdDec( pred_real_bands_roll[quant_strat], pred_imag_bands_roll[quant_strat] ); } - else + ELSE { - isar_splitBinPostRendMdHuffDec( + ivas_splitBinPostRendMdHuffDec( pBits, hBinHrSplitPostRend, pMultiBinPoseData, num_subframes, @@ -963,83 +1024,87 @@ void isar_splitBinPostRendMdDec( } #endif - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ ) { - if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) ) { - for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_unquant_md( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); + ivas_split_rend_unquant_md_fx( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], pred_quantstep_yaw_fx[quant_strat] ); } - for ( ; b < pred_real_bands_yaw[quant_strat]; b++ ) + FOR( ; b < pred_real_bands_yaw[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_unquant_md( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); + ivas_split_rend_unquant_md_fx( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], pred_quantstep_yaw_fx[quant_strat] ); } - for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - set_zero( hMd->pred_mat_re[ch1], BINAURAL_CHANNELS ); - set_zero( hMd->pred_mat_im[ch1], BINAURAL_CHANNELS ); - hMd->pred_mat_re[ch1][ch1] = 1.0f; + set32_fx( hMd->pred_mat_re_fx[ch1], 0, BINAURAL_CHANNELS ); + set32_fx( hMd->pred_mat_im_fx[ch1], 0, BINAURAL_CHANNELS ); + hMd->pred_mat_re_fx[ch1][ch1] = L_shl( 1, Q25 ); /* 1.0f in Q25 */ + move32(); } } - for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + FOR( b = 0; b < d_bands_yaw[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_unquant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); + ivas_split_rend_unquant_md_fx( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], 0 ); } - for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - hMd->gd = 0.0f; + hMd->gd_fx = 0; + move32(); } } - else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + ELSE IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], PITCH_ONLY ) ) { - for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + FOR( b = 0; b < bands_pitch[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_unquant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); + ivas_split_rend_unquant_md_fx( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], 0 ); } - for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - hMd->gd = 1.0f; - hMd->gd2 = 1.0f; + hMd->gd_fx = L_shl( 1, Q25 ); /* 1.0f in Q25 */ + move32(); + hMd->gd2_fx = L_shl( 1, Q25 ); /* 1.0f in Q25 */ + move32(); } } - else + ELSE { - for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + FOR( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ); + ivas_split_rend_unquant_md_fx( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 ); } - for ( ; b < pred_real_bands_roll[quant_strat]; b++ ) + FOR( ; b < pred_real_bands_roll[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ); + ivas_split_rend_unquant_md_fx( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 ); } - for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - set_zero( hMd->pred_mat_re[ch1], BINAURAL_CHANNELS ); - set_zero( hMd->pred_mat_im[ch1], BINAURAL_CHANNELS ); - hMd->pred_mat_re[ch1][ch1] = 1.0f; + set32_fx( hMd->pred_mat_re_fx[ch1], 0, BINAURAL_CHANNELS ); + set32_fx( hMd->pred_mat_im_fx[ch1], 0, BINAURAL_CHANNELS ); + hMd->pred_mat_re_fx[ch1][ch1] = L_shl( 1, Q25 ); /* 1.0f in Q25 */ + move32(); } } } } } - #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { @@ -1139,135 +1204,134 @@ void isar_splitBinPostRendMdDec( return; } - /*-----------------------------------------------------------------------------------------* * Function wrap_around_angle() * * *-----------------------------------------------------------------------------------------*/ - -static void wrap_around_angle( - float *a ) +static void wrap_around_angle_fx( + Word32 *a_fx ) { - if ( ( *a ) > 180.0f ) + IF( GT_32( ( *a_fx ), 754974720 /*180.f in Q22*/ ) ) { - ( *a ) = ( *a ) - 360; + *a_fx = L_sub( ( *a_fx ), 1509949440 /*360.f in Q22*/ ); } - else if ( ( *a ) < -180.0f ) + ELSE IF( LT_32( ( *a_fx ), L_negate( 754974720 /*180.f in Q22*/ ) ) ) { - ( *a ) = ( *a ) + 360; + *a_fx = L_add( *a_fx, 1509949440 /*360.f in Q22*/ ); } return; } - /*-----------------------------------------------------------------------------------------* * Function wrap_around_angle() * * *-----------------------------------------------------------------------------------------*/ - -static void wrap_around_ypr( +static void wrap_around_ypr_fx( IVAS_QUATERNION *Quaternions ) { /*only if quat is actually yaw, pitch , roll angles*/ - if ( Quaternions->w == -3.0f ) + IF( EQ_32( Quaternions->w_fx, L_negate( 12582912 /*3.0f in Q22*/ ) ) ) { - wrap_around_angle( &Quaternions->x ); - wrap_around_angle( &Quaternions->y ); - wrap_around_angle( &Quaternions->z ); + wrap_around_angle_fx( &Quaternions->x_fx ); + wrap_around_angle_fx( &Quaternions->y_fx ); + wrap_around_angle_fx( &Quaternions->z_fx ); } return; } - /*-----------------------------------------------------------------------------------------* * Function wrap_around_angle() * * *-----------------------------------------------------------------------------------------*/ - -static float get_interp_fact( - float p[MAX_HEAD_ROT_POSES], - const float p_t, - const int16_t ind[2] ) +static Word32 get_interp_fact_fx( + Word32 p_fx[MAX_HEAD_ROT_POSES], + const Word32 p_t_fx, + const Word16 ind[2], + Word16 *exp ) { - float n, d, interp_fact; - - if ( ind[0] != ind[1] ) + Word32 n_fx, d_fx, interp_fact_fx; + *exp = 31; + move16(); + IF( NE_16( ind[0], ind[1] ) ) { - n = p[ind[0]] - p[ind[1]]; - d = p[ind[0]] - p_t; - interp_fact = d / n; - if ( interp_fact < 0.0f ) + n_fx = L_sub( p_fx[ind[0]], p_fx[ind[1]] ); + move32(); + d_fx = L_sub( p_fx[ind[0]], p_t_fx ); + move32(); + interp_fact_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( d_fx, n_fx, exp ) ); // Q31-exp + move32(); + IF( LT_32( interp_fact_fx, 0 ) ) { - d = max( -1.0f * MAX_EXTRAPOLATION_ANGLE, ( min( MAX_EXTRAPOLATION_ANGLE, d ) ) ); - n = sinf( n * ( EVS_PI / 180.0f ) ); - d = sinf( d * ( EVS_PI / 180.0f ) ); - interp_fact = d / n; + d_fx = max( -( MAX_EXTRAPOLATION_ANGLE_Q22 ), ( min( ( MAX_EXTRAPOLATION_ANGLE_Q22 ), d_fx ) ) ); + move32(); + n_fx = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_32( n_fx, Q31_BY_360 ), 7 ) ) ) ); + move32(); + d_fx = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_32( d_fx, Q31_BY_360 ), 7 ) ) ) ); + move32(); + interp_fact_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( d_fx, n_fx, exp ) ); // Q31-exp + move32(); } } - else + ELSE { - interp_fact = 0.0f; + interp_fact_fx = 0; + move32(); } - - return interp_fact; + return interp_fact_fx; } - /*-----------------------------------------------------------------------------------------* * Function get_nearest_pose_ind() * * *-----------------------------------------------------------------------------------------*/ - -static void get_nearest_pose_ind( - float p[MAX_HEAD_ROT_POSES], - const float p_t, - int16_t ind[2], - const int16_t num_poses ) +static void get_nearest_pose_ind_fx( + Word32 p[MAX_HEAD_ROT_POSES], + const Word32 p_t, + Word16 ind[2], + const Word16 num_poses ) { - float min_diff, diff; - int16_t pos_idx; + Word32 min_diff, diff; + Word16 pos_idx; ind[0] = 0; ind[1] = 0; - min_diff = 360.0f; + min_diff = 1509949440; // 360 in Q22 /*find the closest pose from assumed poses*/ - for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { - diff = fabsf( p_t - p[pos_idx] ); - if ( diff < min_diff ) + diff = L_abs( L_sub( p_t, p[pos_idx] ) ); + IF( LT_32( diff, min_diff ) ) { ind[0] = pos_idx; - min_diff = (float) diff; + min_diff = diff; } } - min_diff = 360.0; - for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + min_diff = 1509949440; // 360 in Q22 + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { - diff = fabsf( p_t - p[pos_idx] ); - if ( ( diff < min_diff ) && - ( fabs( p[pos_idx] - p[ind[0]] ) > EPSILON ) ) + diff = L_abs( L_sub( p_t, p[pos_idx] ) ); + IF( LT_32( diff, min_diff ) && + GT_32( L_abs( L_sub( p[pos_idx], p[ind[0]] ) ), EPSILON_FX ) ) { ind[1] = pos_idx; - min_diff = (float) diff; + min_diff = diff; } } return; } - /*-----------------------------------------------------------------------------------------* * Function get_interpolation_vars() * * *-----------------------------------------------------------------------------------------*/ - static void get_interpolation_vars( MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const IVAS_QUATERNION *Quaternions_ref, @@ -1275,303 +1339,426 @@ static void get_interpolation_vars( int16_t interp_yaw_pose_idx[2], int16_t interp_pitch_pose_idx[2], int16_t interp_roll_pose_idx[2], - float *interp_yaw_fact, - float *interp_pitch_fact, - float *interp_roll_fact ) + Word32 *interp_yaw_fact_fx, + Word32 *interp_pitch_fact_fx, + Word32 *interp_roll_fact_fx, + Word16 *q_yaw, + Word16 *q_pitch, + Word16 *q_roll ) { IVAS_QUATERNION quaternions_diff, quaternions_ref_euler, quaternions_act_euler; - float y[MAX_HEAD_ROT_POSES], p[MAX_HEAD_ROT_POSES], r[MAX_HEAD_ROT_POSES]; + Word32 y_fx[MAX_HEAD_ROT_POSES], p_fx[MAX_HEAD_ROT_POSES], r_fx[MAX_HEAD_ROT_POSES]; + int16_t pos_idx, num_poses; + Word16 exp; - quaternions_diff.x = 0.0f; - quaternions_diff.y = 0.0f; - quaternions_diff.z = 0.0f; + quaternions_diff.x_fx = 0; + quaternions_diff.y_fx = 0; + quaternions_diff.z_fx = 0; num_poses = pMultiBinPoseData->num_poses; - for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { - quaternions_diff.x = pMultiBinPoseData->relative_head_poses[pos_idx][0]; - quaternions_diff.y = pMultiBinPoseData->relative_head_poses[pos_idx][1]; - quaternions_diff.z = pMultiBinPoseData->relative_head_poses[pos_idx][2]; - y[pos_idx] = quaternions_diff.x; - p[pos_idx] = quaternions_diff.y; - r[pos_idx] = quaternions_diff.z; + quaternions_diff.x_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][0]; + quaternions_diff.y_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][1]; + quaternions_diff.z_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][2]; + y_fx[pos_idx] = quaternions_diff.x_fx; + p_fx[pos_idx] = quaternions_diff.y_fx; + r_fx[pos_idx] = quaternions_diff.z_fx; } /*interpolation if actual pose is not same as one of assumed poses*/ /*get the deviation*/ - Quat2EulerDegree( *Quaternions_ref, &quaternions_ref_euler.z, &quaternions_ref_euler.y, &quaternions_ref_euler.x ); /*order in Quat2Euler seems to be reversed ?*/ - Quat2EulerDegree( *Quaternions_act, &quaternions_act_euler.z, &quaternions_act_euler.y, &quaternions_act_euler.x ); /*order in Quat2Euler seems to be reversed ?*/ - quaternions_diff.w = -3.0f; /*euler*/ - quaternions_diff.x = quaternions_act_euler.x - quaternions_ref_euler.x; - quaternions_diff.y = quaternions_act_euler.y - quaternions_ref_euler.y; - quaternions_diff.z = quaternions_act_euler.z - quaternions_ref_euler.z; - wrap_around_ypr( &quaternions_diff ); - + Quat2EulerDegree_fx( *Quaternions_ref, &quaternions_ref_euler.z_fx, &quaternions_ref_euler.y_fx, &quaternions_ref_euler.x_fx ); /*order in Quat2Euler seems to be reversed ?*/ + Quat2EulerDegree_fx( *Quaternions_act, &quaternions_act_euler.z_fx, &quaternions_act_euler.y_fx, &quaternions_act_euler.x_fx ); + + /*order in Quat2Euler seems to be reversed ?*/ + quaternions_diff.w_fx = -12582912; /*euler*/ //-3 in Q22 + quaternions_diff.x_fx = L_sub( quaternions_act_euler.x_fx, quaternions_ref_euler.x_fx ); + quaternions_diff.y_fx = L_sub( quaternions_act_euler.y_fx, quaternions_ref_euler.y_fx ); + quaternions_diff.z_fx = L_sub( quaternions_act_euler.z_fx, quaternions_ref_euler.z_fx ); + wrap_around_ypr_fx( &quaternions_diff ); interp_yaw_pose_idx[0] = 0; interp_yaw_pose_idx[1] = 0; - if ( fabs( quaternions_diff.x ) > EPSILON ) + IF( GT_32( L_abs( quaternions_diff.x_fx ), EPSILON_FX ) ) { - get_nearest_pose_ind( y, quaternions_diff.x, interp_yaw_pose_idx, num_poses ); + get_nearest_pose_ind_fx( y_fx, quaternions_diff.x_fx, interp_yaw_pose_idx, num_poses ); } - *interp_yaw_fact = get_interp_fact( y, quaternions_diff.x, interp_yaw_pose_idx ); + *interp_yaw_fact_fx = get_interp_fact_fx( y_fx, quaternions_diff.x_fx, interp_yaw_pose_idx, &exp ); + *q_yaw = Q31 - exp; interp_pitch_pose_idx[0] = 0; interp_pitch_pose_idx[1] = 0; - if ( fabs( quaternions_diff.y ) > EPSILON ) + IF( GT_32( L_abs( quaternions_diff.y_fx ), EPSILON_FX ) ) { - get_nearest_pose_ind( p, quaternions_diff.y, interp_pitch_pose_idx, num_poses ); + get_nearest_pose_ind_fx( p_fx, quaternions_diff.y_fx, interp_pitch_pose_idx, num_poses ); } - *interp_pitch_fact = get_interp_fact( p, quaternions_diff.y, interp_pitch_pose_idx ); + *interp_pitch_fact_fx = get_interp_fact_fx( p_fx, quaternions_diff.y_fx, interp_pitch_pose_idx, &exp ); + *q_pitch = Q31 - exp; interp_roll_pose_idx[0] = 0; interp_roll_pose_idx[1] = 0; - if ( fabs( quaternions_diff.z ) > EPSILON ) + IF( GT_32( L_abs( quaternions_diff.z_fx ), EPSILON_FX ) ) { - get_nearest_pose_ind( r, quaternions_diff.z, interp_roll_pose_idx, num_poses ); + get_nearest_pose_ind_fx( r_fx, quaternions_diff.z_fx, interp_roll_pose_idx, num_poses ); } - *interp_roll_fact = get_interp_fact( r, quaternions_diff.z, interp_roll_pose_idx ); + *interp_roll_fact_fx = get_interp_fact_fx( r_fx, quaternions_diff.z_fx, interp_roll_pose_idx, &exp ); + *q_roll = Q31 - exp; return; } - /*-----------------------------------------------------------------------------------------* * Function interpolate_pred_matrix() * * *-----------------------------------------------------------------------------------------*/ - -static void interpolate_pred_matrix( +static void interpolate_pred_matrix_fx( ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], - const int16_t sf_idx, - const int16_t band_idx, - const int16_t ind[2], - const float interp_fact, - float mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) + const Word16 sf_idx, + const Word16 band_idx, + const Word16 ind[2], + const Word32 interp_fact_fx, + Word16 intrep_norm, + Word32 mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_mat_re, + Word32 mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_mat_im ) { - int16_t ch_idx1, ch_idx2; - float diff; + Word16 ch_idx1, ch_idx2; ISAR_BIN_HR_SPLIT_REND_MD *pRot_md; - float mix_mat_re1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mix_mat_im1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mix_mat_re2[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mix_mat_im2[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + // ord16 intrep_norm = Q_factor_L(interp_fact); + // ord32 interp_fact_fx = floatToFixed(interp_fact, intrep_norm); + Word32 diff_fx; + Word32 mix_mat_re1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_re2_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im2_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 buff_exp_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], buff_exp_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - set_zero( mix_mat_re1[ch_idx1], BINAURAL_CHANNELS ); - set_zero( mix_mat_im1[ch_idx1], BINAURAL_CHANNELS ); - mix_mat_re1[ch_idx1][ch_idx1] = 1.0f; + set32_fx( mix_mat_re1_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + set32_fx( mix_mat_im1_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + mix_mat_re1_fx[ch_idx1][ch_idx1] = ONE_IN_Q25; - set_zero( mix_mat_re2[ch_idx1], BINAURAL_CHANNELS ); - set_zero( mix_mat_im2[ch_idx1], BINAURAL_CHANNELS ); - mix_mat_re2[ch_idx1][ch_idx1] = 1.0f; + set32_fx( mix_mat_re2_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + set32_fx( mix_mat_im2_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + mix_mat_re2_fx[ch_idx1][ch_idx1] = ONE_IN_Q25; } - if ( ind[0] != 0 ) + IF( ind[0] != 0 ) { pRot_md = &rot_md[ind[0] - 1][sf_idx][band_idx]; - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) { - mix_mat_re1[ch_idx1][ch_idx2] = pRot_md->pred_mat_re[ch_idx1][ch_idx2]; - mix_mat_im1[ch_idx1][ch_idx2] = pRot_md->pred_mat_im[ch_idx1][ch_idx2]; + mix_mat_re1_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_re_fx[ch_idx1][ch_idx2]; + mix_mat_im1_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_im_fx[ch_idx1][ch_idx2]; } } } - if ( ind[1] != 0 ) + IF( ind[1] != 0 ) { pRot_md = &rot_md[ind[1] - 1][sf_idx][band_idx]; - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) { - mix_mat_re2[ch_idx1][ch_idx2] = pRot_md->pred_mat_re[ch_idx1][ch_idx2]; - mix_mat_im2[ch_idx1][ch_idx2] = pRot_md->pred_mat_im[ch_idx1][ch_idx2]; + mix_mat_re2_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_re_fx[ch_idx1][ch_idx2]; + mix_mat_im2_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_im_fx[ch_idx1][ch_idx2]; } } } - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + Word16 final_exp = 0, mat_re_exp = 0, mat_im_exp = 0; + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) { - diff = mix_mat_re1[ch_idx1][ch_idx2] - mix_mat_re2[ch_idx1][ch_idx2]; - mat_re[ch_idx1][ch_idx2] = mix_mat_re1[ch_idx1][ch_idx2] - ( diff * interp_fact ); + final_exp = 0; + diff_fx = BASOP_Util_Add_Mant32Exp( mix_mat_re1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( mix_mat_re2_fx[ch_idx1][ch_idx2] ), 31 - Q25, &final_exp ); + Word64 tmp1 = W_mult_32_32( diff_fx, interp_fact_fx ); // final_exp + (31 - intrep_norm) + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // final_exp + (31 - intrep_norm) - tmp1_nrm + mat_re_exp = 0; + mat_re_fx[ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( mix_mat_re1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( tmp1_final ), final_exp + ( 31 - intrep_norm ) - tmp1_nrm, &mat_re_exp ); + buff_exp_re[ch_idx1][ch_idx2] = mat_re_exp; + + final_exp = 0; + diff_fx = BASOP_Util_Add_Mant32Exp( mix_mat_im1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( mix_mat_im2_fx[ch_idx1][ch_idx2] ), 31 - Q25, &final_exp ); + Word64 tmp2 = W_mult_32_32( diff_fx, interp_fact_fx ); // final_exp + (31 - intrep_norm) + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // final_exp + (31 - intrep_norm) - tmp1_nrm + mat_im_exp = 0; + mat_im_fx[ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( mix_mat_im1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( tmp2_final ), final_exp + ( 31 - intrep_norm ) - tmp2_nrm, &mat_im_exp ); + buff_exp_im[ch_idx1][ch_idx2] = mat_im_exp; + } + } - diff = mix_mat_im1[ch_idx1][ch_idx2] - mix_mat_im2[ch_idx1][ch_idx2]; - mat_im[ch_idx1][ch_idx2] = mix_mat_im1[ch_idx1][ch_idx2] - ( diff * interp_fact ); + Word16 max_exp_re = MIN16B; + Word16 max_exp_im = MIN16B; + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_exp_re = max( max_exp_re, buff_exp_re[i][j] ); + max_exp_im = max( max_exp_im, buff_exp_im[i][j] ); } } + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mat_re_fx[i][j] = L_shr( mat_re_fx[i][j], max_exp_re - buff_exp_re[i][j] ); + mat_im_fx[i][j] = L_shr( mat_im_fx[i][j], max_exp_im - buff_exp_im[i][j] ); + } + } + + *exp_mat_re = max_exp_re; + *exp_mat_im = max_exp_im; return; } - - /*-----------------------------------------------------------------------------------------* * Function interpolate_rend_md() * * *-----------------------------------------------------------------------------------------*/ -static void interpolate_rend_md( +static void interpolate_rend_md_fx( ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], - float mix_mat_re[][BINAURAL_CHANNELS], - float mix_mat_im[][BINAURAL_CHANNELS], - float *gd_int, - const int16_t sf_idx, - const int16_t band_idx, - const int16_t interp_yaw_pose_idx[2], - const int16_t interp_pitch_pose_idx[2], - const int16_t interp_roll_pose_idx[2], - const float interp_yaw_fact, - const float interp_pitch_fact, - const float interp_roll_fact ) + Word32 mix_mat_re_fx[][BINAURAL_CHANNELS], + Word16 *exp_mix_mat_re, + Word32 mix_mat_im_fx[][BINAURAL_CHANNELS], + Word16 *exp_mix_mat_im, + Word32 *gd_int_fx, + Word16 *exp_gd_int, + const Word16 sf_idx, + const Word16 band_idx, + const Word16 interp_yaw_pose_idx[2], + const Word16 interp_pitch_pose_idx[2], + const Word16 interp_roll_pose_idx[2], + const Word32 interp_yaw_fact_fx, + Word16 Q_yaw, + const Word32 interp_pitch_fact_fx, + Word16 Q_pitch, + const Word32 interp_roll_fact_fx, + Word16 Q_roll ) { - int16_t ch_idx1, idx1, idx2; - float mix_mat_re1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mix_mat_im1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mix_mat_re3[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mix_mat_im3[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - int16_t ch_idx2; - float gd1, gd2, gd3, gd4, diff, pitch_gain_r, pitch_gain_l; + Word16 ch_idx1, idx1, idx2; + + Word32 mix_mat_re1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_re3_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im3_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + Word16 exp_mix_mat_re1 = 0; + Word16 exp_mix_mat_im1 = 0; + Word16 exp_mix_mat_re3 = 0; + Word16 exp_mix_mat_im3 = 0; + + Word16 ch_idx2; + Word16 exp_pitch_gain_r, exp_pitch_gain_l; + Word32 gd1_fx = 0, gd2_fx = 0; + Word32 gd3_fx = 0, gd4_fx = 0; + Word32 pitch_gain_r_fx, pitch_gain_l_fx; + Word32 diff_fx; - gd1 = 0.0f; - gd2 = 0.0f; + Word16 exp_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 exp_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; idx1 = interp_yaw_pose_idx[0]; idx2 = interp_yaw_pose_idx[1]; - if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + + + IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) ) { - interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_yaw_pose_idx, interp_yaw_fact, mix_mat_re, mix_mat_im ); + interpolate_pred_matrix_fx( rot_md, sf_idx, band_idx, interp_yaw_pose_idx, interp_yaw_fact_fx, Q_yaw, mix_mat_re_fx, exp_mix_mat_re, mix_mat_im_fx, exp_mix_mat_im ); - if ( idx1 != 0 ) + IF( NE_16( idx1, 0 ) ) { - gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; + gd1_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd_fx; // Q25 } - if ( idx2 != 0 ) + IF( NE_16( idx2, 0 ) ) { - gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; + gd2_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd_fx; } - - diff = gd1 - gd2; - *gd_int = gd1 - ( diff * interp_yaw_fact ); + diff_fx = L_sub( gd1_fx, gd2_fx ); // Q25 + Word32 tmp1 = Mpy_32_32( diff_fx, interp_yaw_fact_fx ); // 6+Q_yaw + Word16 exp_tmp2 = 0; + Word32 tmp2 = BASOP_Util_Add_Mant32Exp( diff_fx, 31 - Q25, L_negate( tmp1 ), 6 + Q_yaw, &exp_tmp2 ); + *gd_int_fx = tmp2; + *exp_gd_int = exp_tmp2; } - else + ELSE { /*P = P'*/ - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - set_zero( mix_mat_re[ch_idx1], BINAURAL_CHANNELS ); - set_zero( mix_mat_im[ch_idx1], BINAURAL_CHANNELS ); - mix_mat_re[ch_idx1][ch_idx1] = 1.0f; + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mix_mat_re_fx[ch_idx1][j] = 0; + mix_mat_im_fx[ch_idx1][j] = 0; + mix_mat_re_fx[ch_idx1][ch_idx1] = ONE_IN_Q25; + } } - *gd_int = 0.0f; + + *exp_mix_mat_re = 6; + *exp_mix_mat_im = 6; + + *gd_int_fx = 0; + *exp_gd_int = 0; } idx1 = interp_pitch_pose_idx[0]; idx2 = interp_pitch_pose_idx[1]; - if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) ) { - gd1 = 1.0f; - gd2 = 1.0f; + gd1_fx = ONE_IN_Q25; + gd2_fx = ONE_IN_Q25; - gd3 = 1.0f; - gd4 = 1.0f; + gd3_fx = ONE_IN_Q25; + gd4_fx = ONE_IN_Q25; + + IF( NE_16( idx1, 0 ) ) + { + gd1_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd_fx; + gd3_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd2_fx; + } + IF( NE_16( idx2, 0 ) ) + { + gd2_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd_fx; + gd4_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd2_fx; + } - if ( idx1 != 0 ) + diff_fx = L_sub( gd1_fx, gd2_fx ); // Q25 + IF( EQ_32( diff_fx, -1 ) ) + { + diff_fx = 0; + } + Word32 tmp = Mpy_32_32( diff_fx, interp_pitch_fact_fx ); // 6 + Q_pitch + Word16 exp_tmp1 = 0; + Word32 tmp1 = BASOP_Util_Add_Mant32Exp( gd1_fx, 31 - Q25, L_negate( tmp ), 6 + 31 - Q_pitch, &exp_tmp1 ); + pitch_gain_l_fx = tmp1; + pitch_gain_l_fx = max( 0, pitch_gain_l_fx ); + exp_pitch_gain_l = exp_tmp1; + + diff_fx = L_sub( gd3_fx, gd4_fx ); + IF( EQ_32( diff_fx, -1 ) ) { - gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; - gd3 = rot_md[idx1 - 1][sf_idx][band_idx].gd2; + diff_fx = 0; } - if ( idx2 != 0 ) + tmp = Mpy_32_32( diff_fx, interp_pitch_fact_fx ); + exp_tmp1 = 0; + tmp1 = BASOP_Util_Add_Mant32Exp( gd3_fx, 31 - Q25, L_negate( tmp ), 6 + 31 - Q_pitch, &exp_tmp1 ); + pitch_gain_r_fx = tmp1; + pitch_gain_r_fx = max( 0, pitch_gain_r_fx ); + exp_pitch_gain_r = exp_tmp1; + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; - gd4 = rot_md[idx2 - 1][sf_idx][band_idx].gd2; + mix_mat_re_fx[ch_idx1][0] = Mpy_32_32( mix_mat_re_fx[ch_idx1][0], pitch_gain_l_fx ); // exp_mix_mat_re + exp_pitch_gain_l + exp_mat_re[ch_idx1][0] = *exp_mix_mat_re + exp_pitch_gain_l; + mix_mat_re_fx[ch_idx1][1] = Mpy_32_32( mix_mat_re_fx[ch_idx1][1], pitch_gain_r_fx ); // exp_mix_mat_re + exp_pitch_gain_r + exp_mat_re[ch_idx1][1] = *exp_mix_mat_re + exp_pitch_gain_r; + mix_mat_im_fx[ch_idx1][0] = Mpy_32_32( mix_mat_im_fx[ch_idx1][0], pitch_gain_l_fx ); // exp_mix_mat_im + exp_pitch_gain_l + exp_mat_im[ch_idx1][0] = *exp_mix_mat_im + exp_pitch_gain_l; + mix_mat_im_fx[ch_idx1][1] = Mpy_32_32( mix_mat_im_fx[ch_idx1][1], pitch_gain_r_fx ); // exp_mix_mat_im + exp_pitch_gain_r + exp_mat_im[ch_idx1][1] = *exp_mix_mat_im + exp_pitch_gain_r; } - diff = gd1 - gd2; - pitch_gain_l = gd1 - ( diff * interp_pitch_fact ); - pitch_gain_l = max( 0.0f, pitch_gain_l ); - diff = gd3 - gd4; - pitch_gain_r = gd3 - ( diff * interp_pitch_fact ); - pitch_gain_r = max( 0.0f, pitch_gain_r ); + Word16 max_exp_re = MIN16B, max_exp_im = MIN16B; + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_exp_re = max( max_exp_re, exp_mat_re[i][j] ); + max_exp_im = max( max_exp_im, exp_mat_im[i][j] ); + } + } - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) { - mix_mat_re[ch_idx1][0] *= pitch_gain_l; - mix_mat_re[ch_idx1][1] *= pitch_gain_r; - mix_mat_im[ch_idx1][0] *= pitch_gain_l; - mix_mat_im[ch_idx1][1] *= pitch_gain_r; + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mix_mat_re_fx[i][j] = L_shr( mix_mat_re_fx[i][j], max_exp_re - exp_mat_re[i][j] ); + mix_mat_im_fx[i][j] = L_shr( mix_mat_im_fx[i][j], max_exp_im - exp_mat_im[i][j] ); + } } + + *exp_mix_mat_re = max_exp_re; + *exp_mix_mat_im = max_exp_im; } - else + ELSE { - pitch_gain_l = 1.0f; - pitch_gain_r = 1.0f; + pitch_gain_l_fx = ONE_IN_Q25; + pitch_gain_r_fx = ONE_IN_Q25; } + idx1 = interp_roll_pose_idx[0]; idx2 = interp_roll_pose_idx[1]; - if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) ) { - interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact, mix_mat_re3, mix_mat_im3 ); + interpolate_pred_matrix_fx( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact_fx, Q_roll, mix_mat_re3_fx, &exp_mix_mat_re3, mix_mat_im3_fx, &exp_mix_mat_im3 ); - isar_mat_mult_2by2_complex( mix_mat_re, mix_mat_im, mix_mat_re3, mix_mat_im3, mix_mat_re1, mix_mat_im1 ); + isar_mat_mult_2by2_complex_fx( mix_mat_re_fx, *exp_mix_mat_re, mix_mat_im_fx, *exp_mix_mat_im, mix_mat_re3_fx, exp_mix_mat_re3, + mix_mat_im3_fx, exp_mix_mat_im3, mix_mat_re1_fx, &exp_mix_mat_re1, mix_mat_im1_fx, &exp_mix_mat_im1 ); - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) { - mix_mat_re[ch_idx1][ch_idx2] = mix_mat_re1[ch_idx1][ch_idx2]; - mix_mat_im[ch_idx1][ch_idx2] = mix_mat_im1[ch_idx1][ch_idx2]; + mix_mat_re_fx[ch_idx1][ch_idx2] = mix_mat_re1_fx[ch_idx1][ch_idx2]; + mix_mat_im_fx[ch_idx1][ch_idx2] = mix_mat_im1_fx[ch_idx1][ch_idx2]; } } + *exp_mix_mat_re = exp_mix_mat_re1; + *exp_mix_mat_im = exp_mix_mat_im1; } return; } - /*-----------------------------------------------------------------------------------------* * Function isar_SplitRenderer_PostRenderer() * * *-----------------------------------------------------------------------------------------*/ - -static void isar_SplitRenderer_PostRenderer( +void isar_SplitRenderer_PostRenderer( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ - float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ const IVAS_QUATERNION Quaternion_act ) { int16_t pos_idx, b, brange[2], ch_idx1; - int16_t num_md_bands, slot_idx, b2, num_slots, sf_idx_md; - float pred_out_re[BINAURAL_CHANNELS], pred_out_im[BINAURAL_CHANNELS], tmp_re, tmp_im, gd_int; + int16_t num_md_bands, slot_idx, b2, index_slot, num_slots, sf_idx_md; + Word32 pred_out_re_fx[BINAURAL_CHANNELS], pred_out_im_fx[BINAURAL_CHANNELS], tmp_re_fx, tmp_im_fx, gd_int_fx; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; #else ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[1][MAX_SPLIT_REND_MD_BANDS]; #endif int16_t interp_yaw_pose_idx[2], interp_pitch_pose_idx[2], interp_roll_pose_idx[2]; - float interp_yaw_fact, interp_pitch_fact, interp_roll_fact; - float mix_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mix_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 interp_yaw_fact_fx, interp_pitch_fact_fx, interp_roll_fact_fx; + Word16 Q_yaw = Q31, Q_pitch = Q31, Q_roll = Q31; + Word32 mix_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG float Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; #endif - float fade; - float *pMix_mat_re_prev[BINAURAL_CHANNELS]; - float *pMix_mat_im_prev[BINAURAL_CHANNELS]; + Word16 fade_fx; + Word32 *pMix_mat_re_prev_fx[BINAURAL_CHANNELS]; + Word32 *pMix_mat_im_prev_fx[BINAURAL_CHANNELS]; const int16_t *pBand_grouping = isar_split_rend_band_grouping; num_md_bands = MAX_SPLIT_REND_MD_BANDS; @@ -1586,27 +1773,33 @@ static void isar_SplitRenderer_PostRenderer( #endif sf_idx_md = 0; - get_interpolation_vars( pMultiBinPoseData, &hBinPostRenderer->QuaternionsPre[sf_idx_md], &Quaternion_act, interp_yaw_pose_idx, interp_pitch_pose_idx, interp_roll_pose_idx, &interp_yaw_fact, &interp_pitch_fact, &interp_roll_fact ); - for ( b = 0; b < num_md_bands; b++ ) + get_interpolation_vars( pMultiBinPoseData, &hBinPostRenderer->QuaternionsPre[sf_idx_md], &Quaternion_act, interp_yaw_pose_idx, interp_pitch_pose_idx, interp_roll_pose_idx, &interp_yaw_fact_fx, &interp_pitch_fact_fx, &interp_roll_fact_fx, &Q_yaw, &Q_pitch, &Q_roll ); + + FOR( b = 0; b < num_md_bands; b++ ) { - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - set_zero( mix_mat_re[ch_idx1], BINAURAL_CHANNELS ); - set_zero( mix_mat_im[ch_idx1], BINAURAL_CHANNELS ); - mix_mat_re[ch_idx1][ch_idx1] = 1.0f; + set_l( mix_mat_re_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + set_l( mix_mat_im_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + mix_mat_re_fx[ch_idx1][ch_idx1] = L_shl( 1, Q25 ); } - gd_int = 0.0f; - interpolate_rend_md( hBinPostRenderer->rot_md, mix_mat_re, mix_mat_im, &gd_int, sf_idx_md, b, interp_yaw_pose_idx, interp_pitch_pose_idx, interp_roll_pose_idx, interp_yaw_fact, interp_pitch_fact, interp_roll_fact ); - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + Word16 exp_gd_int = 0; + + Word16 exp_mix_mat_re = 6, exp_mix_mat_im = 6; + + interpolate_rend_md_fx( hBinPostRenderer->rot_md, mix_mat_re_fx, &exp_mix_mat_re, mix_mat_im_fx, &exp_mix_mat_im, &gd_int_fx, &exp_gd_int, sf_idx_md, b, interp_yaw_pose_idx, + interp_pitch_pose_idx, interp_roll_pose_idx, interp_yaw_fact_fx, Q_yaw, interp_pitch_fact_fx, Q_pitch, interp_roll_fact_fx, Q_roll ); + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { /*update the prediction matrix with interpolated matrix*/ - rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0] = mix_mat_re[ch_idx1][0]; - rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] = mix_mat_re[ch_idx1][1]; - rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] = mix_mat_im[ch_idx1][0]; - rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] = mix_mat_im[ch_idx1][1]; - rot_md_act[pos_idx][b].gd = gd_int; + rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0] = L_shl( mix_mat_re_fx[ch_idx1][0], exp_mix_mat_re - 6 ); // Q25 + rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1] = L_shl( mix_mat_re_fx[ch_idx1][1], exp_mix_mat_re - 6 ); // Q25 + rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0] = L_shl( mix_mat_im_fx[ch_idx1][0], exp_mix_mat_im - 6 ); // Q25 + rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1] = L_shl( mix_mat_im_fx[ch_idx1][1], exp_mix_mat_im - 6 ); // Q25 + rot_md_act[pos_idx][b].gd_fx = L_shl( gd_int_fx, exp_gd_int - 6 ); // Q25 } } @@ -1655,72 +1848,74 @@ static void isar_SplitRenderer_PostRenderer( pos_idx = 0; #endif { - for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) { - fade = ( (float) slot_idx + 1.0f ) / MAX_PARAM_SPATIAL_SUBFRAMES; - fade = min( fade, 1.0f ); - for ( b = 0; b < num_md_bands; b++ ) + index_slot = slot_idx; /* TODO: can be cleaned up */ + fade_fx = fade_table_fx[slot_idx]; + fade_fx = min( fade_fx, MAX_16 ); + FOR( b = 0; b < num_md_bands; b++ ) { - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - if ( hBinPostRenderer->cf_flag ) + IF( hBinPostRenderer->cf_flag ) { - pMix_mat_re_prev[ch_idx1] = hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1]; - pMix_mat_im_prev[ch_idx1] = hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1]; - mix_mat_re[ch_idx1][0] = fade * ( rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0] ) + - ( 1.0f - fade ) * pMix_mat_re_prev[ch_idx1][0]; - mix_mat_re[ch_idx1][1] = fade * ( rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] ) + - ( 1.0f - fade ) * pMix_mat_re_prev[ch_idx1][1]; - - mix_mat_im[ch_idx1][0] = fade * ( rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] ) + - ( 1.0f - fade ) * pMix_mat_im_prev[ch_idx1][0]; - mix_mat_im[ch_idx1][1] = fade * ( rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] ) + - ( 1.0f - fade ) * pMix_mat_im_prev[ch_idx1][1]; + pMix_mat_re_prev_fx[ch_idx1] = hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1]; + pMix_mat_im_prev_fx[ch_idx1] = hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1]; + mix_mat_re_fx[ch_idx1][0] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0], fade_fx ), + Mpy_32_16_1( pMix_mat_re_prev_fx[ch_idx1][0], sub( 32767, fade_fx ) ) ); + mix_mat_re_fx[ch_idx1][1] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1], fade_fx ), + Mpy_32_16_1( pMix_mat_re_prev_fx[ch_idx1][1], sub( 32767, fade_fx ) ) ); + + mix_mat_im_fx[ch_idx1][0] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0], fade_fx ), + Mpy_32_16_1( pMix_mat_im_prev_fx[ch_idx1][0], sub( 32767, fade_fx ) ) ); + mix_mat_im_fx[ch_idx1][1] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1], fade_fx ), + Mpy_32_16_1( pMix_mat_im_prev_fx[ch_idx1][1], sub( 32767, fade_fx ) ) ); } - else + ELSE { - mix_mat_re[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0]; - mix_mat_re[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1]; - mix_mat_im[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0]; - mix_mat_im[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1]; + mix_mat_re_fx[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0]; + mix_mat_re_fx[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1]; + mix_mat_im_fx[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0]; + mix_mat_im_fx[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1]; } } brange[0] = pBand_grouping[b]; brange[1] = pBand_grouping[b + 1]; - for ( b2 = brange[0]; b2 < brange[1]; b2++ ) + Word16 exp_tmp1, exp_tmp2; + FOR( b2 = brange[0]; b2 < brange[1]; b2++ ) { - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { /* Apply prediction matrix */ - IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[0][slot_idx][b2], - Cldfb_ImagBuffer_Ref_Binaural[0][slot_idx][b2], - mix_mat_re[0][ch_idx1], - mix_mat_im[0][ch_idx1], - tmp_re, - tmp_im ); - pred_out_re[ch_idx1] = tmp_re; - pred_out_im[ch_idx1] = tmp_im; - - IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[1][slot_idx][b2], - Cldfb_ImagBuffer_Ref_Binaural[1][slot_idx][b2], - mix_mat_re[1][ch_idx1], - mix_mat_im[1][ch_idx1], - tmp_re, - tmp_im ); - pred_out_re[ch_idx1] += tmp_re; - pred_out_im[ch_idx1] += tmp_im; + ivas_cmult_fix( Cldfb_RealBuffer_Ref_Binaural_fx[0][index_slot][b2], 25, Cldfb_ImagBuffer_Ref_Binaural_fx[0][index_slot][b2], 25, mix_mat_re_fx[0][ch_idx1], 6, mix_mat_im_fx[0][ch_idx1], 6, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 ); + // tmp_re_fx = L_shl(tmp_re_fx, sub(exp_tmp1, 6)); //Q25 + // tmp_im_fx = L_shl(tmp_im_fx, sub(exp_tmp1, 6)); //Q25 + + pred_out_re_fx[ch_idx1] = tmp_re_fx; + pred_out_im_fx[ch_idx1] = tmp_im_fx; + Word16 exp_re = exp_tmp1; + Word16 exp_im = exp_tmp2; + + ivas_cmult_fix( Cldfb_RealBuffer_Ref_Binaural_fx[1][index_slot][b2], 25, Cldfb_ImagBuffer_Ref_Binaural_fx[1][index_slot][b2], 25, mix_mat_re_fx[1][ch_idx1], 6, mix_mat_im_fx[1][ch_idx1], 6, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 ); + // tmp_re_fx = L_shl(tmp_re_fx, sub(exp_tmp1, 6)); //Q25 + // tmp_im_fx = L_shl(tmp_im_fx, sub(exp_tmp1, 6)); //Q25 + + pred_out_re_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( pred_out_re_fx[ch_idx1], exp_re, tmp_re_fx, exp_tmp1, &exp_re ); + pred_out_re_fx[ch_idx1] = L_shl( pred_out_re_fx[ch_idx1], exp_re - 25 ); + pred_out_im_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( pred_out_im_fx[ch_idx1], exp_im, tmp_im_fx, exp_tmp2, &exp_im ); + pred_out_im_fx[ch_idx1] = L_shl( pred_out_im_fx[ch_idx1], exp_im - 25 ); } - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][slot_idx][b2] = pred_out_re[ch_idx1]; - Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][slot_idx][b2] = pred_out_im[ch_idx1]; + Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_re[ch_idx1]; + Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_im[ch_idx1]; #else - Cldfb_RealBuffer_Ref_Binaural[ch_idx1][slot_idx][b2] = pred_out_re[ch_idx1]; - Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][slot_idx][b2] = pred_out_im[ch_idx1]; + Cldfb_RealBuffer_Ref_Binaural_fx[ch_idx1][index_slot][b2] = pred_out_re_fx[ch_idx1]; + Cldfb_ImagBuffer_Ref_Binaural_fx[ch_idx1][index_slot][b2] = pred_out_im_fx[ch_idx1]; #endif } } @@ -1734,16 +1929,16 @@ static void isar_SplitRenderer_PostRenderer( pos_idx = 0; #endif { - for ( b = 0; b < num_md_bands; b++ ) + FOR( b = 0; b < num_md_bands; b++ ) { - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { - hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0]; - hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1]; - hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0]; - hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1]; + hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0]; // Q25 + hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1]; // Q25 + hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0]; // Q25 + hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1]; // Q25 } - hBinPostRenderer->gd_mem[pos_idx][b] = rot_md_act[pos_idx][b].gd; + hBinPostRenderer->gd_mem_fx[pos_idx][b] = rot_md_act[pos_idx][b].gd_fx; // Q25 } } hBinPostRenderer->cf_flag = 1; @@ -1788,72 +1983,86 @@ static void isar_SplitRenderer_PostRenderer( return; } - /*-----------------------------------------------------------------------------------------* * Function isar_rend_CldfbSplitPostRendProcessTdIn() * * *-----------------------------------------------------------------------------------------*/ - static void isar_rend_CldfbSplitPostRendProcessTdIn( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const IVAS_QUATERNION QuaternionPost, - float output[][L_FRAME48k] ) + Word32 output_fx[][L_FRAME48k], + Word16 *Q_out ) { int16_t ch_idx, slot_idx, num_cldfb_bands; - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + Word16 Q_output = 11; /* Implement CLDFB analysis */ - for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) { - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + Scale_sig32( output_fx[ch_idx], L_FRAME48k, Q_output - Q_out[ch_idx] ); + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { - cldfbAnalysis_ts( &( output[ch_idx][num_cldfb_bands * slot_idx] ), - Cldfb_RealBuffer_Binaural[ch_idx][slot_idx], - Cldfb_ImagBuffer_Binaural[ch_idx][slot_idx], - num_cldfb_bands, - hBinHrSplitPostRend->cldfbAna[ch_idx] ); + Word16 Q_cldfb = Q_output; + cldfbAnalysis_ts_fx_fixed_q( &( output_fx[ch_idx][num_cldfb_bands * slot_idx] ), + Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx], + Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx], + num_cldfb_bands, + hBinHrSplitPostRend->cldfbAna[ch_idx], + &Q_cldfb ); // Q_cldfb - 5 } } - isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); + isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, QuaternionPost ); /* Implement CLDFB synthesis */ - for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) { - float *RealBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 scaleFactor = 31, Q_cldfb; - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch_idx][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch_idx][slot_idx]; + RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; + ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; + scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + scaleFactor = s_min( sub( scaleFactor, 3 ), Q24 ); // guarded bits + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + } + Q_cldfb = add( scaleFactor, sub( Q_output, Q5 ) ); + Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) ); + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1 + Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) ); + Q_out[ch_idx] = sub( Q_cldfb, 1 ); } return; } - - /*-----------------------------------------------------------------------------------------* * Function isar_rend_CldfbSplitPostRendProcess() * * *-----------------------------------------------------------------------------------------*/ - void isar_rend_CldfbSplitPostRendProcess( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const IVAS_QUATERNION QuaternionPost, - float Cldfb_RealBuffer_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float output[][L_FRAME48k], - const int16_t cldfb_in_flag ) + Word32 Cldfb_RealBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + Word16 Q_cldfb_in, + Word32 output_fx[][L_FRAME48k], + Word16 *Q_out, + const Word16 cldfb_in_flag ) { int16_t ch_idx, slot_idx, num_cldfb_bands; @@ -1861,35 +2070,46 @@ void isar_rend_CldfbSplitPostRendProcess( num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; - if ( cldfb_in_flag == 0 ) + IF( EQ_16( cldfb_in_flag, 0 ) ) { - isar_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output ); + isar_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output_fx, Q_out ); pop_wmops(); return; } - isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); + isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, QuaternionPost ); /* Implement CLDFB synthesis */ - for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) { - float *RealBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 scaleFactor = 31, Q_cldfb; - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch_idx][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch_idx][slot_idx]; + RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; + ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; + scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + scaleFactor = s_min( sub( scaleFactor, 3 ), Q24 ); // guarded bits + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + } + Q_cldfb = scaleFactor + Q_cldfb_in; + Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) ); + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1 + Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) ); + Q_out[ch_idx] = sub( Q_cldfb, 1 ); } pop_wmops(); return; } - /*-----------------------------------------------------------------------------------------* * Function isar_init_split_post_rend_handles() * @@ -1902,9 +2122,10 @@ void isar_init_split_post_rend_handles( hSplitRendWrapper->hBinHrSplitPostRend = NULL; hSplitRendWrapper->hSplitBinLCLDDec = NULL; hSplitRendWrapper->hLc3plusDec = NULL; - isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + isar_init_multi_bin_pose_data_fx( &hSplitRendWrapper->multiBinPoseData ); hSplitRendWrapper->first_good_frame_received = 0; return; } + #endif diff --git a/lib_isar/isar_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c index 5a7c6ee70..48a73e916 100644 --- a/lib_isar/isar_splitRendererPre.c +++ b/lib_isar/isar_splitRendererPre.c @@ -39,8 +39,8 @@ #endif #include "ivas_prot.h" #include "prot.h" -#include "isar_rom_post_rend.h" #include "lib_isar_pre_rend.h" +#include "isar_rom_post_rend.h" #include "isar_prot.h" #ifdef DEBUGGING #include "debug.h" @@ -49,18 +49,21 @@ #ifdef DBG_WAV_WRITER #include "string.h" #endif +#include "prot_fx2.h" +#include "basop_util.h" /*---------------------------------------------------------------------* * Local function declarations *---------------------------------------------------------------------*/ - -static void isar_SplitRenderer_GetRotMd( - ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ +static void isar_SplitRenderer_GetRotMd_fx( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ - float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ - const int16_t low_res, - const int16_t ro_md_flag ); + Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + Word16 exp_cldfb_re, + Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + Word16 exp_cldfb_im, + const Word16 low_res, + const Word16 ro_md_flag ); /*------------------------------------------------------------------------- * Local functions @@ -68,448 +71,881 @@ static void isar_SplitRenderer_GetRotMd( * *------------------------------------------------------------------------*/ -static void isar_calc_mat_det_2by2_complex( - float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float *det_re, - float *det_im ) +static void isar_calc_mat_det_2by2_complex_fx( + Word32 in_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_re, + Word32 in_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_im, + Word32 *det_re, + Word16 *exp_det_re, + Word32 *det_im, + Word16 *exp_det_im ) { - float re1, im1, re2, im2; + Word32 re1_fx, im1_fx, re2_fx, im2_fx; - IVAS_CMULT_FLOAT( in_re[0][0], in_im[0][0], in_re[1][1], in_im[1][1], re1, im1 ); - IVAS_CMULT_FLOAT( in_re[0][1], in_im[0][1], in_re[1][0], in_im[1][0], re2, im2 ); - *det_re = re1 - re2; - *det_im = im1 - im2; + Word16 exp_re_1 = 0, exp_re_2 = 0; + Word16 exp_im_1 = 0, exp_im_2 = 0; + ivas_cmult_fix( in_re_fx[0][0], exp_in_re, in_im_fx[0][0], exp_in_im, in_re_fx[1][1], exp_in_re, in_im_fx[1][1], exp_in_im, &re1_fx, &im1_fx, &exp_re_1, &exp_im_1 ); + ivas_cmult_fix( in_re_fx[0][1], exp_in_re, in_im_fx[0][1], exp_in_im, in_re_fx[1][0], exp_in_re, in_im_fx[1][0], exp_in_im, &re2_fx, &im2_fx, &exp_re_2, &exp_im_2 ); + + Word16 exp_re_final = 0, exp_im_final = 0; + *det_re = BASOP_Util_Add_Mant32Exp( re1_fx, exp_re_1, L_negate( re2_fx ), exp_re_2, &exp_re_final ); + *det_im = BASOP_Util_Add_Mant32Exp( im1_fx, exp_im_1, L_negate( im2_fx ), exp_im_2, &exp_im_final ); + *exp_det_re = exp_re_final; + *exp_det_im = exp_im_final; return; } - -static int16_t isar_is_mat_inv_2by2_complex( - float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) +static Word16 isar_is_mat_inv_2by2_complex_fx( + Word32 in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_re, + Word32 in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_im ) { - int16_t is_det_zero = 1; - float det, det_re, det_im; + Word16 is_det_zero = 1; + Word32 det, det_re, det_im; + Word16 exp_det = 0, exp_det_re = 0, exp_det_im = 0; + isar_calc_mat_det_2by2_complex_fx( in_re, exp_in_re, in_im, exp_in_im, &det_re, &exp_det_re, &det_im, &exp_det_im ); - isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + Word64 det_re_sq = W_mult_32_32( det_re, det_re ); + Word16 det_sq_re_nrm = W_norm( det_re_sq ); + Word32 tmp1 = W_extract_h( W_shl( det_re_sq, det_sq_re_nrm ) ); - det = ( ( det_re * det_re ) + ( det_im * det_im ) ); + Word64 det_im_sq = W_mult_32_32( det_im, det_im ); + Word16 det_im_nrm = W_norm( det_im_sq ); + Word32 tmp2 = W_extract_h( W_shl( det_im_sq, det_im_nrm ) ); - if ( det < EPSILON ) + det = BASOP_Util_Add_Mant32Exp( tmp1, exp_det_re + exp_det_re - det_sq_re_nrm, tmp2, exp_det_im + exp_det_im - det_im_nrm, &exp_det ); + + Word16 res = BASOP_Util_Cmp_Mant32Exp( det, exp_det, EPSILON_FX, 31 ); + IF( EQ_16( res, -1 ) ) { is_det_zero = 0; } return is_det_zero; } - - -static void isar_calc_mat_inv_2by2_complex( - float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float out_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float out_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) +static void isar_calc_mat_inv_2by2_complex_fx( + Word32 in_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_re, + Word32 in_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_im, + Word32 out_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_out_re, + Word32 out_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_out_im ) { - float det_re, det_im; - float re, im, det; - - isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + Word16 exp_buffer_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buffer_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - det = ( det_re * det_re ) + ( det_im * det_im ); + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + exp_buffer_re[i][j] = MIN16B; + move16(); + exp_buffer_im[i][j] = MIN16B; + move16(); + } + } + Word32 det_re_fx, det_im_fx; + Word16 exp_det_re = 0, exp_det_im = 0; + move16(); + move16(); + Word32 re_fx, im_fx, det_fx; + Word16 exp_re = 0, exp_im = 0; + move16(); + move16(); + + isar_calc_mat_det_2by2_complex_fx( in_re_fx, exp_in_re, in_im_fx, exp_in_im, &det_re_fx, &exp_det_re, &det_im_fx, &exp_det_im ); + + Word16 tmp1 = W_norm( W_mult_32_32( det_re_fx, det_re_fx ) ); + Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( det_re_fx, det_re_fx ), tmp1 ) ); // 2*exp_det_re - tmp1 + Word16 tmp3 = W_norm( W_mult_32_32( det_im_fx, det_im_fx ) ); + Word32 tmp4 = W_extract_h( W_shl( W_mult_32_32( det_im_fx, det_im_fx ), tmp3 ) ); // 2*exp_im_re - tmp3 + Word16 exp_det = 0; + det_fx = BASOP_Util_Add_Mant32Exp( tmp2, 2 * exp_det_re - tmp1, tmp4, 2 * exp_det_im - tmp3, &exp_det ); + + Word16 exp_tmp5 = 0; + Word16 tmp5 = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, det_fx, &exp_tmp5 ); + exp_det = add( exp_tmp5, sub( 1, exp_det ) ); + det_fx = L_deposit_h( tmp5 ); #ifdef DEBUGGING /* assert to catch cases when input is singular matrix */ - assert( det > 0 ); + assert( GT_32( det_fx, 0 ) ); #endif - det = 1 / det; - - IVAS_CMULT_FLOAT( det_re, -det_im, in_re[1][1], in_im[1][1], re, im ); - out_re[0][0] = re * det; - out_im[0][0] = im * det; - IVAS_CMULT_FLOAT( det_re, -det_im, in_re[0][1], in_im[0][1], re, im ); - out_re[0][1] = -re * det; - out_im[0][1] = -im * det; + exp_re = 0; + exp_im = 0; + move16(); + move16(); + ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[1][1], exp_in_re, in_im_fx[1][1], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im ); + + Word64 tmp7 = W_mult_32_32( re_fx, det_fx ); + Word16 tmp7_nrm = W_norm( tmp7 ); + out_re_fx[0][0] = W_extract_h( W_shl( tmp7, tmp7_nrm ) ); // exp_re + exp_det - tmp7_nrm + move32(); + Word64 tmp8 = W_mult_32_32( im_fx, det_fx ); + Word16 tmp8_nrm = W_norm( tmp8 ); + out_im_fx[0][0] = W_extract_h( W_shl( tmp8, tmp8_nrm ) ); // exp_im + exp_det - tmp8_nrm + move32(); + + exp_buffer_re[0][0] = add( exp_re, sub( exp_det, tmp7_nrm ) ); + move16(); + exp_buffer_im[0][0] = add( exp_im, sub( exp_det, tmp8_nrm ) ); + move16(); + + ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[0][1], exp_in_re, in_im_fx[0][1], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im ); + + Word64 tmp9 = W_mult_32_32( L_negate( re_fx ), det_fx ); + Word16 tmp9_nrm = W_norm( tmp9 ); + out_re_fx[0][1] = W_extract_h( W_shl( tmp9, tmp9_nrm ) ); + Word64 tmp10 = W_mult_32_32( L_negate( im_fx ), det_fx ); + Word16 tmp10_nrm = W_norm( tmp10 ); + out_im_fx[0][1] = W_extract_h( W_shl( tmp10, tmp10_nrm ) ); + + exp_buffer_re[0][1] = add( exp_re, sub( exp_det, tmp9_nrm ) ); + exp_buffer_im[0][1] = add( exp_im, sub( exp_det, tmp10_nrm ) ); + + ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[1][0], exp_in_re, in_im_fx[1][0], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im ); + + + Word64 tmp11 = W_mult_32_32( L_negate( re_fx ), det_fx ); + Word16 tmp11_nrm = W_norm( tmp11 ); + out_re_fx[1][0] = W_extract_h( W_shl( tmp11, tmp11_nrm ) ); + Word64 tmp12 = W_mult_32_32( L_negate( im_fx ), det_fx ); + Word16 tmp12_nrm = W_norm( tmp12 ); + out_im_fx[1][0] = W_extract_h( W_shl( tmp12, tmp12_nrm ) ); + + exp_buffer_re[1][0] = add( exp_re, sub( exp_det, tmp11_nrm ) ); + move16(); + exp_buffer_im[1][0] = add( exp_im, sub( exp_det, tmp12_nrm ) ); + move16(); + + ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[0][0], exp_in_re, in_im_fx[0][0], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im ); + + Word64 tmp13 = W_mult_32_32( re_fx, det_fx ); + Word16 tmp13_nrm = W_norm( tmp13 ); + out_re_fx[1][1] = W_extract_h( W_shl( tmp13, tmp13_nrm ) ); + move32(); + + Word64 tmp14 = W_mult_32_32( im_fx, det_fx ); + Word16 tmp14_nrm = W_norm( tmp14 ); + out_im_fx[1][1] = W_extract_h( W_shl( tmp14, tmp14_nrm ) ); + move32(); + + exp_buffer_re[1][1] = add( exp_re, sub( exp_det, tmp13_nrm ) ); + move16(); + exp_buffer_im[1][1] = add( exp_im, sub( exp_det, tmp14_nrm ) ); + move16(); + + Word16 max_exp_re = MIN16B, max_exp_im = MIN16B; + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_exp_re = s_max( max_exp_re, exp_buffer_re[i][j] ); + max_exp_im = s_max( max_exp_im, exp_buffer_im[i][j] ); + } + } - IVAS_CMULT_FLOAT( det_re, -det_im, in_re[1][0], in_im[1][0], re, im ); - out_re[1][0] = -re * det; - out_im[1][0] = -im * det; + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + out_re_fx[i][j] = L_shr( out_re_fx[i][j], max_exp_re - exp_buffer_re[i][j] ); + move32(); + out_im_fx[i][j] = L_shr( out_im_fx[i][j], max_exp_im - exp_buffer_im[i][j] ); + move32(); + } + } - IVAS_CMULT_FLOAT( det_re, -det_im, in_re[0][0], in_im[0][0], re, im ); - out_re[1][1] = re * det; - out_im[1][1] = im * det; + *exp_out_re = max_exp_re; + move16(); + *exp_out_im = max_exp_im; + move16(); return; } - - -static void ComputePredMat( - float cov_ii_re[][BINAURAL_CHANNELS], - float cov_ii_im[][BINAURAL_CHANNELS], - float cov_io_re[][BINAURAL_CHANNELS], - float cov_io_im[][BINAURAL_CHANNELS], - float pred_mat_re[][BINAURAL_CHANNELS], - float pred_mat_im[][BINAURAL_CHANNELS], - const int16_t num_chs, - const int16_t real_only ) +static void ComputePredMat_fx( + Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_re, + Word32 cov_ii_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_im, + Word32 cov_io_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_re, + Word32 cov_io_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_im, + Word32 pred_mat_re_fx[][BINAURAL_CHANNELS], + Word16 *exp_pred_mat_re, + Word32 pred_mat_im_fx[][BINAURAL_CHANNELS], + Word16 *exp_pred_mat_im, + const Word16 num_chs, + const Word16 real_only ) { - float cov_ii_local_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_ii_inv_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_ii_inv_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float trace_cov; - int16_t i, j; + Word32 cov_ii_local_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_ii_inv_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_ii_inv_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 exp_cov_ii_local_re = 0, exp_cov_ii_inv_re = 0, exp_cov_ii_inv_im = 0; + Word32 trace_cov_fx; - trace_cov = 0.0f; - for ( i = 0; i < num_chs; i++ ) + Word16 i, j; + + trace_cov_fx = 0; + Word16 exp_trace_cov = 0; + FOR( i = 0; i < num_chs; i++ ) { - trace_cov += cov_ii_re[i][i]; + trace_cov_fx = L_add( trace_cov_fx, L_shr( cov_ii_re_fx[i][i], 1 ) ); } + exp_trace_cov = add( exp_cov_ii_re, 1 ); - trace_cov = max( 0.0f, trace_cov ); - - if ( trace_cov < EPSILON ) + trace_cov_fx = L_max( 0, trace_cov_fx ); + Word16 flag = BASOP_Util_Cmp_Mant32Exp( trace_cov_fx, exp_cov_ii_re, EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) { - for ( i = 0; i < num_chs; i++ ) + FOR( i = 0; i < num_chs; i++ ) { /* protection from cases when variance of ref channels is very small */ - set_zero( pred_mat_re[i], BINAURAL_CHANNELS ); - set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); + set32_fx( pred_mat_re_fx[i], 0, BINAURAL_CHANNELS ); + set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); } return; } - for ( i = 0; i < num_chs; i++ ) + Word16 buff_exp[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + buff_exp[i][j] = 0; + move16(); + } + } + + FOR( i = 0; i < num_chs; i++ ) { - mvr2r( cov_ii_re[i], cov_ii_local_re[i], num_chs ); + Copy32( cov_ii_re_fx[i], cov_ii_local_re_fx[i], num_chs ); + set16_fx( buff_exp[i], exp_cov_ii_re, num_chs ); } - for ( i = 0; i < num_chs; i++ ) + Word32 tmp = 0; + FOR( i = 0; i < num_chs; i++ ) { - cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f ); + tmp = Mpy_32_32( trace_cov_fx, 214748 ); // exp_trace_cov + Word16 exp_tmp = 0; + cov_ii_local_re_fx[i][i] = BASOP_Util_Add_Mant32Exp( cov_ii_re_fx[i][i], exp_cov_ii_re, tmp, exp_trace_cov, &exp_tmp ); + move32(); + buff_exp[i][i] = exp_tmp; + move16(); } - if ( isar_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) ) + Word16 max_exp = MIN16B; + FOR( i = 0; i < 2; i++ ) { - isar_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im ); - isar_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, pred_mat_re, pred_mat_im ); + FOR( j = 0; j < 2; j++ ) + { + max_exp = max( max_exp, buff_exp[i][j] ); + } } - else + + FOR( i = 0; i < num_chs; i++ ) { - int16_t max_var_idx; - for ( i = 0; i < num_chs; i++ ) + FOR( j = 0; j < num_chs; j++ ) { - set_zero( pred_mat_re[i], BINAURAL_CHANNELS ); - set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); + cov_ii_local_re_fx[i][j] = L_shr( cov_ii_local_re_fx[i][j], max_exp - buff_exp[i][j] ); + move32(); + } + } + + exp_cov_ii_local_re = max_exp; + move16(); + + IF( isar_is_mat_inv_2by2_complex_fx( cov_ii_local_re_fx, exp_cov_ii_local_re, cov_ii_im_fx, exp_cov_ii_im ) ) + { + isar_calc_mat_inv_2by2_complex_fx( cov_ii_local_re_fx, exp_cov_ii_local_re, cov_ii_im_fx, exp_cov_ii_im, cov_ii_inv_re_fx, &exp_cov_ii_inv_re, cov_ii_inv_im_fx, &exp_cov_ii_inv_im ); + isar_mat_mult_2by2_complex_fx( cov_ii_inv_re_fx, exp_cov_ii_inv_re, cov_ii_inv_im_fx, exp_cov_ii_inv_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, pred_mat_re_fx, exp_pred_mat_re, pred_mat_im_fx, exp_pred_mat_im ); + } + ELSE + { + Word16 max_var_idx; + FOR( i = 0; i < num_chs; i++ ) + { + set32_fx( pred_mat_re_fx[i], 0, BINAURAL_CHANNELS ); + set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); } max_var_idx = 0; - if ( cov_ii_local_re[1][1] > cov_ii_local_re[0][0] ) + move16(); + IF( GT_32( cov_ii_local_re_fx[1][1], cov_ii_local_re_fx[0][0] ) ) { max_var_idx = 1; } - if ( cov_ii_local_re[max_var_idx][max_var_idx] > EPSILON ) + Word16 tmp1 = 0, exp_tmp1 = 0; + move16(); + move16(); + Word16 tmp2 = 0, exp_tmp2 = 0; + move16(); + move16(); + Word16 flag1 = BASOP_Util_Cmp_Mant32Exp( cov_ii_local_re_fx[max_var_idx][max_var_idx], exp_cov_ii_local_re, EPSILON_FX, 0 ); + IF( EQ_16( flag1, 1 ) ) { - for ( j = 0; j < num_chs; j++ ) + Word16 pred_mat_buf_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], pred_mat_buf_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + set16_fx( pred_mat_buf_re[i], *exp_pred_mat_re, BINAURAL_CHANNELS ); + set16_fx( pred_mat_buf_im[i], *exp_pred_mat_im, BINAURAL_CHANNELS ); + } + FOR( j = 0; j < num_chs; j++ ) { - pred_mat_re[max_var_idx][j] = cov_io_re[max_var_idx][j] / cov_ii_local_re[max_var_idx][max_var_idx]; - pred_mat_im[max_var_idx][j] = cov_io_im[max_var_idx][j] / cov_ii_local_re[max_var_idx][max_var_idx]; + tmp1 = BASOP_Util_Divide3232_Scale( cov_io_re_fx[max_var_idx][j], cov_ii_local_re_fx[max_var_idx][max_var_idx], &exp_tmp1 ); + exp_tmp1 = exp_tmp1 + ( exp_cov_io_re - exp_cov_ii_local_re ); + tmp2 = BASOP_Util_Divide3232_Scale( cov_io_im_fx[max_var_idx][j], cov_ii_local_re_fx[max_var_idx][max_var_idx], &exp_tmp2 ); + exp_tmp2 = exp_tmp2 + ( exp_cov_io_im - exp_cov_ii_local_re ); + pred_mat_re_fx[max_var_idx][j] = tmp1; + move32(); + pred_mat_im_fx[max_var_idx][j] = tmp2; + move32(); + pred_mat_buf_re[max_var_idx][j] = exp_tmp1; + move16(); + pred_mat_buf_im[max_var_idx][j] = exp_tmp2; + move16(); } + + Word16 max_re = MIN16B, max_im = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + + max_re = s_max( max_re, pred_mat_buf_re[i][j] ); + move16(); + max_im = s_max( max_im, pred_mat_buf_im[i][j] ); + move16(); + } + } + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + + pred_mat_re_fx[i][j] = L_shr( pred_mat_re_fx[i][j], max_re - pred_mat_buf_re[i][j] ); + move32(); + pred_mat_im_fx[i][j] = L_shr( pred_mat_im_fx[i][j], max_im - pred_mat_buf_im[i][j] ); + move32(); + } + } + + *exp_pred_mat_re = max_re; + move16(); + *exp_pred_mat_im = max_im; + move16(); } } - if ( real_only ) + IF( real_only ) { - for ( i = 0; i < num_chs; i++ ) + FOR( i = 0; i < num_chs; i++ ) { - set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); + set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); } } return; } - - -static void ComputePostPredCov( - float cov_ii_re[][BINAURAL_CHANNELS], - float cov_ii_im[][BINAURAL_CHANNELS], - float pred_mat_re[][BINAURAL_CHANNELS], - float pred_mat_im[][BINAURAL_CHANNELS], - float postpred_cov_re[][BINAURAL_CHANNELS], - const int16_t num_chs ) +static void ComputePostPredCov_fx( + Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_re, + Word32 cov_ii_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_im, + Word32 pred_mat_re_fx[][BINAURAL_CHANNELS], + Word16 exp_pred_mat_re, + Word32 pred_mat_im_fx[][BINAURAL_CHANNELS], + Word16 exp_pred_mat_im, + Word32 postpred_cov_re_fx[][BINAURAL_CHANNELS], + Word16 *exp_postpred_cov_re, + Word16 num_chs ) { - int16_t i, j; - float dmx_mat_conj_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float dmx_mat_conj_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float temp_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float temp_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float postpred_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 i, j; + Word32 dmx_mat_conj_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 dmx_mat_conj_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 temp_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 temp_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 postpred_cov_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 exp_postpred_cov_im = 0; + Word16 exp_temp_mat_re = 0, exp_temp_mat_im = 0; assert( num_chs == BINAURAL_CHANNELS ); - for ( i = 0; i < num_chs; i++ ) + + FOR( i = 0; i < num_chs; i++ ) { - for ( j = 0; j < num_chs; j++ ) + FOR( j = 0; j < num_chs; j++ ) { - dmx_mat_conj_re[i][j] = pred_mat_re[j][i]; - dmx_mat_conj_im[i][j] = -pred_mat_im[j][i]; - - temp_mat_re[i][j] = pred_mat_re[i][j]; - temp_mat_im[i][j] = pred_mat_im[i][j]; + dmx_mat_conj_re_fx[i][j] = pred_mat_re_fx[j][i]; + move32(); + dmx_mat_conj_im_fx[i][j] = L_negate( pred_mat_im_fx[j][i] ); + move32(); + + temp_mat_re_fx[i][j] = pred_mat_re_fx[i][j]; + move32(); + temp_mat_im_fx[i][j] = pred_mat_im_fx[i][j]; + move32(); } - set_zero( postpred_cov_re[i], BINAURAL_CHANNELS ); + set32_fx( postpred_cov_re_fx[i], 0, BINAURAL_CHANNELS ); } + isar_mat_mult_2by2_complex_fx( dmx_mat_conj_re_fx, exp_pred_mat_re, dmx_mat_conj_im_fx, exp_pred_mat_im, cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, temp_mat_re_fx, &exp_temp_mat_re, temp_mat_im_fx, &exp_temp_mat_im ); + isar_mat_mult_2by2_complex_fx( temp_mat_re_fx, exp_temp_mat_re, temp_mat_im_fx, exp_temp_mat_im, pred_mat_re_fx, exp_pred_mat_re, pred_mat_im_fx, exp_pred_mat_im, postpred_cov_re_fx, exp_postpred_cov_re, postpred_cov_im_fx, &exp_postpred_cov_im ); /* 2x2 mult */ - isar_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, temp_mat_re, temp_mat_im ); - isar_mat_mult_2by2_complex( temp_mat_re, temp_mat_im, pred_mat_re, pred_mat_im, postpred_cov_re, postpred_cov_im ); - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - for ( j = 0; j < i; j++ ) + FOR( j = 0; j < i; j++ ) { - postpred_cov_re[i][j] = postpred_cov_re[j][i]; + postpred_cov_re_fx[i][j] = postpred_cov_re_fx[j][i]; + move32(); } } return; } - - -static void ComputeBandedCrossCov( - float Cldfb_RealBuffer1[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer1[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t ch_start_idx1, - float Cldfb_RealBuffer2[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer2[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t ch_start_idx2, - float out_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float out_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - const int16_t num_chs, - const int16_t *pBand_grouping, - const int16_t num_slots, - const int16_t start_slot_idx, - const int16_t md_band_idx, - const int16_t real_only ) +static void ComputeBandedCrossCov_fx( + Word32 Cldfb_RealBuffer1_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re_1, + Word32 Cldfb_ImagBuffer1_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im_1, + const Word16 ch_start_idx1, + Word32 Cldfb_RealBuffer2_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re_2, + Word32 Cldfb_ImagBuffer2_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im_2, + const Word16 ch_start_idx2, + Word32 out_cov_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_out_cov_re, + Word32 out_cov_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_out_cov_im, + const Word16 num_chs, + const Word16 *pBand_grouping, + const Word16 num_slots, + const Word16 start_slot_idx, + const Word16 md_band_idx, + const Word16 real_only ) { - int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; - int16_t brange[2]; + Word16 sf, cldfb_band_idx, ch_idx1, ch_idx2; + Word16 brange[2]; - for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) { - set_f( out_cov_re[ch_idx1], 0.0f, num_chs ); - set_f( out_cov_im[ch_idx1], 0.0f, num_chs ); + set_l( out_cov_re_fx[ch_idx1], 0, num_chs ); + set_l( out_cov_im_fx[ch_idx1], 0, num_chs ); } brange[0] = pBand_grouping[md_band_idx]; + move16(); brange[1] = pBand_grouping[md_band_idx + 1]; - - for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + move16(); + Word16 exp_buff_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buff_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) { - for ( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ ) + FOR( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ ) { - if ( real_only == 0 ) + Word32 tmp_a = out_cov_re_fx[ch_idx1][ch_idx2], tmp_b = out_cov_im_fx[ch_idx1][ch_idx2]; + Word16 exp_tmp_a = 0, exp_tmp_b = 0; + IF( EQ_16( real_only, 0 ) ) { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ ) { - for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) { - out_cov_re[ch_idx1][ch_idx2] += - Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] + - Cldfb_ImagBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx]; - - out_cov_im[ch_idx1][ch_idx2] += - Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] - - Cldfb_ImagBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx]; + Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); + + Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); + + Word16 exp_tmp3 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re_1 + exp_cldfb_re_2 - tmp1_nrm, tmp2_final, exp_cldfb_im_1 + exp_cldfb_im_2 - tmp2_nrm, &exp_tmp3 ); + Word16 exp_tmp_a_tmp = 0; + tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp ); + exp_tmp_a = exp_tmp_a_tmp; + + Word64 tmp4 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp4_nrm = W_norm( tmp4 ); + Word32 tmp4_final = W_extract_h( W_shl( tmp4, tmp4_nrm ) ); // exp_cldfb_re_1 + exp_cldfb_im_2 - tmp4_nrm + + Word64 tmp5 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp5_nrm = W_norm( tmp5 ); + Word32 tmp5_final = W_extract_h( W_shl( tmp5, tmp5_nrm ) ); // exp_cldfb_im_1 + exp_cldfb_re_2 - tmp5_nrm + + Word16 exp_tmp6 = 0; + Word32 tmp6 = BASOP_Util_Add_Mant32Exp( tmp4_final, exp_cldfb_re_1 + exp_cldfb_im_2 - tmp4_nrm, L_negate( tmp5_final ), exp_cldfb_im_1 + exp_cldfb_re_2 - tmp5_nrm, &exp_tmp6 ); + Word16 exp_tmp_b_tmp = 0; + tmp_b = BASOP_Util_Add_Mant32Exp( tmp_b, exp_tmp_b, tmp6, exp_tmp6, &exp_tmp_b_tmp ); + exp_tmp_b = exp_tmp_b_tmp; } } } - else + ELSE { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ ) { - for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) { - out_cov_re[ch_idx1][ch_idx2] += - Cldfb_RealBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] + - Cldfb_ImagBuffer1[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx]; - - out_cov_im[ch_idx1][ch_idx2] = 0.0f; + Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); + + Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); + + Word16 exp_tmp3 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re_1 + exp_cldfb_re_2 - tmp1_nrm, tmp2_final, exp_cldfb_im_1 + exp_cldfb_im_2 - tmp2_nrm, &exp_tmp3 ); + Word16 exp_tmp_a_tmp = 0; + tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp ); + exp_tmp_a = exp_tmp_a_tmp; + + tmp_b = 0; + exp_tmp_b = 0; } } } + out_cov_re_fx[ch_idx1][ch_idx2] = tmp_a; + move32(); + out_cov_im_fx[ch_idx1][ch_idx2] = tmp_b; + move32(); + exp_buff_re[ch_idx1][ch_idx2] = exp_tmp_a; + move32(); + exp_buff_im[ch_idx1][ch_idx2] = exp_tmp_b; + move32(); } } + /*make common exponent*/ + Word16 max_cov_re = 0, max_cov_im = 0; + FOR( int i = 0; i < num_chs; i++ ) + { + FOR( int j = 0; j < num_chs; j++ ) + { + max_cov_re = max( max_cov_re, exp_buff_re[i][j] ); + max_cov_im = max( max_cov_im, exp_buff_im[i][j] ); + } + } + FOR( int i = 0; i < num_chs; i++ ) + { + FOR( int j = 0; j < num_chs; j++ ) + { + out_cov_re_fx[i][j] = L_shr( out_cov_re_fx[i][j], max_cov_re - exp_buff_re[i][j] ); + move32(); + out_cov_im_fx[i][j] = L_shr( out_cov_im_fx[i][j], max_cov_im - exp_buff_im[i][j] ); + move32(); + } + } + + *exp_out_cov_re = max_cov_re; + *exp_out_cov_im = max_cov_im; return; } - - -static void ComputeBandedCov( - float Cldfb_RealBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t ch_start_idx, - float out_cov_re[][BINAURAL_CHANNELS], - float out_cov_im[][BINAURAL_CHANNELS], - const int16_t num_chs, - const int16_t *pBand_grouping, - const int16_t num_slots, - const int16_t start_slot_idx, - const int16_t md_band_idx, - const int16_t real_only ) +static void ComputeBandedCov_fx( + Word32 Cldfb_RealBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re, + Word32 Cldfb_ImagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im, + const Word16 ch_start_idx, + Word32 out_cov_re_fx[][BINAURAL_CHANNELS], + Word16 *exp_cov_re, + Word32 out_cov_im_fx[][BINAURAL_CHANNELS], + Word16 *exp_cov_im, + const Word16 num_chs, + const Word16 *pBand_grouping, + const Word16 num_slots, + const Word16 start_slot_idx, + const Word16 md_band_idx, + const Word16 real_only ) { - int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; - int16_t brange[2]; + Word16 sf, cldfb_band_idx, ch_idx1, ch_idx2; + Word16 brange[2]; - for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) { - set_f( out_cov_re[ch_idx1], 0.0f, num_chs ); - set_f( out_cov_im[ch_idx1], 0.0f, num_chs ); + set32_fx( out_cov_re_fx[ch_idx1], 0, num_chs ); + set32_fx( out_cov_im_fx[ch_idx1], 0, num_chs ); } brange[0] = pBand_grouping[md_band_idx]; + move16(); brange[1] = pBand_grouping[md_band_idx + 1]; + move16(); + + Word16 exp_buff_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buff_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + exp_buff_re[i][j] = 0; + move16(); + exp_buff_im[i][j] = 0; + move16(); + } + } - for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) { - for ( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ ) + FOR( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ ) { - if ( ( ch_idx2 != ch_idx1 ) && ( real_only == 0 ) ) + Word32 tmp_a = out_cov_re_fx[ch_idx1][ch_idx2]; + Word32 tmp_b = out_cov_im_fx[ch_idx1][ch_idx2]; + Word16 exp_tmp_a = 0, exp_tmp_b = 0; + test(); + IF( ( NE_16( ch_idx2, ch_idx1 ) ) && ( EQ_16( real_only, 0 ) ) ) { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ ) { - for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) { - out_cov_re[ch_idx1][ch_idx2] += - Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] + - Cldfb_ImagBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx]; - - out_cov_im[ch_idx1][ch_idx2] += - Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] - - Cldfb_ImagBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx]; + Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // exp_cldfb_re + exp_cldfb_re - tmp1_nrm + + Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // exp_cldfb_im + exp_cldfb_im - tmp2_nrm + + Word16 exp_tmp3 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re + exp_cldfb_re - tmp1_nrm, tmp2_final, exp_cldfb_im + exp_cldfb_im - tmp2_nrm, &exp_tmp3 ); + Word16 exp_tmp_a_tmp = 0; + tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp ); + exp_tmp_a = exp_tmp_a_tmp; + + Word64 tmp4 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp4_nrm = W_norm( tmp4 ); + Word32 tmp4_final = W_extract_h( W_shl( tmp4, tmp4_nrm ) ); // exp_cldfb_re + exp_cldfb_im - tmp4_nrm + + Word64 tmp5 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp5_nrm = W_norm( tmp5 ); + Word32 tmp5_final = W_extract_h( W_shl( tmp5, tmp5_nrm ) ); // exp_cldfb_im + exp_cldfb_re - tmp5_nrm + + Word16 exp_tmp6 = 0; + Word32 tmp6 = BASOP_Util_Add_Mant32Exp( tmp4_final, exp_cldfb_re + exp_cldfb_im - tmp4_nrm, L_negate( tmp5_final ), exp_cldfb_im + exp_cldfb_re - tmp5_nrm, &exp_tmp6 ); + Word16 exp_tmp_b_tmp = 0; + tmp_b = BASOP_Util_Add_Mant32Exp( tmp_b, exp_tmp_b, tmp6, exp_tmp6, &exp_tmp_b_tmp ); + exp_tmp_b = exp_tmp_b_tmp; } } } - else + ELSE { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ ) { - for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) { - out_cov_re[ch_idx1][ch_idx2] += - Cldfb_RealBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx] + - Cldfb_ImagBuffer[ch_start_idx + ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_start_idx + ch_idx2][sf][cldfb_band_idx]; + Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // exp_cldfb_re + exp_cldfb_re - tmp1_nrm + + Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // exp_cldfb_im + exp_cldfb_im - tmp2_nrm + + Word16 exp_tmp3 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re + exp_cldfb_re - tmp1_nrm, tmp2_final, exp_cldfb_im + exp_cldfb_im - tmp2_nrm, &exp_tmp3 ); + + Word16 exp_tmp_a_tmp = 0; + tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp ); + exp_tmp_a = exp_tmp_a_tmp; - out_cov_im[ch_idx1][ch_idx2] = 0.0f; + tmp_b = 0; + exp_tmp_b = 0; } } } + out_cov_re_fx[ch_idx1][ch_idx2] = tmp_a; + move32(); + exp_buff_re[ch_idx1][ch_idx2] = exp_tmp_a; + move32(); + + out_cov_im_fx[ch_idx1][ch_idx2] = tmp_b; + move32(); + exp_buff_im[ch_idx1][ch_idx2] = exp_tmp_b; + move32(); } } - for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + Word16 exp_max_re = MIN16B, exp_max_im = MIN16B; + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) { - for ( ch_idx2 = ch_idx1 + 1; ch_idx2 < num_chs; ch_idx2++ ) + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) { - out_cov_re[ch_idx1][ch_idx2] = out_cov_re[ch_idx2][ch_idx1]; - out_cov_im[ch_idx1][ch_idx2] = -out_cov_im[ch_idx2][ch_idx1]; + exp_max_re = max( exp_max_re, exp_buff_re[i][j] ); + exp_max_im = max( exp_max_im, exp_buff_im[i][j] ); } } - return; -} + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + out_cov_re_fx[i][j] = L_shr( out_cov_re_fx[i][j], exp_max_re - exp_buff_re[i][j] ); + move32(); + out_cov_im_fx[i][j] = L_shr( out_cov_im_fx[i][j], exp_max_im - exp_buff_im[i][j] ); + move32(); + } + } + + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + FOR( ch_idx2 = add( ch_idx1, 1 ); ch_idx2 < num_chs; ch_idx2++ ) + { + out_cov_re_fx[ch_idx1][ch_idx2] = out_cov_re_fx[ch_idx2][ch_idx1]; + move32(); + out_cov_im_fx[ch_idx1][ch_idx2] = L_negate( out_cov_im_fx[ch_idx2][ch_idx1] ); + move32(); + } + } + *exp_cov_re = exp_max_re; + *exp_cov_im = exp_max_im; -static float GetNormFact( - float cov_ii_re[][BINAURAL_CHANNELS], - float cov_ii_im[][BINAURAL_CHANNELS], - float cov_io_re[][BINAURAL_CHANNELS], - float cov_io_im[][BINAURAL_CHANNELS], - float cov_oo_re[][BINAURAL_CHANNELS] ) + return; +} +static Word32 GetNormFact_fx( + Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_re, + Word32 cov_ii_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_im, + Word32 cov_io_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_re, + Word32 cov_io_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_im, + Word32 cov_oo_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_oo_re, + Word16 *exp_norm_fact_fx ) { - int16_t i, j; - float norm_fact, abs_val; + Word16 i, j; + Word32 norm_fact_fx = 0, abs_val_fx; + Word16 exp_abs_val = 0, exp_norm_fact = 0; - norm_fact = 0.0f; - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) { - IVAS_CALCULATE_ABS( cov_ii_re[i][j], cov_ii_im[i][j], abs_val ); - norm_fact = max( norm_fact, abs_val ); - - IVAS_CALCULATE_ABS( cov_io_re[i][j], cov_io_im[i][j], abs_val ); - norm_fact = max( norm_fact, abs_val ); + ivas_calculate_abs_fx( cov_ii_re_fx[i][j], exp_cov_ii_re, cov_ii_im_fx[i][j], exp_cov_ii_im, &abs_val_fx, &exp_abs_val ); + Word16 res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val ); + IF( EQ_16( res_1, negate( 1 ) ) ) + { + norm_fact_fx = abs_val_fx; + exp_norm_fact = exp_abs_val; + } - IVAS_CALCULATE_RABS( cov_oo_re[i][j], abs_val ); - norm_fact = max( norm_fact, abs_val ); + ivas_calculate_abs_fx( cov_io_re_fx[i][j], exp_cov_io_re, cov_io_im_fx[i][j], exp_cov_io_im, &abs_val_fx, &exp_abs_val ); + res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val ); + IF( EQ_16( res_1, negate( 1 ) ) ) + { + norm_fact_fx = abs_val_fx; + exp_norm_fact = exp_abs_val; + } + ivas_calculate_rabs_fx( cov_oo_re_fx[i][j], exp_cov_oo_re, &abs_val_fx, &exp_abs_val ); + res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val ); + IF( EQ_16( res_1, negate( 1 ) ) ) + { + norm_fact_fx = abs_val_fx; + exp_norm_fact = exp_abs_val; + } } } - norm_fact = ( norm_fact > EPSILON ) ? norm_fact : 1.0f; + Word16 flag = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) + { + norm_fact_fx = ONE_IN_Q30; + exp_norm_fact = 1; + } + + Word16 exp_tmp = 0; + Word16 tmp = BASOP_Util_Divide3232_Scale( PCM16_TO_FLT_FAC_FX, norm_fact_fx, &exp_tmp ); + exp_tmp = add( exp_tmp, sub( 16, exp_norm_fact ) ); + norm_fact_fx = L_deposit_h( tmp ); + exp_norm_fact = exp_tmp; - norm_fact = PCM16_TO_FLT_FAC / norm_fact; + *exp_norm_fact_fx = exp_norm_fact; - return norm_fact; + return norm_fact_fx; } - static void isar_split_rend_huffman_encode( isar_split_rend_huffman_cfg_t *huff_cfg, - const int16_t in, - int32_t *hcode, - int32_t *hlen ) + const Word16 in, + Word32 *hcode, + Word32 *hlen ) { - int32_t min_sym_val; - const int32_t *codebook; + Word32 min_sym_val; + const Word32 *codebook; min_sym_val = huff_cfg->codebook[0]; + move32(); codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; *hlen = codebook[1]; + move32(); *hcode = codebook[2]; + move32(); return; } - -static void isar_split_rend_quant_md( +static void isar_split_rend_quant_md_fx( ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, const ISAR_SPLIT_REND_POSE_TYPE pose_type, const int16_t real_only, - float fix_pos_rot_mat[][BINAURAL_CHANNELS], - const float pred_1byquantstep ) + Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS], + const Word32 pred_1byquantstep, // Q26 + const Word16 Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + float fix_pos_rot_mat_flt[][BINAURAL_CHANNELS], + const float pred_1byquantstep_flt // Q26 +#endif +) { int16_t ch1, ch2; int16_t gd_idx_min; #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - float quant_val; + Word32 quant_val; #else - float sign, quant_val; + Word32 sign, quant_val; +#endif +#ifdef DEBUG_QUANT_MD_FX + float quant_val_flt; + Word16 tmp; #endif - if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) { - float onebyquantstep; + Word32 onebyquantstep; onebyquantstep = pred_1byquantstep; - if ( real_only == 1 ) +#ifdef DEBUG_QUANT_MD_FX + float onebyquantstep_flt = pred_1byquantstep_flt; +#endif + IF( real_only == 1 ) { #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - hMd->pred_mat_re[ch1][ch1] = hMd->pred_mat_re2[ch1]; + hMd->pred_mat_re_fx[ch1][ch1] = hMd->pred_mat_re2[ch1]; } - hMd->pred_mat_re[1][0] = 0.0f; - hMd->pred_mat_re[0][1] = 0.0f; + hMd->pred_mat_re_fx[1][0] = 0; + hMd->pred_mat_re_fx[0][1] = 0; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - quant_val = hMd->pred_mat_re[ch1][ch2] - ( ( ch1 == ch2 ) ? 1.0f : 0.0f ); - quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) ); - hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); + quant_val = L_sub( hMd->pred_mat_re_fx[ch1][ch2], L_shr_r( ( ch1 == ch2 ) ? ONE_IN_Q31 : 0, sub( Q31, Q_frame ) ) ); + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( quant_val, L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); // Q25*Q26 = Q20 -> Q16 -> Q0 } } #else @@ -517,10 +953,12 @@ static void isar_split_rend_quant_md( { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sign = ( hMd->pred_mat_re[ch1][ch2] >= 0.0f ) ? 1.0f : -1.0f; - IVAS_CALCULATE_ABS( hMd->pred_mat_re[ch1][ch2], hMd->pred_mat_im[ch1][ch2], hMd->pred_mat_re[ch1][ch2] ); - hMd->pred_mat_re[ch1][ch2] *= sign; - hMd->pred_mat_im[ch1][ch2] = 0.0f; + sign = GE_32( hMd->pred_mat_re_fx[ch1][ch2], 0 ) ? 1 : -1; + Word16 exp_out; + ivas_calculate_abs_fx( hMd->pred_mat_re_fx[ch1][ch2], Q31 - Q_frame, hMd->pred_mat_im_fx[ch1][ch2], Q31 - Q_frame, &hMd->pred_mat_re_fx[ch1][ch2], &exp_out ); + hMd->pred_mat_re_fx[ch1][ch2] = L_shr_r( hMd->pred_mat_re_fx[ch1][ch2], sub( sub( Q31, Q_frame ), exp_out ) ); // Q_frame + hMd->pred_mat_re_fx[ch1][ch2] = (Word32) W_mult0_32_32( hMd->pred_mat_re_fx[ch1][ch2], sign ); + hMd->pred_mat_im_fx[ch1][ch2] = 0; } } #endif @@ -533,9 +971,19 @@ static void isar_split_rend_quant_md( { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2]; - quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) ); - hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); + quant_val = L_sub( hMd->pred_mat_re_fx[ch1][ch2], L_shr_r( fix_pos_rot_mat[ch1][ch2], sub( Q31, Q_frame ) ) ); + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( quant_val, L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); // Q25*Q26 = Q20 -> Q16 -> Q0 + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat_flt[ch1][ch2]; + quant_val_flt = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val_flt, ISAR_SPLIT_REND_PRED_MIN_VAL ) ); + tmp = (int16_t) roundf( onebyquantstep_flt * quant_val_flt ); + if ( hMd->pred_mat_re_idx[ch1][ch2] != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif } } #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS @@ -548,281 +996,629 @@ static void isar_split_rend_quant_md( { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) ); - hMd->pred_mat_im_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( hMd->pred_mat_im_fx[ch1][ch2], L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); + hMd->pred_mat_im_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); + // hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; + + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) ); + tmp = (int16_t) roundf( onebyquantstep_flt * quant_val_flt ); + if ( hMd->pred_mat_im_idx[ch1][ch2] != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif } } } } else if ( pose_type == COM_GAIN_ONLY ) { - quant_val = min( ISAR_SPLIT_REND_D_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_D_MIN_VAL ) ); + quant_val = L_min( L_shl_r( 1, Q_frame ) /*ISAR_SPLIT_REND_D_MAX_VAL_FX*/, L_max( hMd->gd_fx, ISAR_SPLIT_REND_D_MIN_VAL_FX ) ); //_frame + gd_idx_min = 0; //(int16_t)roundf(ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL) + hMd->gd_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_D_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) ); + hMd->gd_fx = W_extract_l( W_shr( W_mult0_32_32( hMd->gd_idx, ISAR_SPLIT_REND_D_Q_STEP_Q31 ), sub( Q31, Q_frame ) ) ); + hMd->gd_idx = sub( hMd->gd_idx, gd_idx_min ); + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = min( ISAR_SPLIT_REND_D_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_D_MIN_VAL ) ); gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL ); - hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * quant_val ); - hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_D_Q_STEP; - hMd->gd_idx = hMd->gd_idx - gd_idx_min; + tmp = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * quant_val_flt ); + tmp = tmp - gd_idx_min; + if ( hMd->gd_idx != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif } else if ( pose_type == LR_GAIN_ONLY ) { - quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ); - gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PITCH_G_MIN_VAL ); - hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); - hMd->gd_idx = hMd->gd_idx - gd_idx_min; - - quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ); - hMd->gd2_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); - hMd->gd2_idx = hMd->gd2_idx - gd_idx_min; + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( L_add( hMd->gd_fx, shr( 20, sub( Q30, Q_frame ) ) ), L_shr_r( ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); // Q25 + gd_idx_min = 7; // (int16_t)roundf(ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PRED_MAX_VAL) + hMd->gd_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) ); + hMd->gd_idx = sub( hMd->gd_idx, gd_idx_min ); + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PRED_MAX_VAL ) ); + gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PRED_MAX_VAL ); + tmp = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val_flt ); + tmp = tmp - gd_idx_min; + if ( hMd->gd_idx != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( L_add( hMd->gd2_fx, shr( 20, sub( Q30, Q_frame ) ) ), L_shr_r( ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); // Q25 + hMd->gd2_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) ); + hMd->gd2_idx = sub( hMd->gd2_idx, gd_idx_min ); + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PRED_MAX_VAL ) ); + tmp = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val_flt ); + tmp = tmp - gd_idx_min; + if ( hMd->gd2_idx != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif } - return; } + #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS -static void get_lr_gains( float cov_in[][BINAURAL_CHANNELS], - float cov_out[][BINAURAL_CHANNELS], - float gains[BINAURAL_CHANNELS] ) +static void get_lr_gains( Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + const Word16 exp_cov_ii_re, + Word32 cov_oo_re_fx[][BINAURAL_CHANNELS], + const Word16 exp_cov_oo_re, + Word32 gains_fx[BINAURAL_CHANNELS], + Word16 *exp_gains_fx ) { - int16_t i; - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 }; + Word16 exp_gd_tmp = 0, i; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - gains[i] = cov_in[i][i]; - if ( gains[i] < EPSILON ) + gains_fx[i] = cov_ii_re_fx[i][i]; + move32(); + exp_gd_tmp_buf[i] = exp_cov_ii_re; + move16(); + + Word16 flag = BASOP_Util_Cmp_Mant32Exp( gains_fx[i], exp_gd_tmp_buf[i], EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) { - gains[i] = 1.0f; + gains_fx[i] = ONE_IN_Q25; + move32(); + exp_gd_tmp_buf[i] = 6; + move16(); } - else + ELSE { - gains[i] = ( cov_out[i][i] ) / gains[i]; - gains[i] = sqrtf( gains[i] ); + Word16 tmp, tmp_sqrt, exp_tmp = 0; + tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gains_fx[i], &exp_tmp ); + exp_tmp = exp_tmp + ( exp_cov_oo_re - exp_gd_tmp_buf[i] ); + tmp_sqrt = Sqrt16( tmp, &exp_tmp ); + gains_fx[i] = L_deposit_h( tmp_sqrt ); + move32(); + exp_gd_tmp_buf[i] = exp_tmp; + move16(); } } + + Word16 max_gd_exp = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + max_gd_exp = max( max_gd_exp, exp_gd_tmp_buf[i] ); + } + exp_gd_tmp = max_gd_exp; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gains_fx[i] = L_shr( gains_fx[i], max_gd_exp - exp_gd_tmp_buf[i] ); + move32(); + } + + *exp_gains_fx = exp_gd_tmp; + move16(); return; } #endif -static void ComputeCoeffs( - float cov_ii_re[][BINAURAL_CHANNELS], - float cov_ii_im[][BINAURAL_CHANNELS], - float cov_io_re[][BINAURAL_CHANNELS], - float cov_io_im[][BINAURAL_CHANNELS], - float cov_oo_re[][BINAURAL_CHANNELS], +static void ComputeCoeffs_fx( + Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_re, + Word32 cov_ii_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_im, + Word32 cov_io_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_re, + Word32 cov_io_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_im, + Word32 cov_oo_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_oo_re, ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, const ISAR_SPLIT_REND_POSE_TYPE pose_type, - const int16_t real_only ) + const Word16 real_only ) { - float postpred_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_ii_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_ii_norm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_io_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_io_norm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_oo_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float sigma_d, gd, gd2, gl2, gr2, cov_norm_fact; - int16_t i, j; - - if ( pose_type == PITCH_ONLY ) - { - float gd_tmp[BINAURAL_CHANNELS]; -#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp ); -#else - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + Word16 i, j; + Word32 gd_fx, gl2_fx, gr2_fx, cov_norm_fact_fx; + Word16 exp_gd = 0; + + Word32 postpred_cov_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 exp_postpred_cov_re = 0; + + Word32 cov_ii_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_ii_norm_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_io_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_io_norm_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_oo_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + Word16 exp_cov_ii_norm_re = 0, exp_cov_ii_norm_im = 0, exp_cov_io_norm_re = 0, exp_cov_io_norm_im = 0, exp_cov_oo_norm_re = 0; + Word16 exp_pred_re = 0, exp_pred_im = 0; + + IF( EQ_16( pose_type, PITCH_ONLY ) ) + { + Word32 gd_tmp_fx[BINAURAL_CHANNELS]; + Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 }; + Word16 exp_gd_tmp = 0; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - gd_tmp[i] = cov_ii_re[i][i]; - if ( gd_tmp[i] < EPSILON ) + gd_tmp_fx[i] = cov_ii_re_fx[i][i]; + move32(); + exp_gd_tmp_buf[i] = exp_cov_ii_re; + move16(); + exp_gd_tmp = exp_cov_ii_re; + + Word16 flag = BASOP_Util_Cmp_Mant32Exp( gd_tmp_fx[i], exp_gd_tmp, EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) { - gd_tmp[i] = 1.0f; + gd_tmp_fx[i] = ONE_IN_Q25; + move32(); + exp_gd_tmp_buf[i] = 6; + move16(); } - else + ELSE { - gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; - gd_tmp[i] = sqrtf( gd_tmp[i] ); + Word16 tmp, tmp_sqrt, exp_tmp = 0; + tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gd_tmp_fx[i], &exp_tmp ); + exp_tmp = add( exp_tmp, sub( exp_cov_oo_re, exp_gd_tmp ) ); + tmp_sqrt = Sqrt16( tmp, &exp_tmp ); + gd_tmp_fx[i] = L_deposit_h( tmp_sqrt ); + move32(); + exp_gd_tmp_buf[i] = exp_tmp; + move16(); } } -#endif - hMd->gd = gd_tmp[0]; - hMd->gd2 = gd_tmp[1]; - } - else - { - if ( real_only ) + + Word16 max_gd_exp = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + max_gd_exp = s_max( max_gd_exp, exp_gd_tmp_buf[i] ); + } + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gd_tmp_fx[i] = L_shr( gd_tmp_fx[i], max_gd_exp - exp_gd_tmp_buf[i] ); + move32(); + } + exp_gd_tmp = max_gd_exp; + move16(); + hMd->gd_fx = gd_tmp_fx[0]; + move16(); + hMd->gd2_fx = gd_tmp_fx[1]; + move16(); + hMd->exp_gd = exp_gd_tmp; + move16(); + hMd->exp_gd2 = exp_gd_tmp; + move16(); + } + ELSE + { + IF( real_only ) { - float gd_tmp[BINAURAL_CHANNELS]; #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp ); + Word32 gd_tmp_fx[BINAURAL_CHANNELS]; + get_lr_gains( cov_ii_re_fx, exp_cov_ii_re, + cov_oo_re_fx, exp_cov_oo_re, + gd_tmp_fx, &hMd->exp_pred_mat_re2 ); + hMd->pred_mat_re_fx[1][0] = 0; + move32(); + hMd->pred_mat_re_fx[0][1] = 0; + move32(); + hMd->exp_pred_mat_re = hMd->exp_pred_mat_re2; + move16(); + hMd->exp_pred_mat_im = hMd->exp_pred_mat_re; + move16(); for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { - hMd->pred_mat_re[i][i] = gd_tmp[i]; - hMd->pred_mat_re2[i] = gd_tmp[i]; - set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS ); + hMd->pred_mat_re_fx[i][i] = gd_tmp_fx[i]; + hMd->pred_mat_re2[i] = gd_tmp_fx[i]; + set32_fx( hMd->pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); } + + #else - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + Word32 gd_tmp_fx[BINAURAL_CHANNELS]; + Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 }; + Word16 exp_gd_tmp = 0; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - gd_tmp[i] = cov_ii_re[i][i]; - if ( gd_tmp[i] < EPSILON ) + gd_tmp_fx[i] = cov_ii_re_fx[i][i]; + move32(); + exp_gd_tmp_buf[i] = exp_cov_ii_re; + move16(); + + Word16 flag = BASOP_Util_Cmp_Mant32Exp( gd_tmp_fx[i], exp_gd_tmp_buf[i], EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) { - gd_tmp[i] = 1.0f; + gd_tmp_fx[i] = ONE_IN_Q25; + move32(); + exp_gd_tmp_buf[i] = 6; + move16(); } - else + ELSE { - gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; - gd_tmp[i] = sqrtf( gd_tmp[i] ); + Word16 tmp, tmp_sqrt, exp_tmp = 0; + tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gd_tmp_fx[i], &exp_tmp ); + exp_tmp = exp_tmp + ( exp_cov_oo_re - exp_gd_tmp_buf[i] ); + tmp_sqrt = Sqrt16( tmp, &exp_tmp ); + gd_tmp_fx[i] = L_deposit_h( tmp_sqrt ); + move32(); + exp_gd_tmp_buf[i] = exp_tmp; + move16(); } - hMd->pred_mat_re[i][i] = gd_tmp[i]; - set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS ); + hMd->pred_mat_re_fx[i][i] = gd_tmp_fx[i]; + move32(); + set32_fx( hMd->pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); + } + hMd->pred_mat_re_fx[1][0] = 0; + move32(); + hMd->pred_mat_re_fx[0][1] = 0; + move32(); + + Word16 max_gd_exp = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + max_gd_exp = max( max_gd_exp, exp_gd_tmp_buf[i] ); } + exp_gd_tmp = max_gd_exp; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re_fx[i][i] = L_shr( hMd->pred_mat_re_fx[i][i], max_gd_exp - exp_gd_tmp_buf[i] ); + move32(); + } + + exp_pred_re = exp_gd_tmp; + move16(); + exp_pred_im = exp_gd_tmp; + move16(); + + hMd->exp_pred_mat_re = exp_pred_re; + move16(); + hMd->exp_pred_mat_im = exp_pred_im; + move16(); #endif - hMd->pred_mat_re[1][0] = 0.0f; - hMd->pred_mat_re[0][1] = 0.0f; } - else + ELSE { #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - get_lr_gains( cov_ii_re, cov_oo_re, hMd->pred_mat_re2 ); + get_lr_gains( cov_ii_re_fx, exp_cov_ii_re, + cov_oo_re_fx, exp_cov_oo_re, + hMd->pred_mat_re2, &hMd->exp_pred_mat_re2 ); #endif - cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); + Word16 exp_norm_fact = 0; + cov_norm_fact_fx = GetNormFact_fx( cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, cov_oo_re_fx, exp_cov_oo_re, &exp_norm_fact ); - /* normalize the covariance */ - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) { - cov_ii_norm_re[i][j] = cov_ii_re[i][j] * cov_norm_fact; - cov_ii_norm_im[i][j] = cov_ii_im[i][j] * cov_norm_fact; - cov_io_norm_re[i][j] = cov_io_re[i][j] * cov_norm_fact; - cov_io_norm_im[i][j] = cov_io_im[i][j] * cov_norm_fact; - cov_oo_norm_re[i][j] = cov_oo_re[i][j] * cov_norm_fact; + cov_ii_norm_re_fx[i][j] = Mpy_32_32( cov_ii_re_fx[i][j], cov_norm_fact_fx ); + move32(); + cov_ii_norm_im_fx[i][j] = Mpy_32_32( cov_ii_im_fx[i][j], cov_norm_fact_fx ); + move32(); + cov_io_norm_re_fx[i][j] = Mpy_32_32( cov_io_re_fx[i][j], cov_norm_fact_fx ); + move32(); + cov_io_norm_im_fx[i][j] = Mpy_32_32( cov_io_im_fx[i][j], cov_norm_fact_fx ); + move32(); + cov_oo_norm_re_fx[i][j] = Mpy_32_32( cov_oo_re_fx[i][j], cov_norm_fact_fx ); + move32(); } } - ComputePredMat( cov_ii_norm_re, cov_ii_norm_im, cov_io_norm_re, cov_io_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, BINAURAL_CHANNELS, real_only ); + exp_cov_ii_norm_re = add( exp_cov_ii_re, exp_norm_fact ); + exp_cov_ii_norm_im = add( exp_cov_ii_im, exp_norm_fact ); + exp_cov_io_norm_re = add( exp_cov_io_re, exp_norm_fact ); + exp_cov_io_norm_im = add( exp_cov_io_im, exp_norm_fact ); + exp_cov_oo_norm_re = add( exp_cov_oo_re, exp_norm_fact ); + + ComputePredMat_fx( cov_ii_norm_re_fx, exp_cov_ii_norm_re, cov_ii_norm_im_fx, exp_cov_ii_norm_im, cov_io_norm_re_fx, exp_cov_io_norm_re, cov_io_norm_im_fx, exp_cov_io_norm_im, hMd->pred_mat_re_fx, &exp_pred_re, hMd->pred_mat_im_fx, &exp_pred_im, BINAURAL_CHANNELS, real_only ); + hMd->exp_pred_mat_re = exp_pred_re; + move16(); + hMd->exp_pred_mat_im = exp_pred_im; + move16(); - ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, BINAURAL_CHANNELS ); + /*TODO : change this function to real only as thats what is needed*/ + ComputePostPredCov_fx( cov_ii_norm_re_fx, exp_cov_ii_norm_re, cov_ii_norm_im_fx, exp_cov_ii_norm_im, hMd->pred_mat_re_fx, exp_pred_re, hMd->pred_mat_im_fx, exp_pred_im, postpred_cov_re_fx, &exp_postpred_cov_re, BINAURAL_CHANNELS ); /* normalize everything to +-1 range */ - gd = 1.0f / ( PCM16_TO_FLT_FAC ); - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + Word16 gd_16_fx = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, PCM16_TO_FLT_FAC_FX, &exp_gd ); + gd_fx = L_deposit_h( gd_16_fx ); + exp_gd = add( exp_gd, sub( 1, 16 ) ); + + Word16 tmp_buff_2[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmp_buff_3[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) { - postpred_cov_re[i][j] *= gd; - cov_ii_norm_re[i][j] = cov_ii_norm_re[i][j] * gd; - cov_oo_norm_re[i][j] = cov_oo_norm_re[i][j] * gd; + Word64 tmp_2 = W_mult_32_32( cov_ii_norm_re_fx[i][j], gd_fx ); + Word64 tmp_3 = W_mult_32_32( cov_oo_norm_re_fx[i][j], gd_fx ); + Word16 shift_2 = W_norm( tmp_2 ); + Word16 shift_3 = W_norm( tmp_3 ); + + postpred_cov_re_fx[i][j] = Mpy_32_32( postpred_cov_re_fx[i][j], gd_fx ); + move32(); + cov_ii_norm_re_fx[i][j] = W_extract_h( W_shl( tmp_2, shift_2 ) ); + move32(); + cov_oo_norm_re_fx[i][j] = W_extract_h( W_shl( tmp_3, shift_3 ) ); + move32(); + + tmp_buff_2[i][j] = exp_cov_ii_norm_re + exp_gd - shift_2; + move16(); + tmp_buff_3[i][j] = exp_cov_oo_norm_re + exp_gd - shift_3; + move16(); + } + } + Word16 max_2 = MIN16B, max_3 = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_2 = s_max( max_2, tmp_buff_2[i][j] ); + max_3 = s_max( max_3, tmp_buff_3[i][j] ); } } - gd2 = 0.0f; - sigma_d = 0.0f; - hMd->gd = 0.0f; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + cov_ii_norm_re_fx[i][j] = L_shr( cov_ii_norm_re_fx[i][j], max_2 - tmp_buff_2[i][j] ); + move32(); + cov_oo_norm_re_fx[i][j] = L_shr( cov_oo_norm_re_fx[i][j], max_3 - tmp_buff_3[i][j] ); + move32(); + } + } - if ( postpred_cov_re[0][0] > EPSILON ) + exp_postpred_cov_re = add( exp_postpred_cov_re, exp_gd ); + exp_cov_ii_norm_re = max_2; + move16(); + exp_cov_oo_norm_re = max_3; + move16(); + + hMd->gd_fx = 0; + move16(); + Word16 exp_gl2 = 0; + move16(); + Word16 check_postPred = BASOP_Util_Cmp_Mant32Exp( postpred_cov_re_fx[0][0], exp_postpred_cov_re, EPSILON_FX, 0 ); + IF( EQ_16( check_postPred, 1 ) ) { - gl2 = ( cov_oo_norm_re[0][0] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[0][0] ); - gl2 = max( gl2, 1.0f ); - gl2 = sqrtf( gl2 ); + Word16 exp_div_res = 0; + Word16 div_res = BASOP_Util_Divide3232_Scale( cov_oo_norm_re_fx[0][0], postpred_cov_re_fx[0][0], &exp_div_res ); + exp_div_res = exp_div_res + ( exp_cov_oo_norm_re - exp_postpred_cov_re ); + gl2_fx = L_deposit_h( div_res ); + exp_gl2 = exp_div_res; + move16(); + + Word16 Cmp1 = BASOP_Util_Cmp_Mant32Exp( gl2_fx, exp_gl2, ONE_IN_Q30, 1 ); + IF( EQ_16( Cmp1, negate( 1 ) ) ) + { + gl2_fx = ONE_IN_Q30; + exp_gl2 = 1; + move16(); + move16(); + } + + gl2_fx = Sqrt32( gl2_fx, &exp_gl2 ); } - else + ELSE { - gl2 = 1.0f; + gl2_fx = ONE_IN_Q30; + exp_gl2 = 1; + move16(); + move16(); } - if ( postpred_cov_re[1][1] > EPSILON ) + Word16 exp_gr2 = 0; + check_postPred = BASOP_Util_Cmp_Mant32Exp( postpred_cov_re_fx[1][1], exp_postpred_cov_re, EPSILON_FX, 0 ); + IF( EQ_16( check_postPred, 1 ) ) { - gr2 = ( cov_oo_norm_re[1][1] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[1][1] ); - gr2 = max( gr2, 1.0f ); - gr2 = sqrtf( gr2 ); + Word16 exp_div_res = 0; + Word16 div_res = BASOP_Util_Divide3232_Scale( cov_oo_norm_re_fx[1][1], postpred_cov_re_fx[1][1], &exp_div_res ); + exp_div_res = exp_div_res + ( exp_cov_oo_norm_re - exp_postpred_cov_re ); + gr2_fx = L_deposit_h( div_res ); + exp_gr2 = exp_div_res; + + Word16 Cmp1 = BASOP_Util_Cmp_Mant32Exp( gr2_fx, exp_gr2, ONE_IN_Q30, 1 ); + IF( EQ_16( Cmp1, negate( 1 ) ) ) + { + gr2_fx = ONE_IN_Q30; + move16(); + exp_gr2 = 1; + move16(); + } + + gr2_fx = Sqrt32( gr2_fx, &exp_gr2 ); } - else + ELSE { - gr2 = 1.0f; + gr2_fx = ONE_IN_Q30; + move16(); + exp_gr2 = 1; + move16(); } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + Word16 pred_mat_buf_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 pred_mat_buf_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + pred_mat_buf_re[i][j] = exp_pred_re; + move16(); + pred_mat_buf_im[i][j] = exp_pred_im; + move16(); + } + } + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re_fx[i][0] = Mpy_32_32( hMd->pred_mat_re_fx[i][0], gl2_fx ); + move32(); + hMd->pred_mat_re_fx[i][1] = Mpy_32_32( hMd->pred_mat_re_fx[i][1], gr2_fx ); + move32(); + pred_mat_buf_re[i][0] = add( exp_pred_re, exp_gl2 ); + move16(); + pred_mat_buf_re[i][1] = add( exp_pred_re, exp_gr2 ); + move16(); + } + + IF( EQ_16( real_only, 0 ) ) + { + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_im_fx[i][0] = Mpy_32_32( hMd->pred_mat_im_fx[i][0], gl2_fx ); + move32(); + hMd->pred_mat_im_fx[i][1] = Mpy_32_32( hMd->pred_mat_im_fx[i][1], gr2_fx ); + move32(); + + pred_mat_buf_im[i][0] = add( exp_pred_im, exp_gl2 ); + move16(); + pred_mat_buf_im[i][1] = add( exp_pred_im, exp_gr2 ); + move16(); + } + } + + Word16 max_exp_pred_re = MIN16B, max_exp_pred_im = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - hMd->pred_mat_re[i][0] *= gl2; - hMd->pred_mat_re[i][1] *= gr2; + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_exp_pred_re = s_max( max_exp_pred_re, pred_mat_buf_re[i][j] ); + max_exp_pred_im = s_max( max_exp_pred_im, pred_mat_buf_im[i][j] ); + } } - if ( real_only == 0 ) + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) { - hMd->pred_mat_im[i][0] *= gl2; - hMd->pred_mat_im[i][1] *= gr2; + hMd->pred_mat_re_fx[i][j] = L_shr( hMd->pred_mat_re_fx[i][j], max_exp_pred_re - pred_mat_buf_re[i][j] ); + move32(); + hMd->pred_mat_im_fx[i][j] = L_shr( hMd->pred_mat_im_fx[i][j], max_exp_pred_im - pred_mat_buf_im[i][j] ); + move32(); } } + + hMd->exp_pred_mat_re = max_exp_pred_re; + move16(); + hMd->exp_pred_mat_im = max_exp_pred_im; + move16(); } } return; } - static void get_base2_bits( const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int16_t num_subframes, - const int16_t num_quant_strats, - const int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - int32_t base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS] ) + const Word16 num_subframes, + const Word16 num_quant_strats, + const Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS] ) { - int16_t pred_roll_bits; - int16_t d_gain_bits, pitch_gain_bits, pose_idx, q; - int16_t pred_yaw_bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 pred_roll_bits; + Word16 d_gain_bits, pitch_gain_bits, pose_idx, q; + Word16 pred_yaw_bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 bin_ch_2, bin_ch_2_num_sf, bin_ch_num_sf; ISAR_SPLIT_REND_POSE_TYPE pose_type; - for ( q = 0; q < num_quant_strats; q++ ) + FOR( q = 0; q < num_quant_strats; q++ ) { - pred_yaw_bits[q] = (int16_t) ceilf( log2f( pred_quant_pnts_yaw[q] ) ); + pred_yaw_bits[q] = ceil_log_2( pred_quant_pnts_yaw[q] ); + move16(); } - pred_roll_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) ); + pred_roll_bits = ceil_log_2( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS ); - d_gain_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_D_QUANT_PNTS ) ); + d_gain_bits = ceil_log_2( ISAR_SPLIT_REND_D_QUANT_PNTS ); pitch_gain_bits = d_gain_bits; + move16(); - for ( q = 0; q < num_quant_strats; q++ ) + FOR( q = 0; q < num_quant_strats; q++ ) { base2bits[q] = 0; + move32(); } - for ( q = 0; q < num_quant_strats; q++ ) + bin_ch_2 = DEPR_i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); + bin_ch_2_num_sf = DEPR_i_mult( bin_ch_2, num_subframes ); + bin_ch_num_sf = DEPR_i_mult( BINAURAL_CHANNELS, num_subframes ); + + FOR( q = 0; q < num_quant_strats; q++ ) { - for ( pose_idx = 0; pose_idx < pMultiBinPoseData->num_poses - 1; pose_idx++ ) + FOR( pose_idx = 0; pose_idx < sub( pMultiBinPoseData->num_poses, 1 ); pose_idx++ ) { pose_type = hBinHrSplitPreRend->pose_type[pose_idx]; - if ( pose_type == ANY_YAW ) + IF( EQ_32( pose_type, ANY_YAW ) ) { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; - base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_real_bands_yaw[q] ), bin_ch_2_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_2_num_sf ) ); + move32(); #else - base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS; - base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS; - base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_real_bands_yaw[q] ), bin_ch_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_2_num_sf ) ); + move32(); #endif - base2bits[q] += d_gain_bits * d_bands_yaw[q] * num_subframes; + + + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( d_gain_bits, d_bands_yaw[q] ), num_subframes ) ); + move32(); } - else if ( pose_type == PITCH_ONLY ) + ELSE IF( EQ_32( pose_type, PITCH_ONLY ) ) { - base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; - base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pitch_gain_bits, bands_pitch[q] ), num_subframes ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pitch_gain_bits, bands_pitch[q] ), num_subframes ) ); + move32(); } - else + ELSE { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; - base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_real_bands_roll[q] ), bin_ch_2_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_2_num_sf ) ); + move32(); #else - base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS; - base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS; - base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_real_bands_roll[q] ), bin_ch_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_2_num_sf ) ); + move32(); #endif } } @@ -835,186 +1631,191 @@ static void get_base2_bits( static void isar_SplitRenderer_code_md_base2( const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int16_t num_subframes, - const int16_t pred_real_bands_yaw, - const int16_t pred_imag_bands_yaw, - const int16_t pred_quant_pnts_yaw, - const int16_t d_bands_yaw, - const int16_t bands_pitch, - const int16_t pred_real_bands_roll, - const int16_t pred_imag_bands_roll, + const Word16 num_subframes, + const Word16 pred_real_bands_yaw, + const Word16 pred_imag_bands_yaw, + const Word16 pred_quant_pnts_yaw, + const Word16 d_bands_yaw, + const Word16 bands_pitch, + const Word16 pred_real_bands_roll, + const Word16 pred_imag_bands_roll, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int16_t pos_idx, b, ch1, ch2, sf_idx; - int16_t min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses; - int16_t min_pred_roll_idx, pred_roll_code_len; - int16_t pred_cb_idx; - int32_t code; + Word16 pos_idx, b, ch1, ch2, sf_idx; + Word16 min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses; + Word16 min_pred_roll_idx, pred_roll_code_len; + Word16 pred_cb_idx; + Word32 code; ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; - if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) + IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) ) { pred_cb_idx = 1; + move16(); } - else + ELSE { pred_cb_idx = 0; + move16(); } - min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0]; - min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0]; - min_gd_idx = (int16_t) pHuff_cfg->gd.codebook[0]; - min_p_gd_idx = (int16_t) pHuff_cfg->p_gd.codebook[0]; + min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] ); + min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] ); + min_gd_idx = extract_l( pHuff_cfg->gd.codebook[0] ); + min_p_gd_idx = extract_l( pHuff_cfg->p_gd.codebook[0] ); pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; + move16(); pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; + move16(); gd_code_len = pHuff_cfg->gd_base2_code_len; + move16(); p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + move16(); num_poses = pMultiBinPoseData->num_poses; + move16(); - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < sub( num_poses, 1 ); pos_idx++ ) { - if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], ANY_YAW ) ) { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( b = 0; b < pred_real_bands_yaw; b++ ) + FOR( b = 0; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx; + code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx; + code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } } #else - - for ( b = 0; b < pred_imag_bands_yaw; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx; + code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx; + code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } } - - for ( ; b < pred_real_bands_yaw; b++ ) + FOR( ; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_idx; + code = L_sub( hMd->pred_mat_re_idx[ch1][ch1], min_pred_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } #endif - for ( b = 0; b < d_bands_yaw; b++ ) + FOR( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - code = hMd->gd_idx - min_gd_idx; + code = L_sub( hMd->gd_idx, min_gd_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, gd_code_len ); } } - else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + ELSE IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], PITCH_ONLY ) ) { - for ( b = 0; b < bands_pitch; b++ ) + FOR( b = 0; b < bands_pitch; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - code = hMd->gd_idx - min_p_gd_idx; + code = L_sub( hMd->gd_idx, min_p_gd_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len ); - code = hMd->gd2_idx - min_p_gd_idx; + code = L_sub( hMd->gd2_idx, min_p_gd_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len ); } } - else + ELSE { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( b = 0; b < pred_real_bands_roll; b++ ) + FOR( b = 0; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx; + code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_roll_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); } } } - for ( b = 0; b < pred_imag_bands_roll; b++ ) + FOR( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx; + code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_roll_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); } } } #else - for ( b = 0; b < pred_imag_bands_roll; b++ ) + FOR( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx; + code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_roll_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); } } - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx; + code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_roll_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); } } } - - for ( ; b < pred_real_bands_roll; b++ ) + FOR( ; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_roll_idx; + code = L_sub( hMd->pred_mat_re_idx[ch1][ch1], min_pred_roll_idx ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); } } @@ -1049,71 +1850,73 @@ static void isar_SplitRenderer_code_md_base2( static void isar_SplitRenderer_code_md_huff( const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int16_t num_subframes, - const int16_t pred_real_bands_yaw, - const int16_t pred_imag_bands_yaw, - const int16_t pred_quant_pnts_yaw, - const int16_t d_bands_yaw, - const int16_t bands_pitch, - const int16_t pred_real_bands_roll, - const int16_t pred_imag_bands_roll, + const Word16 num_subframes, + const Word16 pred_real_bands_yaw, + const Word16 pred_imag_bands_yaw, + const Word16 pred_quant_pnts_yaw, + const Word16 d_bands_yaw, + const Word16 bands_pitch, + const Word16 pred_real_bands_roll, + const Word16 pred_imag_bands_roll, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int16_t pos_idx, b, ch1, ch2, sf_idx, num_poses; - int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - int16_t min_pred_idx, max_pred_idx; - int16_t min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx; - int32_t code, len; + Word16 pos_idx, b, ch1, ch2, sf_idx, num_poses; + Word16 sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 min_pred_idx, max_pred_idx; + Word16 min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx; + Word32 code, len; ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; - if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) + IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) ) { pred_cb_idx = 1; + move16(); } - else + ELSE { pred_cb_idx = 0; + move16(); } - min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0]; - max_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3]; - min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0]; - max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; + min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] ); + max_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[DEPR_i_mult( sub( pred_quant_pnts_yaw, 1 ), 3 )] ); + min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] ); + max_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[DEPR_i_mult( sub( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS, 1 ), 3 )] ); num_poses = pMultiBinPoseData->num_poses; + move16(); - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < sub( num_poses, 1 ); pos_idx++ ) { - if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], ANY_YAW ) ) { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( b = 0; b < pred_real_bands_yaw; b++ ) + FOR( b = 0; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); @@ -1121,13 +1924,13 @@ static void isar_SplitRenderer_code_md_huff( } } #else - for ( b = 0; b < pred_imag_bands_yaw; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); @@ -1135,37 +1938,37 @@ static void isar_SplitRenderer_code_md_huff( } isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } } - - for ( ; b < pred_real_bands_yaw; b++ ) + FOR( ; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } #endif - for ( b = 0; b < d_bands_yaw; b++ ) + FOR( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } - else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + ELSE IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], PITCH_ONLY ) ) { - for ( b = 0; b < bands_pitch; b++ ) + FOR( b = 0; b < bands_pitch; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len ); @@ -1175,29 +1978,29 @@ static void isar_SplitRenderer_code_md_huff( ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } - else + ELSE { #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - for ( b = 0; b < pred_real_bands_roll; b++ ) + FOR( b = 0; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } } - for ( b = 0; b < pred_imag_bands_roll; b++ ) + FOR( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); @@ -1205,13 +2008,13 @@ static void isar_SplitRenderer_code_md_huff( } } #else - for ( b = 0; b < pred_imag_bands_roll; b++ ) + FOR( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); @@ -1219,21 +2022,20 @@ static void isar_SplitRenderer_code_md_huff( } isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } } - - for ( ; b < pred_real_bands_roll; b++ ) + FOR( ; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch1], &code, &len ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); @@ -1253,7 +2055,7 @@ static void isar_SplitRenderer_code_md_huff( cntr++; num_bits += pBits->bits_written; /* collect bits for every second */ - if ( cntr == 50 ) + IF( cntr == 50 ) { cntr = 0; fnum_bits = (float) num_bits / 1000.0f; @@ -1265,41 +2067,45 @@ static void isar_SplitRenderer_code_md_huff( return; } - static void isar_SplitRenderer_quant_code( const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, const IVAS_QUATERNION headPosition, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int16_t low_res_pre_rend_rot, + const Word16 low_res_pre_rend_rot, #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS const int16_t ro_md_flag, #endif - const int32_t target_md_bits ) + const Word32 target_md_bits, + Word16 Q_frame ) { #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - int16_t q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; + Word16 q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; #else - int16_t num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; -#endif - int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit; - int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - int32_t base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; +#endif + Word32 overhead_bits, quant_strat_bits, huff_bits, start_bit; + Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 pred_1byquantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 pred_quantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; +#ifdef DEBUG_QUANT_MD_FX float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; +#endif ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - int16_t rot_axis_code, num_bits; + Word16 rot_axis_code, num_bits; #endif - if ( low_res_pre_rend_rot ) + IF( low_res_pre_rend_rot ) { num_subframes = 1; } - else + ELSE { num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; } @@ -1320,90 +2126,122 @@ static void isar_SplitRenderer_quant_code( #endif /* code ref pose*/ - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - int16_t angle; + Word16 angle; IVAS_QUATERNION head_pos_euler; - Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x ); - angle = (int16_t) roundf( head_pos_euler.x ); - angle += 180; + Quat2EulerDegree_fx( headPosition, &head_pos_euler.z_fx, &head_pos_euler.y_fx, &head_pos_euler.x_fx ); + angle = (Word16) L_shr_r( head_pos_euler.x_fx, Q22 ); + angle = add( angle, 180 ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); - angle = (int16_t) roundf( head_pos_euler.y ); - angle += 180; + angle = (Word16) L_shr_r( head_pos_euler.y_fx, Q22 ); + angle = add( angle, 180 ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); - angle = (int16_t) roundf( head_pos_euler.z ); - angle += 180; + angle = (Word16) L_shr_r( head_pos_euler.z_fx, Q22 ); + angle = add( angle, 180 ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); } #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, - pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw, - d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats ); + isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, + pred_quant_pnts_yaw, pred_quantstep_yaw_fx, pred_1byquantstep_yaw_fx, + d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats ); #else - isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, - pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw, - d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, &num_quant_strats, &num_complex_bands ); + isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, + pred_quant_pnts_yaw, pred_quantstep_yaw_fx, pred_1byquantstep_yaw_fx, + d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, &num_quant_strats, &num_complex_bands ); +#endif +#ifdef DEBUG_QUANT_MD_FX + fixedToFloat_arrL( pred_quantstep_yaw_fx, pred_quantstep_yaw, Q31, ISAR_SPLIT_REND_NUM_QUANT_STRATS ); + fixedToFloat_arrL( pred_1byquantstep_yaw_fx, pred_1byquantstep_yaw, Q26, ISAR_SPLIT_REND_NUM_QUANT_STRATS ); #endif - quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); - overhead_bits = pBits->bits_written - overhead_bits + quant_strat_bits + 1; /* 1 for base2 vs huff */ + quant_strat_bits = ceil_log_2( num_quant_strats ); + + overhead_bits = L_add( L_add( L_sub( pBits->bits_written, overhead_bits ), quant_strat_bits ), 1 ); /* 1 for base2 vs huff */ get_base2_bits( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, num_quant_strats, pred_real_bands_yaw, pred_imag_bands_yaw, pred_quant_pnts_yaw, d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits ); - for ( q = 0; q < num_quant_strats; q++ ) + FOR( q = 0; q < num_quant_strats; q++ ) { - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) { - if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + IF( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) { - for ( b = 0; b < pred_imag_bands_yaw[q]; b++ ) + FOR( b = 0; b < pred_imag_bands_yaw[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - - isar_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); + isar_split_rend_quant_md_fx( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], pred_1byquantstep_yaw_fx[q], Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] +#endif + ); } - for ( ; b < pred_real_bands_yaw[q]; b++ ) + FOR( ; b < pred_real_bands_yaw[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - - isar_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); + isar_split_rend_quant_md_fx( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], pred_1byquantstep_yaw_fx[q], Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] +#endif + ); } - for ( b = 0; b < d_bands_yaw[q]; b++ ) + FOR( b = 0; b < d_bands_yaw[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - - isar_split_rend_quant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); + isar_split_rend_quant_md_fx( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], 0, Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0.0f +#endif + ); } } - else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + ELSE IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) { - for ( b = 0; b < bands_pitch[q]; b++ ) + FOR( b = 0; b < bands_pitch[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); + isar_split_rend_quant_md_fx( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], 0, Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0.0f +#endif + ); } } - else + ELSE { - for ( b = 0; b < pred_imag_bands_roll[q]; b++ ) + FOR( b = 0; b < pred_imag_bands_roll[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); + isar_split_rend_quant_md_fx( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26, Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP +#endif + ); } - for ( ; b < pred_real_bands_roll[q]; b++ ) + FOR( ; b < pred_real_bands_roll[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - isar_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); + isar_split_rend_quant_md_fx( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26, Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP +#endif + ); } } } @@ -1429,11 +2267,13 @@ static void isar_SplitRenderer_quant_code( pred_imag_bands_roll[q], pBits ); - huff_bits = pBits->bits_written - huff_bits; - - if ( ( target_md_bits >= ( base2bits[q] + overhead_bits ) ) || ( target_md_bits >= ( huff_bits + overhead_bits ) ) || ( q == ( num_quant_strats - 1 ) ) ) + huff_bits = L_sub( pBits->bits_written, huff_bits ); + test(); + test(); + test(); + IF( GE_32( target_md_bits, ( base2bits[q] + overhead_bits ) ) || GE_32( target_md_bits, ( huff_bits + overhead_bits ) ) || EQ_16( q, sub( num_quant_strats, 1 ) ) ) { - if ( huff_bits > base2bits[q] ) + IF( GT_32( huff_bits, base2bits[q] ) ) { pBits->bits_written = start_bit; @@ -1444,7 +2284,7 @@ static void isar_SplitRenderer_quant_code( pred_quant_pnts_yaw[q], d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); } - break; + BREAK; } pBits->bits_written = start_bit; @@ -1529,83 +2369,104 @@ static void isar_SplitRenderer_quant_code( return; } - - /*------------------------------------------------------------------------- * Function isar_SplitRenderer_GetRotMd() * * *------------------------------------------------------------------------*/ -static void isar_SplitRenderer_GetRotMd( +static Word16 imult1616( Word16 x, Word16 y ) +{ + assert( (int) x * (int) y < 32768 && (int) x * (int) y >= -32768 ); + return extract_l( L_mult0( x, y ) ); +} + +static void isar_SplitRenderer_GetRotMd_fx( ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ - float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ - const int16_t low_res, - const int16_t ro_md_flag ) + Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + Word16 exp_cldfb_re, + Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + Word16 exp_cldfb_im, + const Word16 low_res, + const Word16 ro_md_flag ) { - float cov_ii_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_oo_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_io_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_ii_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_oo_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float cov_io_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - int16_t real_only = 0; - int16_t pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes, ch_s_idx1, ch_s_idx2; - int16_t num_md_bands, num_poses; - const int16_t *pBand_grouping = isar_split_rend_band_grouping; - - push_wmops( "isar_SplitRenderer_GetRotMd" ); + Word32 cov_ii_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_oo_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_io_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_ii_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_oo_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_io_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word16 exp_cov_io_re = 0, exp_cov_io_im = 0; + Word16 exp_cov_ii_re = 0, exp_cov_ii_im = 0; + Word16 exp_cov_oo_re = 0, exp_cov_oo_im = 0; + + Word16 real_only = 0; + Word16 pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes, ch_s_idx1, ch_s_idx2; + Word16 num_md_bands, num_poses; + const Word16 *pBand_grouping = isar_split_rend_band_grouping; + + push_wmops( "isar_SplitRenderer_GetRotMd_fx" ); num_md_bands = MAX_SPLIT_REND_MD_BANDS; + move16(); num_poses = pMultiBinPoseData->num_poses; + move16(); - if ( low_res ) + IF( low_res ) { num_slots = CLDFB_NO_COL_MAX; + move16(); num_subframes = 1; + move16(); } - else + ELSE { num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); } /* compute reference signal covariance */ - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - start_slot_idx = sf_idx * num_slots; - for ( b = 0; b < num_md_bands; b++ ) + start_slot_idx = imult1616( sf_idx, num_slots ); + FOR( b = 0; b < num_md_bands; b++ ) { - if ( ( b < SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) ) + test(); + IF( LT_16( b, SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) ) { real_only = 0; + move16(); } - else + ELSE { real_only = 1; + move16(); } ch_s_idx1 = 0; - ComputeBandedCov( Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx1, cov_ii_re, cov_ii_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); + + ComputeBandedCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx1, cov_ii_re_fx, &exp_cov_ii_re, cov_ii_im_fx, &exp_cov_ii_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); /* compute rotated signal covariance */ - for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) { - if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL ) + IF( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL ) { - if ( b >= SPLIT_REND_RO_MD_BAND_THRESH ) + IF( GE_16( b, SPLIT_REND_RO_MD_BAND_THRESH ) ) { real_only = 1; } } - ch_s_idx2 = ( pos_idx + 1 ) * BINAURAL_CHANNELS; - ComputeBandedCrossCov( Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx1, Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx2, cov_io_re, cov_io_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); + ch_s_idx2 = imult1616( add( pos_idx, 1 ), BINAURAL_CHANNELS ); - ComputeBandedCov( Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx2, cov_oo_re, cov_oo_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); + ComputeBandedCrossCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx1, Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx2, cov_io_re_fx, &exp_cov_io_re, cov_io_im_fx, &exp_cov_io_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); - ComputeCoeffs( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re, &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b], hBinHrSplitPreRend->pose_type[pos_idx], real_only ); + ComputeBandedCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx2, cov_oo_re_fx, &exp_cov_oo_re, cov_oo_im_fx, &exp_cov_oo_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); + + ComputeCoeffs_fx( cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, cov_oo_re_fx, exp_cov_oo_re, &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b], hBinHrSplitPreRend->pose_type[pos_idx], real_only ); } } } @@ -1613,35 +2474,183 @@ static void isar_SplitRenderer_GetRotMd( pop_wmops(); return; } - - /*------------------------------------------------------------------------- * Function isar_rend_CldfbSplitPreRendProcess() * * *------------------------------------------------------------------------*/ - void isar_rend_CldfbSplitPreRendProcess( const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, const IVAS_QUATERNION headPosition, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re, + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im, ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t target_md_bits, - const int16_t low_res_pre_rend_rot, - const int16_t ro_md_flag ) + const Word32 target_md_bits, + const Word16 low_res_pre_rend_rot, + const Word16 ro_md_flag ) { push_wmops( "isar_rend_CldfbSplitPreRendProcess" ); - isar_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag ); + isar_SplitRenderer_GetRotMd_fx( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, low_res_pre_rend_rot, ro_md_flag ); + + Word16 num_md_bands, num_poses; + Word16 pos_idx, b, sf_idx, num_subframes; + + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + num_poses = pMultiBinPoseData->num_poses; + + IF( low_res_pre_rend_rot ) + { + num_subframes = 1; + } + ELSE + { + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + + /*FILE *filePointer_gd, *filePointer_gd2; + FILE *filePointer_re, *filePointer_im; + filePointer_gd = fopen("Fixed_code_cov_gd_complete.txt", "a"); + filePointer_gd2 = fopen("Fixed_code_cov_gd2_complete.txt", "a"); + filePointer_re = fopen("Fixed_code_re_complete.txt", "a"); + filePointer_im = fopen("Fixed_code_im_complete.txt", "a");*/ + +#ifdef DUMP_GETROTMD_OUTPUT + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( b = 0; b < num_md_bands; b++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd ); + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2 = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 ); + /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd); + fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/ + } + else + { + for ( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i][j], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re ); + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i][j], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im ); + /*fprintf(filePointer_re, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j]); + fprintf(filePointer_im, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j]);*/ + } + } + } + } + } + } +#endif + + /*fclose(filePointer_gd); + fclose(filePointer_gd2); + fclose(filePointer_re); + fclose(filePointer_im);*/ + + /* Check if rescaling can be simplified/avoid */ + Word16 exp_frame = 0; + // Word32 L_temp_max = 0; + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( b = 0; b < num_md_bands; b++ ) + { + FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd ); + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 ); + } + ELSE + { + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re ); #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits ); -#else - isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits ); + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re2 ); #endif + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im ); + } + } + } + } + // exp_frame = s_min( exp_frame, sub( 31, norm_l( L_temp_max ) ) ); + exp_frame = s_min( exp_frame, 15 ); // Considering the max value as of prediction matrices as 300 + Word16 Q_frame = sub( Q31, exp_frame ); + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( b = 0; b < num_md_bands; b++ ) + { + FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx = L_shr_r( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, sub( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd ) ); + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx = L_shr_r( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, sub( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 ) ); + /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd); + fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/ + } + ELSE + { + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i], BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re, exp_frame ) ); + Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i], BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im, exp_frame ) ); + } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re2, BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re2, exp_frame ) ); +#endif + } + } + } + } + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits, Q_frame ); +#else + isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits, Q_frame ); +#endif +#ifdef DEBUG_QUANT_CODE_OUT + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( b = 0; b < num_md_bands; b++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd = fixedToFloat( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, Q_frame ); + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2 = fixedToFloat( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, Q_frame ); + /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd); + fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/ + } + else + { + for ( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + fixedToFloat_arrL( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i], Q_frame, BINAURAL_CHANNELS ); + fixedToFloat_arrL( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i], Q_frame, BINAURAL_CHANNELS ); + // for ( int j = 0; j < BINAURAL_CHANNELS; j++ ) + //{ + // hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i][j], Q6 ); + // hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i][j], Q6 ); + // /*fprintf(filePointer_re, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j]); + // fprintf(filePointer_im, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j]);*/ + // } + } + } + } + } + } +#endif #ifdef SPLIT_POSE_CORRECTION_DEBUG float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv; IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], head_pos_euler; @@ -1737,13 +2746,11 @@ void isar_rend_CldfbSplitPreRendProcess( return; } - /*------------------------------------------------------------------------- * Function isar_splitBinPreRendOpen() * * *------------------------------------------------------------------------*/ - ivas_error isar_splitBinPreRendOpen( ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData @@ -1758,9 +2765,9 @@ ivas_error isar_splitBinPreRendOpen( ivas_error error; int16_t ch; #endif - int16_t pos_idx, sf_idx, bandIdx; + Word16 pos_idx, sf_idx, bandIdx; - if ( ( hBinRend = (ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_PRE_REND ) ) ) == NULL ) + IF( ( hBinRend = (ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_PRE_REND ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) ); } @@ -1786,20 +2793,18 @@ ivas_error isar_splitBinPreRendOpen( } #endif - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) { - for ( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ ) { - for ( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ ) + FOR( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ ) { - hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd = 0.0f; + hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd_fx = 0; } } } - - set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); - - set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); + set_fix_rotation_mat_fx( hBinRend->fix_pos_rot_mat_fx, pMultiBinPoseData ); + set_pose_types_fx( hBinRend->pose_type, pMultiBinPoseData ); isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); @@ -1816,7 +2821,6 @@ ivas_error isar_splitBinPreRendOpen( return IVAS_ERR_OK; } - /*------------------------------------------------------------------------- * Function isar_splitBinPreRendClose() * @@ -1826,16 +2830,16 @@ ivas_error isar_splitBinPreRendOpen( void isar_splitBinPreRendClose( ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ) { - if ( ( *hBinHrSplitPreRend ) != NULL ) + IF( ( *hBinHrSplitPreRend ) != NULL ) { #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG { - int16_t i, n; - for ( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + Word16 i, n; + FOR( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) { - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + FOR( n = 0; n < BINAURAL_CHANNELS; n++ ) { - if ( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL ) + IF( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL ) { deleteCldfb( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) ); ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL; @@ -1861,24 +2865,24 @@ void isar_splitBinPreRendClose( * * *-------------------------------------------------------------------------*/ - -void isar_set_split_rend_ht_setup( +void isar_set_split_rend_ht_setup_fx( SPLIT_REND_WRAPPER *hSplitrend, IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], - float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ) + Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ) { - int16_t sf, i, j; - if ( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + Word16 sf, i, j; + IF( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { - for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) { Quaternions[sf] = Quaternions[0]; - for ( i = 0; i < 3; i++ ) + FOR( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) + FOR( j = 0; j < 3; j++ ) { - Rmat[sf][i][j] = Rmat[0][i][j]; + Rmat_fx[sf][i][j] = Rmat_fx[0][i][j]; + move32(); } } } @@ -1887,7 +2891,6 @@ void isar_set_split_rend_ht_setup( return; } - /*------------------------------------------------------------------------- * Function isar_init_split_rend_handles() * @@ -1897,24 +2900,27 @@ void isar_set_split_rend_ht_setup( void isar_init_split_rend_handles( SPLIT_REND_WRAPPER *hSplitRendWrapper ) { - int16_t i; + Word16 i; hSplitRendWrapper->hBinHrSplitPreRend = NULL; hSplitRendWrapper->hCldfbHandles = NULL; hSplitRendWrapper->hSplitBinLCLDEnc = NULL; hSplitRendWrapper->hLc3plusEnc = NULL; - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) { hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL; + hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = NULL; } hSplitRendWrapper->lc3plusDelaySamples = 0; + move32(); - isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + isar_init_multi_bin_pose_data_fx_enc( &hSplitRendWrapper->multiBinPoseData ); return; } + /*------------------------------------------------------------------------- * Function split_renderer_open_lc3plus() * @@ -1924,7 +2930,7 @@ void isar_init_split_rend_handles( ivas_error split_renderer_open_lc3plus( SPLIT_REND_WRAPPER *hSplitRendWrapper, const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t OutSampleRate, + const Word32 OutSampleRate, #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS const IVAS_RENDER_FRAMESIZE isar_frame_size #else @@ -1933,7 +2939,7 @@ ivas_error split_renderer_open_lc3plus( ) { ivas_error error; - int16_t i, delayBufferLength; + Word16 i, delayBufferLength; LC3PLUS_CONFIG config; #if defined ISAR_BITSTREAM_UPDATE_LC3PLUS int16_t isar_frame_size_ms; @@ -1943,7 +2949,6 @@ ivas_error split_renderer_open_lc3plus( return error; } #endif - #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS /* Check configuration validity */ if ( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms ) @@ -1954,14 +2959,12 @@ ivas_error split_renderer_open_lc3plus( config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS - config.isar_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; + config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; #endif config.samplerate = OutSampleRate; - #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS config.isar_frame_duration_us = isar_frame_size_ms * 1000; #endif - #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 ); #endif @@ -1979,41 +2982,55 @@ ivas_error split_renderer_open_lc3plus( } /* This returns delay of entire LC3plus chain (enc + dec) */ - if ( ( error = ISAR_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK ) + IF( ( error = ISAR_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK ) { return error; } /* Alocate buffers for delay compensation */ - if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + IF( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) { - delayBufferLength = (int16_t) ( OutSampleRate / (int32_t) FRAMES_PER_SECOND + hSplitRendWrapper->lc3plusDelaySamples ); - for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) + delayBufferLength = (Word16) ( OutSampleRate / (int32_t) FRAMES_PER_SECOND + hSplitRendWrapper->lc3plusDelaySamples ); + FOR( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) { - if ( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL ) + IF( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) ); } set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], delayBufferLength ); + IF( ( hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = malloc( delayBufferLength * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) ); + } + + set32_fx( hSplitRendWrapper->lc3plusDelayBuffers_fx[i], 0, delayBufferLength ); } + hSplitRendWrapper->lc3plusDelayBuffers_q = 31; } - else + ELSE { /* Delay is always expected to be exactly 2 CLDFB columns */ assert( hSplitRendWrapper->lc3plusDelaySamples % ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 0 ); assert( hSplitRendWrapper->lc3plusDelaySamples / ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 2 ); delayBufferLength = 2 /* Columns */ * 2 /* real and imag */ * CLDFB_NO_CHANNELS_MAX; - for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) + FOR( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) { - if ( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL ) + IF( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) ); } set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], delayBufferLength ); + IF( ( hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = malloc( delayBufferLength * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) ); + } + + set32_fx( hSplitRendWrapper->lc3plusDelayBuffers_fx[i], 0, delayBufferLength ); } + hSplitRendWrapper->lc3plusDelayBuffers_q = 31; } return IVAS_ERR_OK; @@ -2025,7 +3042,6 @@ ivas_error split_renderer_open_lc3plus( * * *------------------------------------------------------------------------*/ - ivas_error splitRendLc3plusEncodeAndWrite( SPLIT_REND_WRAPPER *hSplitBin, ISAR_SPLIT_REND_BITS_HANDLE pBits, @@ -2036,12 +3052,14 @@ ivas_error splitRendLc3plusEncodeAndWrite( #else const int32_t SplitRendBitRate, #endif - float *in[] ) + Word32 *in[], + Word16 Q_sig ) { ivas_error error; int16_t i; int32_t lc3plusBitstreamSize; - float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + Word32 *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + Word16 Q_in[16]; assert( hSplitBin->hLc3plusEnc != NULL ); /* Find next byte boundary and zero-pad to it */ @@ -2070,10 +3088,11 @@ ivas_error splitRendLc3plusEncodeAndWrite( #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS ISAR_SPLIT_REND_BITStream_write_int32( pBits, isar_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 ); #endif - /* Write bitstream */ #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) + set16_fx( Q_in, Q_sig, 16 ); + move16(); + if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize, Q_in ) ) != IVAS_ERR_OK ) #else if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) #endif @@ -2091,40 +3110,48 @@ ivas_error splitRendLc3plusEncodeAndWrite( return IVAS_ERR_OK; } + /*------------------------------------------------------------------------- * Function isar_renderMultiTDBinToSplitBinaural() * * *------------------------------------------------------------------------*/ - ivas_error isar_renderMultiTDBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, + const Word32 SplitRendBitRate, #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS const int16_t isar_frame_size_ms, #endif - const int16_t codec_frame_size_ms, + const Word16 codec_frame_size_ms, ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int16_t max_bands, - float *in[], - const int16_t low_res_pre_rend_rot, - const int16_t pcm_out_flag, - const int16_t ro_md_flag ) + const Word16 max_bands, + // float *in[], + Word32 *in_fx[], // Q11 + Word16 Q_sig, + const Word16 low_res_pre_rend_rot, + const Word16 pcm_out_flag, + const Word16 ro_md_flag ) { ivas_error error; #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - int32_t bit_len, available_bits, target_md_bits; + int32_t bit_len, available_bits, target_md_bits, tmp_32; #else - int32_t bit_len, available_bits, target_md_bits, actual_md_bits; + Word32 bit_len, available_bits, target_md_bits, actual_md_bits, tmp_32; #endif - int16_t num_cldfb_bands, ch, slot_idx, pos_idx, num_poses; - float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - uint8_t useLc3plus; - float *in_delayed[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; - int16_t i; - int32_t num_slots; + Word16 num_cldfb_bands, ch, slot_idx, pos_idx, num_poses; + Word16 tmp, tmp_e; + Word32 Cldfb_In_BinReal_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 Cldfb_In_BinImag_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word16 Q_in = Q_sig, q_final = 0; + move16(); + move16(); + // float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + // float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + UWord8 useLc3plus; + Word32 *in_delayed_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; + Word16 i; + Word32 num_slots; push_wmops( "isar_renderMultiTDBinToSplitBinaural" ); @@ -2133,37 +3160,55 @@ ivas_error isar_renderMultiTDBinToSplitBinaural( useLc3plus = hSplitBin->hLc3plusEnc != NULL; - if ( useLc3plus ) + IF( useLc3plus ) { /*this should always have the time resolution of pose correction MD. Note that this does not change frame size of LC3plus*/ - int16_t frame_size = (int16_t) ( hSplitBin->hLc3plusEnc->config.samplerate / (int32_t) FRAMES_PER_SECOND ); - - for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + // Word16 frame_size = (Word16) ( hSplitBin->hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND ); + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.samplerate, FRAMES_PER_SECOND_FX, &tmp_e ); + Word16 frame_size = shr( tmp, sub( 15, tmp_e ) ); // Q0 + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) { /* Artificially delay input to head pose correction analysis by LC3plus coding delay, so that audio and metadata are in sync after decoding */ - mvr2r( hSplitBin->lc3plusDelayBuffers[i] + frame_size, hSplitBin->lc3plusDelayBuffers[i], (int16_t) hSplitBin->lc3plusDelaySamples ); - in_delayed[i] = hSplitBin->lc3plusDelayBuffers[i]; - mvr2r( in[i], hSplitBin->lc3plusDelayBuffers[i] + hSplitBin->lc3plusDelaySamples, frame_size ); + mvl2l( hSplitBin->lc3plusDelayBuffers_fx[i] + frame_size, hSplitBin->lc3plusDelayBuffers_fx[i], (Word16) hSplitBin->lc3plusDelaySamples ); + // mvr2r( hSplitBin->lc3plusDelayBuffers[i] + frame_size, hSplitBin->lc3plusDelayBuffers[i], (int16_t) hSplitBin->lc3plusDelaySamples ); + in_delayed_fx[i] = hSplitBin->lc3plusDelayBuffers_fx[i]; + // in_delayed[i] = hSplitBin->lc3plusDelayBuffers[i]; + mvl2l( in_fx[i], hSplitBin->lc3plusDelayBuffers_fx[i] + hSplitBin->lc3plusDelaySamples, frame_size ); + // mvr2r(in[i], hSplitBin->lc3plusDelayBuffers[i] + hSplitBin->lc3plusDelaySamples, frame_size); } } - else + ELSE { - for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) { - in_delayed[i] = in[i]; + in_delayed_fx[i] = in_fx[i]; + move32(); } } #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS actual_md_bits = pBits->bits_written; + move32(); #endif - if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) + + test(); + test(); + IF( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) { + Word32 in_delayed_cldfb[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k] = { 0 }; + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ ) + { + Copy32( in_delayed_fx[i], in_delayed_cldfb[i], L_FRAME48k ); + Scale_sig32( in_delayed_cldfb[i], L_FRAME48k, -4 ); + } + Q_sig = sub( Q_sig, 4 ); num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ); + move32(); num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; - + move16(); /* CLDFB Analysis*/ - for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { #ifdef SPLIT_POSE_CORRECTION_DEBUG { @@ -2181,93 +3226,153 @@ ivas_error isar_renderMultiTDBinToSplitBinaural( } #endif - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + HANDLE_CLDFB_FILTER_BANK temp_cldfbAna = hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]; + Scale_sig32( temp_cldfbAna->cldfb_state_fx, + sub( temp_cldfbAna->p_filter_length, temp_cldfbAna->no_channels ), sub( Q_sig, temp_cldfbAna->Q_cldfb_state ) ); + temp_cldfbAna->Q_cldfb_state = Q_sig; + move16(); + FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) { - cldfbAnalysis_ts( &( in_delayed[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ), - Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], - max_bands, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch] ); + Word16 Q_cldfb = Q_sig; + // floatToFixed_arrL(hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state_fx, Q_output, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->p_filter_length - hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->no_channels); + cldfbAnalysis_ts_fx_fixed_q( &( in_delayed_cldfb[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ), + Cldfb_In_BinReal_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], + Cldfb_In_BinImag_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], + max_bands, + temp_cldfbAna, + &Q_cldfb ); + /*fixedToFloat_arrL(hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state, Q_output, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->p_filter_length - hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->no_channels); + fixedToFloat_arrL(Cldfb_In_BinReal_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Q_cldfb, max_bands); + fixedToFloat_arrL(Cldfb_In_BinImag_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Q_cldfb, max_bands);*/ + /*for (int k = 0; k < max_bands; k++) { + printf("\n%f %f ", Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx][k], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx][k]); + }*/ } } } + q_final = sub( Q_sig, 5 ); } - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { - target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + // target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + target_md_bits = W_extract_l( W_mult0_32_32( isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ), L_FRAME48k ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( target_md_bits, 48000, &tmp_e ); + target_md_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS actual_md_bits = pBits->bits_written; #endif - - isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); + /*scaling to max Q*/ + Word16 scale_factor = 31; + move32(); + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + scale_factor = s_min( scale_factor, s_min( getScaleFactor32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ) ); + } + } + scale_factor = sub( scale_factor, 2 ); + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, scale_factor ); + Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, scale_factor ); + } + } + q_final = add( q_final, scale_factor ); + Word16 exp_cldfb_re = sub( 31, q_final ); + Word16 exp_cldfb_im = sub( 31, q_final ); + isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); } - if ( pcm_out_flag == 0 ) + IF( EQ_16( pcm_out_flag, 0 ) ) { pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; pBits->codec = useLc3plus ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD; - if ( !useLc3plus ) + IF( !useLc3plus ) { - available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + // available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + available_bits = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( available_bits, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e ); + available_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - available_bits -= pBits->bits_written; + available_bits = L_sub( available_bits, pBits->bits_written ); #else - actual_md_bits = pBits->bits_written - actual_md_bits; - available_bits -= actual_md_bits; + actual_md_bits = L_sub( pBits->bits_written, actual_md_bits ); + available_bits = L_sub( available_bits, actual_md_bits ); #endif pBits->codec_frame_size_ms = codec_frame_size_ms; + move16(); #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS pBits->isar_frame_size_ms = isar_frame_size_ms; + move16(); #endif - - isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); + isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, available_bits, pBits, &q_final ); } - else + ELSE { #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS -#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in ) ) != IVAS_ERR_OK ) -#else available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, in ) ) != IVAS_ERR_OK ) -#endif + IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in_fx, Q_in ) ) != IVAS_ERR_OK ) + { + return error; + } #else - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK ) -#endif + IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in_flt ) ) != IVAS_ERR_OK ) { return error; } +#endif } } - else + ELSE { pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; pBits->codec = ISAR_SPLIT_REND_CODEC_NONE; } /*zero pad*/ - if ( pcm_out_flag ) + IF( pcm_out_flag ) { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( SplitRendBitRate, FRAMES_PER_SEC, &tmp_e ); + bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0 + // bit_len = SplitRendBitRate / FRAMES_PER_SEC; } - else + ELSE { - if ( !useLc3plus ) + IF( !useLc3plus ) { - bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + // bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + + bit_len = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( bit_len, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e ); + bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 } - else + ELSE { - bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; - bit_len = SplitRendBitRate * bit_len / 1000; + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( (Word32) hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e ); + bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0 + // bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + // bit_len = SplitRendBitRate * bit_len / 1000; + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_mult0_32_32( SplitRendBitRate, bit_len ) ), 1000, &tmp_e ); + bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 } } - while ( pBits->bits_written < bit_len ) + + WHILE( LT_32( pBits->bits_written, bit_len ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); } @@ -2277,64 +3382,88 @@ ivas_error isar_renderMultiTDBinToSplitBinaural( return error; } - /*------------------------------------------------------------------------- * Function lc3plusTimeAlignCldfbPoseCorr() * * *------------------------------------------------------------------------*/ - void lc3plusTimeAlignCldfbPoseCorr( SPLIT_REND_WRAPPER *hSplitBin, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_in ) { - float Cldfb_In_BinReal_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_In_BinImag_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; - int16_t pose, ch, slot_idx; - float *bufRead, *bufWrite; + Word32 Cldfb_In_BinReal_tmp_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_In_BinImag_tmp_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; + Word16 pose, ch, slot_idx; + Word32 *bufRead_fx, *bufWrite_fx; + + IF( GT_16( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) ) + { + // hSplitBin->lc3plusDelayBuffers_q[0] = *Q_in; + FOR( Word16 i = 0; i < hSplitBin->multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ ) + { + + Scale_sig32( hSplitBin->lc3plusDelayBuffers_fx[i], 4 * CLDFB_NO_CHANNELS_MAX, sub( *Q_in, hSplitBin->lc3plusDelayBuffers_q ) ); + } + hSplitBin->lc3plusDelayBuffers_q = *Q_in; + } + ELSE + { + FOR( Word16 i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + for ( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) ); + Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) ); + } + } + *Q_in = hSplitBin->lc3plusDelayBuffers_q; + } - for ( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose ) + FOR( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose ) { - for ( ch = 0; ch < BINAURAL_CHANNELS; ++ch ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ++ch ) { - bufRead = hSplitBin->lc3plusDelayBuffers[pose * BINAURAL_CHANNELS + ch]; - bufWrite = bufRead; + bufRead_fx = hSplitBin->lc3plusDelayBuffers_fx[pose * BINAURAL_CHANNELS + ch]; + bufWrite_fx = bufRead_fx; /* Save last 2 columns for next frame */ - for ( slot_idx = 0; slot_idx < 2; ++slot_idx ) + FOR( slot_idx = 0; slot_idx < 2; ++slot_idx ) { - mvr2r( Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinReal_tmp[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinImag_tmp[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + Copy32( Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinReal_tmp_fx[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + Copy32( Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinImag_tmp_fx[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); } /* Delay existing columns by 2 slots */ - for ( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx ) + /*TODO : shouldnt the delay be 7.5 ms ? 5ms + LC3plus delay */ + FOR( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx ) { - mvr2r( Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); + Copy32( Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); + Copy32( Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); } /* Fill 2 first columns from buffer */ - for ( slot_idx = 0; slot_idx < 2; ++slot_idx ) + FOR( slot_idx = 0; slot_idx < 2; ++slot_idx ) { - mvr2r( bufRead, Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); - bufRead += CLDFB_NO_CHANNELS_MAX; - mvr2r( bufRead, Cldfb_In_BinImag[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); - bufRead += CLDFB_NO_CHANNELS_MAX; + Copy32( bufRead_fx, Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + bufRead_fx += CLDFB_NO_CHANNELS_MAX; + Copy32( bufRead_fx, Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + bufRead_fx += CLDFB_NO_CHANNELS_MAX; } /* Copy last 2 columns to buffer */ - for ( slot_idx = 0; slot_idx < 2; ++slot_idx ) + FOR( slot_idx = 0; slot_idx < 2; ++slot_idx ) { - mvr2r( Cldfb_In_BinReal_tmp[pose][ch][slot_idx], bufWrite, CLDFB_NO_CHANNELS_MAX ); - bufWrite += CLDFB_NO_CHANNELS_MAX; - mvr2r( Cldfb_In_BinImag_tmp[pose][ch][slot_idx], bufWrite, CLDFB_NO_CHANNELS_MAX ); - bufWrite += CLDFB_NO_CHANNELS_MAX; + Copy32( Cldfb_In_BinReal_tmp_fx[pose][ch][slot_idx], bufWrite_fx, CLDFB_NO_CHANNELS_MAX ); + bufWrite_fx += CLDFB_NO_CHANNELS_MAX; + Copy32( Cldfb_In_BinImag_tmp_fx[pose][ch][slot_idx], bufWrite_fx, CLDFB_NO_CHANNELS_MAX ); + bufWrite_fx += CLDFB_NO_CHANNELS_MAX; } } } return; } + #endif diff --git a/lib_isar/isar_splitRenderer_utils.c b/lib_isar/isar_splitRenderer_utils.c index eff0ecdae..b290ca12a 100644 --- a/lib_isar/isar_splitRenderer_utils.c +++ b/lib_isar/isar_splitRenderer_utils.c @@ -35,22 +35,152 @@ #ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "ivas_prot.h" +#include "prot.h" +#include "cnst.h" +#include "isar_cnst.h" +#include "ivas_rom_rend.h" +#include "ivas_rom_com.h" #include "isar_rom_post_rend.h" +#include "ivas_rom_binauralRenderer.h" #include "lib_isar_post_rend.h" #include "isar_prot.h" #ifdef DEBUGGING #include "debug.h" #endif #include "wmc_auto.h" +#include "basop_settings.h" +#include "prot_fx2.h" + +#include "basop_util.h" /*------------------------------------------------------------------------- - * Function isar_mat_mult_2by2_complex() + * Function ivas_mat_mult_2by2_complex() * * *------------------------------------------------------------------------*/ +void ivas_cmult_fix( Word32 in1_re_fx, Word16 exp_re1, Word32 in1_im_fx, Word16 exp_im1, Word32 in2_re_fx, Word16 exp_re2, Word32 in2_im_fx, Word16 exp_im2, Word32 *out1_re_fx, Word32 *out1_im_fx, Word16 *exp_out1_re, Word16 *exp_out1_im ) +{ + Word16 shift_1 = W_norm( W_mult_32_32( in1_re_fx, in2_re_fx ) ); + Word16 shift_2 = W_norm( W_mult_32_32( in1_im_fx, in2_im_fx ) ); + Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( in1_re_fx, in2_re_fx ), shift_1 ) ); + Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( in1_im_fx, in2_im_fx ), shift_2 ) ); + Word16 exp_tmp1 = 0; + move16(); + *out1_re_fx = BASOP_Util_Add_Mant32Exp( tmp1, exp_re1 + exp_re2 - shift_1, L_negate( tmp2 ), exp_im1 + exp_im2 - shift_2, &exp_tmp1 ); + *exp_out1_re = exp_tmp1; + Word16 shift_3 = W_norm( W_mult_32_32( in1_re_fx, in2_im_fx ) ); + Word16 shift_4 = W_norm( W_mult_32_32( in2_re_fx, in1_im_fx ) ); + Word32 tmp3 = W_extract_h( W_shl( W_mult_32_32( in1_re_fx, in2_im_fx ), shift_3 ) ); + Word32 tmp4 = W_extract_h( W_shl( W_mult_32_32( in2_re_fx, in1_im_fx ), shift_4 ) ); + Word16 exp_tmp2 = 0; + move16(); + *out1_im_fx = BASOP_Util_Add_Mant32Exp( tmp3, exp_re1 + exp_im2 - shift_3, tmp4, exp_re2 + exp_im1 - shift_4, &exp_tmp2 ); + *exp_out1_im = exp_tmp2; + move16(); +} + +void ivas_calculate_abs_fx( Word32 re_fx, Word16 exp_re, Word32 im_fx, Word16 exp_im, Word32 *out_fx, Word16 *exp_out ) +{ + Word16 shift_1 = W_norm( W_mult_32_32( re_fx, re_fx ) ); + Word16 shift_2 = W_norm( W_mult_32_32( im_fx, im_fx ) ); + Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( re_fx, re_fx ), shift_1 ) ); + Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( im_fx, im_fx ), shift_2 ) ); + Word16 exp_tmp1 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1, exp_re + exp_re - shift_1, tmp2, exp_im + exp_im - shift_2, &exp_tmp1 ); + *out_fx = Sqrt32( tmp3, &exp_tmp1 ); + *exp_out = exp_tmp1; +} + +void ivas_calculate_rabs_fx( Word32 re_fx, Word16 exp_re, Word32 *out_fx, Word16 *exp_out ) +{ + Word16 shift_1 = W_norm( W_mult_32_32( re_fx, re_fx ) ); + Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( re_fx, re_fx ), shift_1 ) ); + Word16 exp_tmp1 = exp_re + exp_re - shift_1; + Word32 tmp2 = Sqrt32( tmp1, &exp_tmp1 ); + *out_fx = tmp2; + *exp_out = exp_tmp1; +} + +void isar_mat_mult_2by2_complex_fx( + Word32 in_re1_fx[2][2], + Word16 exp_re1, + Word32 in_im1_fx[2][2], + Word16 exp_im1, + Word32 in_re2_fx[2][2], + Word16 exp_re2, + Word32 in_im2_fx[2][2], + Word16 exp_im2, + Word32 out_re2_fx[2][2], + Word16 *final_exp_re_1, + Word32 out_im2_fx[2][2], + Word16 *final_exp_im_1 ) +{ + Word16 i, j; + Word32 tmp_re_fx, tmp_im_fx; -void isar_mat_mult_2by2_complex( + Word16 exp_tmp1 = 0, exp_tmp2 = 0, exp_tmp3 = 0, exp_tmp4 = 0; + Word16 final_exp_re = 0, final_exp_im = 0; + Word16 BuffExp_re[2][2]; + Word16 BuffExp_im[2][2]; + + FOR( i = 0; i < 2; i++ ) + { + FOR( j = 0; j < 2; j++ ) + { + ivas_cmult_fix( in_re1_fx[i][0], exp_re1, in_im1_fx[i][0], exp_im1, in_re2_fx[0][j], exp_re2, in_im2_fx[0][j], exp_im2, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 ); + + out_re2_fx[i][j] = tmp_re_fx; + move32(); + out_im2_fx[i][j] = tmp_im_fx; + move32(); + + ivas_cmult_fix( in_re1_fx[i][1], exp_re1, in_im1_fx[i][1], exp_im1, in_re2_fx[1][j], exp_re2, in_im2_fx[1][j], exp_im2, &tmp_re_fx, &tmp_im_fx, &exp_tmp3, &exp_tmp4 ); + + out_re2_fx[i][j] = BASOP_Util_Add_Mant32Exp( out_re2_fx[i][j], exp_tmp1, tmp_re_fx, exp_tmp3, &final_exp_re ); + move32(); + out_im2_fx[i][j] = BASOP_Util_Add_Mant32Exp( out_im2_fx[i][j], exp_tmp2, tmp_im_fx, exp_tmp4, &final_exp_im ); + move32(); + + BuffExp_re[i][j] = final_exp_re; + move16(); + BuffExp_im[i][j] = final_exp_im; + move16(); + } + } + + Word16 max_exp_re = 0; + Word16 max_exp_im = 0; + move16(); + move16(); + FOR( i = 0; i < 2; i++ ) + { + FOR( j = 0; j < 2; j++ ) + { + max_exp_re = s_max( max_exp_re, BuffExp_re[i][j] ); + max_exp_im = s_max( max_exp_im, BuffExp_im[i][j] ); + } + } + + FOR( i = 0; i < 2; i++ ) + { + FOR( j = 0; j < 2; j++ ) + { + out_re2_fx[i][j] = L_shr( out_re2_fx[i][j], max_exp_re - BuffExp_re[i][j] ); + move32(); + out_im2_fx[i][j] = L_shr( out_im2_fx[i][j], max_exp_im - BuffExp_im[i][j] ); + move32(); + } + } + *final_exp_re_1 = max_exp_re; + move16(); + *final_exp_im_1 = max_exp_im; + move16(); + + return; +} + +void ivas_mat_mult_2by2_complex( float in_re1[2][2], float in_im1[2][2], float in_re2[2][2], @@ -87,13 +217,16 @@ void isar_mat_mult_2by2_complex( void ISAR_SPLIT_REND_BITStream_init( ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t buf_len_bytes, - uint8_t *pbuf ) + const Word32 buf_len_bytes, + UWord8 *pbuf ) { pBits->bits_buf = pbuf; pBits->buf_len = buf_len_bytes; + move32(); pBits->bits_read = 0; + move32(); pBits->bits_written = 0; + move32(); return; } @@ -108,24 +241,28 @@ void ISAR_SPLIT_REND_BITStream_init( void isar_split_rend_huffman_dec_init_min_max_len( isar_split_rend_huffman_cfg_t *p_huff_cfg ) { - int16_t i, code_len; - const int32_t *codebook; + Word16 i, code_len; + const Word32 *codebook; codebook = p_huff_cfg->codebook; p_huff_cfg->min_len = p_huff_cfg->sym_len; + move16(); p_huff_cfg->max_len = 0; + move16(); - for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + FOR( i = 0; i < p_huff_cfg->sym_len; i++ ) { - code_len = (int16_t) codebook[1]; - if ( p_huff_cfg->min_len > code_len ) + code_len = extract_l( codebook[1] ); + IF( GT_16( p_huff_cfg->min_len, code_len ) ) { p_huff_cfg->min_len = code_len; + move16(); } - if ( p_huff_cfg->max_len < code_len ) + IF( LT_16( p_huff_cfg->max_len, code_len ) ) { p_huff_cfg->max_len = code_len; + move16(); } codebook = codebook + 3; } @@ -140,16 +277,16 @@ void isar_split_rend_huffman_dec_init_min_max_len( * *------------------------------------------------------------------------*/ -static int16_t is_idx_present( - int16_t *idx_list, - const int16_t idx, - const int16_t len ) +static Word16 is_idx_present( + Word16 *idx_list, + const Word16 idx, + const Word16 len ) { - int16_t i; + Word16 i; - for ( i = 0; i < len; i++ ) + FOR( i = 0; i < len; i++ ) { - if ( idx_list[i] == idx ) + IF( EQ_16( idx_list[i], idx ) ) { return 1; } @@ -160,39 +297,46 @@ static int16_t is_idx_present( /*------------------------------------------------------------------------- - * Function isar_split_huff_get_idx_trav_list() + * Function ivas_split_huff_get_idx_trav_list() * * *------------------------------------------------------------------------*/ -static void isar_split_huff_get_idx_trav_list( - int16_t *idx_list, +static void ivas_split_huff_get_idx_trav_list( + Word16 *idx_list, isar_split_rend_huffman_cfg_t *p_huff_cfg ) { - int16_t i, j, min_idx; - int32_t min_bits; - const int32_t *codebook; + Word16 i, j, min_idx; + Word32 min_bits; + const Word32 *codebook; - for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + FOR( i = 0; i < p_huff_cfg->sym_len; i++ ) { idx_list[i] = -1; + move16(); } - for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + FOR( i = 0; i < p_huff_cfg->sym_len; i++ ) { codebook = p_huff_cfg->codebook; min_bits = p_huff_cfg->max_len; + move16(); min_idx = -1; - for ( j = 0; j < p_huff_cfg->sym_len; j++ ) + move16(); + FOR( j = 0; j < p_huff_cfg->sym_len; j++ ) { - if ( ( min_bits >= codebook[1] ) && ( is_idx_present( idx_list, j, i + 1 ) == 0 ) ) + test(); + IF( GE_32( min_bits, codebook[1] ) && EQ_16( is_idx_present( idx_list, j, i + 1 ), 0 ) ) { min_bits = codebook[1]; + move16(); min_idx = j; + move16(); } codebook += 3; } idx_list[i] = min_idx; + move16(); } return; @@ -208,42 +352,54 @@ static void isar_split_huff_get_idx_trav_list( void isar_split_rend_init_huff_cfg( ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ) { - pHuff_cfg->pred[0].codebook = &isar_split_rend_huff_pred31_consts[0][0]; + pHuff_cfg->pred[0].codebook = &ivas_split_rend_huff_pred31_consts[0][0]; pHuff_cfg->pred[0].sym_len = ISAR_SPLIT_REND_PRED_31QUANT_PNTS; + move16(); isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] ); - isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] ); - pHuff_cfg->pred_base2_code_len[0] = (int16_t) ceilf( log2f( pHuff_cfg->pred[0].sym_len ) ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] ); + pHuff_cfg->pred_base2_code_len[0] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS_LOG2_CEIL; + move16(); - pHuff_cfg->pred[1].codebook = &isar_split_rend_huff_pred63_consts[0][0]; + pHuff_cfg->pred[1].codebook = &ivas_split_rend_huff_pred63_consts[0][0]; pHuff_cfg->pred[1].sym_len = ISAR_SPLIT_REND_PRED_63QUANT_PNTS; + move16(); isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] ); - isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] ); - pHuff_cfg->pred_base2_code_len[1] = (int16_t) ceilf( log2f( pHuff_cfg->pred[1].sym_len ) ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] ); + pHuff_cfg->pred_base2_code_len[1] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS_LOG2_CEIL; + move16(); - pHuff_cfg->pred_roll.codebook = &isar_split_rend_huff_roll_pred_consts[0][0]; + pHuff_cfg->pred_roll.codebook = &ivas_split_rend_huff_roll_pred_consts[0][0]; pHuff_cfg->pred_roll.sym_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS; + move16(); isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll ); - isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll ); - pHuff_cfg->pred_roll_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->pred_roll.sym_len ) ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll ); + pHuff_cfg->pred_roll_base2_code_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS_LOG2_CEIL; + move16(); - pHuff_cfg->gd.codebook = &isar_split_rend_huff_d_consts[0][0]; + pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0]; pHuff_cfg->gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + move16(); isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd ); - isar_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd ); - pHuff_cfg->gd_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->gd.sym_len ) ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd ); + pHuff_cfg->gd_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL; + move16(); - pHuff_cfg->p_gd.codebook = &isar_split_rend_huff_p_d_consts[0][0]; + pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0]; pHuff_cfg->p_gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + move16(); isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd ); - isar_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd ); - pHuff_cfg->p_gd_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->p_gd.sym_len ) ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd ); + pHuff_cfg->p_gd_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL; + move16(); - pHuff_cfg->p_gd_diff.codebook = &isar_split_rend_huff_p_d_diff_consts[0][0]; + pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0]; pHuff_cfg->p_gd_diff.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + move16(); isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff ); - isar_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff ); - pHuff_cfg->p_gd_diff_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->p_gd_diff.sym_len ) ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff ); + pHuff_cfg->p_gd_diff_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL; + move16(); return; } @@ -255,6 +411,34 @@ void isar_split_rend_init_huff_cfg( * *------------------------------------------------------------------------*/ +void set_fix_rotation_mat_fx( + Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + Word32 cos_yaw, sin_yaw; + Word16 pos_idx; + Word16 ind = 0; + + // pMultiBinPoseData->relative_head_poses can take only take -30, -22.5, -15, 0, 15, 22.5 and 30 degrees. + // cos(180 - theta) = cos(theta). + // Need only 4 values in LUT + + FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ ) + { + ind = extract_l( L_shr( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] ), Q22 ) ); + + ind = shr( ind, 3 ); /* Values: 0, 1, 2 and 3 */ + cos_yaw = ivas_split_rend_fix_pos_rot_mat_cos_fx[ind]; /* Q31 */ + sin_yaw = 0; + + fix_pos_rot_mat[pos_idx][0][0] = cos_yaw; /* Q31 */ + fix_pos_rot_mat[pos_idx][1][1] = cos_yaw; /* Q31 */ + fix_pos_rot_mat[pos_idx][0][1] = sin_yaw; /* Q31 */ + fix_pos_rot_mat[pos_idx][1][0] = L_negate( sin_yaw ); /* Q31 */ + } + + return; +} void set_fix_rotation_mat( float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) @@ -285,6 +469,33 @@ void set_fix_rotation_mat( * *------------------------------------------------------------------------*/ +void set_pose_types_fx( + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + Word16 pos_idx; + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + IF( GT_32( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] ), EPSILON_FX ) ) + { + pose_type[pos_idx] = ANY_YAW; + move32(); + } + ELSE IF( GT_32( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][2] ), EPSILON_FX ) ) + { + pose_type[pos_idx] = ANY_ROLL; + move32(); + } + ELSE + { + pose_type[pos_idx] = PITCH_ONLY; + move32(); + } + } + + return; +} void set_pose_types( ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) @@ -317,19 +528,19 @@ void set_pose_types( * *------------------------------------------------------------------------*/ -int16_t wrap_a( - int16_t val, - const int16_t min_val, - const int16_t max_val ) +Word16 wrap_a( + Word16 val, + const Word16 min_val, + const Word16 max_val ) { - if ( val < min_val ) + IF( LT_16( val, min_val ) ) { - val = max_val - min_val + val + 1; + val = add( add( sub( max_val, min_val ), val ), 1 ); } - if ( val > max_val ) + IF( GT_16( val, max_val ) ) { - val = min_val + val - max_val - 1; + val = sub( sub( add( min_val, val ), max_val ), 1 ); } return val; @@ -343,18 +554,25 @@ int16_t wrap_a( *------------------------------------------------------------------------*/ void isar_SplitRenderer_getdiagdiff( - int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - const int16_t sign, - const int16_t min_val, - const int16_t max_val ) + Word16 in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const Word16 sign, + const Word16 min_val, + const Word16 max_val ) { out_idx[0][0] = in_idx[0][0]; + move16(); out_idx[0][1] = in_idx[0][1]; - out_idx[1][1] = in_idx[1][1] + sign * out_idx[0][0]; + move16(); + // DEPR_i_mult used instead of i_mult becuase it is not available + out_idx[1][1] = add( in_idx[1][1], DEPR_i_mult( sign, out_idx[0][0] ) ); + move16(); out_idx[1][1] = wrap_a( out_idx[1][1], min_val, max_val ); - out_idx[1][0] = in_idx[1][0] + sign * out_idx[0][1]; + move16(); + out_idx[1][0] = add( in_idx[1][0], DEPR_i_mult( sign, out_idx[0][1] ) ); + move16(); out_idx[1][0] = wrap_a( out_idx[1][0], min_val, max_val ); + move16(); return; } @@ -365,12 +583,11 @@ void isar_SplitRenderer_getdiagdiff( * * *------------------------------------------------------------------------*/ - -int32_t ISAR_SPLIT_REND_BITStream_read_int32( +Word32 ISAR_SPLIT_REND_BITStream_read_int32( ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t bits ) + const Word32 bits ) { - int32_t val, k, bit_val; + Word32 val, k, bit_val; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG assert( ( pBits->bits_written - pBits->bits_read ) >= bits ); @@ -379,11 +596,12 @@ int32_t ISAR_SPLIT_REND_BITStream_read_int32( /* write bit by bit */ val = 0; - for ( k = bits - 1; k >= 0; k-- ) + move32(); + FOR( k = L_sub( bits, 1 ); k >= 0; k-- ) { - bit_val = ( pBits->bits_buf[pBits->bits_read >> 3] & ( 1 << ( pBits->bits_read & 7 ) ) ) != 0; - val |= bit_val << k; - pBits->bits_read++; + bit_val = NE_32( L_and( pBits->bits_buf[L_shr( pBits->bits_read, 3 )], ( L_shl( 1, (Word16) ( L_and( pBits->bits_read, 7 ) ) ) ) ), 0 ); + val = L_or( val, L_shl( bit_val, (Word16) k ) ); + pBits->bits_read = L_add( pBits->bits_read, 1 ); } return val; @@ -398,10 +616,10 @@ int32_t ISAR_SPLIT_REND_BITStream_read_int32( void ISAR_SPLIT_REND_BITStream_write_int32( ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t val, - const int32_t bits ) + const Word32 val, + const Word32 bits ) { - int32_t mask, k; + Word32 mask, k; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG /*protection check*/ @@ -411,20 +629,20 @@ void ISAR_SPLIT_REND_BITStream_write_int32( } #endif - mask = 1 << ( bits - 1 ); + mask = L_shl( 1, extract_l( L_sub( bits, 1 ) ) ); /* write bit by bit */ - for ( k = 0; k < bits; k++ ) + FOR( k = 0; k < bits; k++ ) { - if ( val & mask ) + IF( L_and( val, mask ) ) { - pBits->bits_buf[pBits->bits_written >> 3] |= ( 1 << ( pBits->bits_written & 7 ) ); + pBits->bits_buf[L_shr( pBits->bits_written, 3 )] = (UWord8) L_or( pBits->bits_buf[L_shr( pBits->bits_written, 3 )], L_shl( 1, extract_l( L_and( pBits->bits_written, 7 ) ) ) ); } - else + ELSE { - pBits->bits_buf[pBits->bits_written >> 3] &= ~( 1 << ( pBits->bits_written & 7 ) ); + pBits->bits_buf[L_shr( pBits->bits_written, 3 )] = (UWord8) L_and( pBits->bits_buf[L_shr( pBits->bits_written, 3 )], ~L_shl( 1, extract_l( L_and( pBits->bits_written, 7 ) ) ) ); } pBits->bits_written++; - mask >>= 1; + mask = L_shr( mask, 1 ); } return; @@ -433,7 +651,7 @@ void ISAR_SPLIT_REND_BITStream_write_int32( #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG /*------------------------------------------------------------------------- - * isar_log_cldfb2wav_data() + * ivas_mat_mult_2by2_complex() * * *------------------------------------------------------------------------*/ @@ -483,34 +701,38 @@ void isar_log_cldfb2wav_data( * *------------------------------------------------------------------------*/ -int32_t isar_get_split_rend_md_target_brate( - const int32_t SplitRendBitRate, - const int16_t pcm_out_flag ) +Word32 isar_get_split_rend_md_target_brate( + const Word32 SplitRendBitRate, + const Word16 pcm_out_flag ) { - int32_t md_bitrate; + Word32 md_bitrate; - if ( pcm_out_flag == 1 ) + IF( EQ_16( pcm_out_flag, 1 ) ) { md_bitrate = SplitRendBitRate; + move32(); } - else + ELSE { - switch ( SplitRendBitRate ) + SWITCH( SplitRendBitRate ) { case SPLIT_REND_768k: { md_bitrate = 256000; - break; + move32(); + BREAK; } case SPLIT_REND_512k: { md_bitrate = 128000; - break; + move32(); + BREAK; } case SPLIT_REND_384k: { md_bitrate = 128000; - break; + move32(); + BREAK; } default: { @@ -529,13 +751,13 @@ int32_t isar_get_split_rend_md_target_brate( * *------------------------------------------------------------------------*/ -int32_t isar_get_lcld_bitrate( - const int32_t SplitRendBitRate, +Word32 isar_get_lcld_bitrate( + const Word32 SplitRendBitRate, const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) { - if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) { - switch ( SplitRendBitRate ) + SWITCH( SplitRendBitRate ) { case SPLIT_REND_768k: { @@ -555,7 +777,7 @@ int32_t isar_get_lcld_bitrate( } } } - else + ELSE { return SplitRendBitRate; } @@ -563,7 +785,6 @@ int32_t isar_get_lcld_bitrate( return -1; } - #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS /*------------------------------------------------------------------------- * Function isar_get_lc3plus_bitrate() @@ -571,18 +792,18 @@ int32_t isar_get_lcld_bitrate( * *------------------------------------------------------------------------*/ -int32_t isar_get_lc3plus_bitrate( - const int32_t SplitRendBitRate, +Word32 isar_get_lc3plus_bitrate( + const Word32 SplitRendBitRate, ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ) + const Word16 split_prerender_frame_size_ms ) { - if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) { - int32_t inBandMdBps = (int32_t) ( 8 * 1000 / split_prerender_frame_size_ms ); - return isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ) - inBandMdBps; + Word32 inBandMdBps = (Word32) ( 8 * 1000 / split_prerender_frame_size_ms ); + return L_sub( isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ), inBandMdBps ); } - if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) { return SplitRendBitRate; } @@ -599,10 +820,10 @@ int32_t isar_get_lc3plus_bitrate( * *------------------------------------------------------------------------*/ -int8_t isar_get_lc3plus_bitrate_id( - const int32_t SplitRendBitRate ) +Word8 isar_get_lc3plus_bitrate_id( + const Word32 SplitRendBitRate ) { - switch ( SplitRendBitRate ) + SWITCH( SplitRendBitRate ) { case SPLIT_REND_768k: { @@ -626,7 +847,7 @@ int8_t isar_get_lc3plus_bitrate_id( } default: { - break; + BREAK; } } @@ -635,60 +856,65 @@ int8_t isar_get_lc3plus_bitrate_id( /*------------------------------------------------------------------------- - * Function isar_get_lc3plus_size_from_id() + * Function ivas_mat_mult_2by2_complex() * * *------------------------------------------------------------------------*/ -int32_t isar_get_lc3plus_size_from_id( - const int8_t SplitRendBitRateId, +Word32 isar_get_lc3plus_size_from_id( + const Word8 SplitRendBitRateId, const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ) + const Word16 split_prerender_frame_size_ms ) { - int32_t bitrate; + Word32 bitrate; - switch ( SplitRendBitRateId ) + SWITCH( SplitRendBitRateId ) { case 4: { bitrate = SPLIT_REND_768k; - break; + move32(); + BREAK; } case 3: { bitrate = SPLIT_REND_512k; - break; + move32(); + BREAK; } case 2: { bitrate = SPLIT_REND_384k; - break; + move32(); + BREAK; } case 1: { bitrate = SPLIT_REND_320k; - break; + move32(); + BREAK; } case 0: { bitrate = SPLIT_REND_256k; - break; + move32(); + BREAK; } default: { bitrate = -1; - break; + move32(); + BREAK; } } bitrate = isar_get_lc3plus_bitrate( bitrate, poseCorrectionMode, split_prerender_frame_size_ms ); /* Return size in bytes */ - return (int32_t) ( bitrate * split_prerender_frame_size_ms / 1000 / 8 ); + return (Word32) ( bitrate * split_prerender_frame_size_ms / 1000 / 8 ); } #endif - /*------------------------------------------------------------------------- * Function isar_split_rend_validate_config() * @@ -697,124 +923,129 @@ int32_t isar_get_lc3plus_size_from_id( ivas_error isar_split_rend_validate_config( const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int16_t is_pcm_out ) + const Word16 is_pcm_out ) { /* Valid DOF range is 0-3 */ - if ( pSplitRendConfig->dof < 0 || pSplitRendConfig->dof > 3 ) + test(); + IF( LT_16( pSplitRendConfig->dof, 0 ) || GT_16( pSplitRendConfig->dof, 3 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Valid DOF range is 0-3" ); } /* Only CLDFB pose correction supports HQ mode */ - if ( pSplitRendConfig->poseCorrectionMode != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB && pSplitRendConfig->hq_mode != 0 ) + test(); + IF( NE_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) && NE_16( pSplitRendConfig->hq_mode, 0 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Only CLDFB pose correction supports HQ mode" ); } /* Split rendering with no pose correction - 0 DOF and pose correction NONE must only ever be set together */ - if ( ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof != 0 ) || - ( pSplitRendConfig->poseCorrectionMode != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof == 0 ) ) + test(); + test(); + test(); + IF( ( EQ_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) && NE_16( pSplitRendConfig->dof, 0 ) ) || + ( NE_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) && EQ_16( pSplitRendConfig->dof, 0 ) ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "0 DOF and pose correction NONE must only ever be set together" ); } - if ( pSplitRendConfig->codec_frame_size_ms != 0 ) /* 0 means "default for current codec", will be set to actual value at a later stage */ + IF( NE_16( pSplitRendConfig->codec_frame_size_ms, 0 ) ) /* 0 means "default for current codec", will be set to actual value at a later stage */ { - if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 && pSplitRendConfig->codec_frame_size_ms != 20 ) + test(); + test(); + test(); + IF( EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LCLD ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 5 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 10 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 20 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" ); } - if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && ( pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 ) ) + test(); + test(); + IF( EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 5 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 10 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LC3plus codec" ); } } /* Validate bitrate */ - if ( is_pcm_out == 0 ) + IF( EQ_16( is_pcm_out, 0 ) ) { - switch ( pSplitRendConfig->splitRendBitRate ) + SWITCH( pSplitRendConfig->splitRendBitRate ) { case SPLIT_REND_256k: - if ( pSplitRendConfig->dof != 0 ) + IF( NE_16( pSplitRendConfig->dof, 0 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrates of 320 kbps and lower are only valid with 0 DOF" ); } - break; + BREAK; case SPLIT_REND_320k: /* Only valid with 0 DOF */ - if ( pSplitRendConfig->dof != 0 ) + IF( NE_16( pSplitRendConfig->dof, 0 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrates of 320 kbps and lower are only valid with 0 DOF" ); } - break; + BREAK; case SPLIT_REND_384k: case SPLIT_REND_512k: #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS case SPLIT_REND_768k: #endif /* Always valid */ - break; + BREAK; #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS case SPLIT_REND_768k: - if ( pSplitRendConfig->dof == 0 && pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + test(); + IF( EQ_16( pSplitRendConfig->dof, 0 ) && EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrate is too high for LC3plus with 0 DOF" ); } - break; + BREAK; #endif default: return IVAS_ERR_LC3PLUS_INVALID_BITRATE; } } - else + ELSE { - if ( pSplitRendConfig->dof == 1 ) - { + IF( EQ_16( pSplitRendConfig->dof, 1 ) ){ #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - if ( pSplitRendConfig->splitRendBitRate < 34000 ) - { + IF( LT_32( pSplitRendConfig->splitRendBitRate, 34000 ) ){ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 34 kbps" ); - } + } #else - if ( pSplitRendConfig->splitRendBitRate < 50000 ) - { + IF( LT_32( pSplitRendConfig->splitRendBitRate, 50000 ) ){ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" ); - } + } #endif - } - else if ( pSplitRendConfig->dof == 2 ) - { +} +ELSE IF( EQ_16( pSplitRendConfig->dof, 2 ) ){ #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - if ( pSplitRendConfig->splitRendBitRate < 50000 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 50 kbps" ); - } + IF( LT_32( pSplitRendConfig->splitRendBitRate, 50000 ) ){ + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 50 kbps" ); +} #else - if ( pSplitRendConfig->splitRendBitRate < 66000 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" ); - } + IF( LT_32( pSplitRendConfig->splitRendBitRate, 66000 ) ){ + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" ); +} #endif - } - else if ( pSplitRendConfig->dof == 3 ) - { +} +ELSE IF( EQ_16( pSplitRendConfig->dof, 3 ) ) +{ #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - if ( pSplitRendConfig->splitRendBitRate < 82000 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 82 kbps" ); - } + IF( LT_32( pSplitRendConfig->splitRendBitRate, 82000 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); + } #else - if ( pSplitRendConfig->splitRendBitRate < 128000 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); - } -#endif - } + IF( LT_32( pSplitRendConfig->splitRendBitRate, 128000 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); } +#endif +} +} - return IVAS_ERR_OK; +return IVAS_ERR_OK; } @@ -824,89 +1055,113 @@ ivas_error isar_split_rend_validate_config( * *------------------------------------------------------------------------*/ -void isar_split_rend_get_quant_params( - const int16_t num_md_bands, - int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], +void isar_split_rend_get_quant_params_fx( + const Word16 num_md_bands, + Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - const int16_t ro_flag, + const Word16 ro_flag, #endif - int16_t *num_quant_strats + Word16 *num_quant_strats #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS , - int16_t *num_complex_bands + Word16 *num_complex_bands #endif ) { - int16_t q; + Word16 q; *num_quant_strats = ISAR_SPLIT_REND_NUM_QUANT_STRATS; + move16(); #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW; + move16(); assert( *num_complex_bands <= num_md_bands ); #endif pred_quant_pnts_yaw[0] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS; - pred_quantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_Q_STEP; - pred_1byquantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_1BYQ_STEP; - for ( q = 1; q < *num_quant_strats; q++ ) + move16(); + pred_quantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_Q_STEP_FX_Q31; + move32(); + pred_1byquantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_1BYQ_STEP_FX_Q26; + move32(); + FOR( q = 1; q < *num_quant_strats; q++ ) { pred_quant_pnts_yaw[q] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS; - pred_quantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_Q_STEP; - pred_1byquantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_1BYQ_STEP; + move16(); + pred_quantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_Q_STEP_FX_Q31; + move32(); + pred_1byquantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_1BYQ_STEP_FX_Q26; + move32(); } - for ( q = 0; q < *num_quant_strats; q++ ) + FOR( q = 0; q < *num_quant_strats; q++ ) { pred_real_bands_yaw[q] = num_md_bands; + move16(); pred_real_bands_roll[q] = num_md_bands; + move16(); } #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS pred_imag_bands_yaw[0] = num_md_bands; + move16(); pred_imag_bands_roll[0] = num_md_bands; + move16(); pred_imag_bands_yaw[1] = num_md_bands; + move16(); pred_imag_bands_roll[1] = num_md_bands; - for ( q = 2; q < *num_quant_strats; q++ ) + move16(); + + FOR( q = 2; q < *num_quant_strats; q++ ) { - pred_imag_bands_yaw[q] = ( q < ( *num_quant_strats - 1 ) ) ? num_md_bands : *num_complex_bands; + pred_imag_bands_yaw[q] = LT_16( q, sub( *num_quant_strats, 1 ) ) ? num_md_bands : *num_complex_bands; + move16(); pred_imag_bands_roll[q] = *num_complex_bands; + move16(); } #else - if ( ro_flag ) + IF( ro_flag ) { - for ( q = 0; q < *num_quant_strats; q++ ) + FOR( q = 0; q < *num_quant_strats; q++ ) { pred_imag_bands_yaw[q] = SPLIT_REND_RO_MD_BAND_THRESH; + move16(); } } - else + ELSE { - for ( q = 0; q < *num_quant_strats - 2; q++ ) + FOR( q = 0; q < *num_quant_strats - 2; q++ ) { pred_imag_bands_yaw[q] = num_md_bands; + move16(); } pred_imag_bands_yaw[( *num_quant_strats - 2 )] = COMPLEX_MD_BAND_THRESH_HIGH; + move16(); pred_imag_bands_yaw[( *num_quant_strats - 1 )] = COMPLEX_MD_BAND_THRESH_LOW; + move16(); } - for ( q = 0; q < *num_quant_strats; q++ ) + FOR( q = 0; q < *num_quant_strats; q++ ) { pred_imag_bands_roll[q] = SPLIT_REND_RO_MD_BAND_THRESH; + move16(); } #endif - for ( q = 0; q < *num_quant_strats; q++ ) + FOR( q = 0; q < *num_quant_strats; q++ ) { d_bands_yaw[q] = 0; + move16(); bands_pitch[q] = num_md_bands; + move16(); } return; @@ -919,15 +1174,15 @@ void isar_split_rend_get_quant_params( * *------------------------------------------------------------------------*/ -int16_t isar_renderSplitGetRot_axisNumBits( - const int16_t dof ) +Word16 isar_renderSplitGetRot_axisNumBits( + const Word16 dof ) { - int16_t num_bits; - if ( dof < 3 ) + Word16 num_bits; + IF( dof < 3 ) { num_bits = 2; } - else + ELSE { num_bits = 0; } @@ -941,27 +1196,27 @@ int16_t isar_renderSplitGetRot_axisNumBits( *------------------------------------------------------------------------*/ ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( - const int16_t dof, - const int16_t code ) + const Word16 dof, + const Word16 code ) { ISAR_SPLIT_REND_ROT_AXIS rot_axis; - if ( dof == 1 ) + IF( dof == 1 ) { rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; } else if ( dof == 2 ) { - if ( code == 0 ) + IF( code == 0 ) { rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; } - else + ELSE { rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ( code - 1 ) + YAW_PITCH; } } - else + ELSE { rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) DEFAULT_AXIS; } @@ -975,30 +1230,30 @@ ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( * *------------------------------------------------------------------------*/ -int16_t isar_renderSplitGetCodeFromRot_axis( - const int16_t dof, +Word16 isar_renderSplitGetCodeFromRot_axis( + const Word16 dof, const ISAR_SPLIT_REND_ROT_AXIS rot_axis, - int16_t *num_bits ) + Word16 *num_bits ) { - int16_t code = 0; - if ( dof == 1 ) + Word16 code = 0; + IF( dof == 1 ) { - code = (int16_t) rot_axis; + code = (Word16) rot_axis; } else if ( dof == 2 ) { - if ( rot_axis == DEFAULT_AXIS ) + IF( rot_axis == DEFAULT_AXIS ) { - code = (int16_t) rot_axis; + code = (Word16) rot_axis; } - else + ELSE { - code = (int16_t) ( rot_axis - YAW_PITCH ) + 1; + code = (Word16) ( rot_axis - YAW_PITCH ) + 1; } } - else + ELSE { - code = (int16_t) DEFAULT_AXIS; + code = (Word16) DEFAULT_AXIS; } *num_bits = isar_renderSplitGetRot_axisNumBits( dof ); @@ -1012,52 +1267,61 @@ int16_t isar_renderSplitGetCodeFromRot_axis( * *------------------------------------------------------------------------*/ -void isar_renderSplitGetMultiBinPoseData( +void isar_renderSplitGetMultiBinPoseData_fx( const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const ISAR_SPLIT_REND_ROT_AXIS rot_axis ) { - int16_t pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses; - const float *relative_yaw_angles; - const float *relative_pitch_angles; - const float *relative_roll_angles; + Word16 pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses; + const Word32 *relative_yaw_angles; + const Word32 *relative_pitch_angles; + const Word32 *relative_roll_angles; - for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) { - pMultiBinPoseData->relative_head_poses[pos_idx][0] = 0.0f; - pMultiBinPoseData->relative_head_poses[pos_idx][1] = 0.0f; - pMultiBinPoseData->relative_head_poses[pos_idx][2] = 0.0f; + pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0; + move32(); } /* 0 DOF defaults */ num_yaw_poses = 0; + move16(); num_pitch_poses = 0; + move16(); num_roll_poses = 0; + move16(); /* defaults for all DOF except 3DOF HQ */ - relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles_hq; - relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles_hq; - relative_roll_angles = isar_split_rend_relative_roll_pos_angles_hq; + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq_fx; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq_fx; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq_fx; - if ( pSplit_rend_config->dof == 1 ) + IF( EQ_16( pSplit_rend_config->dof, 1 ) ) { - switch ( rot_axis ) + SWITCH( rot_axis ) { case DEFAULT_AXIS: case YAW: { num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; - break; + move16(); + BREAK; } case PITCH: { num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; - break; + move16(); + BREAK; } case ROLL: { num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; - break; + move16(); + BREAK; } default: { @@ -1065,9 +1329,9 @@ void isar_renderSplitGetMultiBinPoseData( } } } - else if ( pSplit_rend_config->dof == 2 ) + ELSE IF( EQ_16( pSplit_rend_config->dof, 2 ) ) { - switch ( rot_axis ) + SWITCH( rot_axis ) { case DEFAULT_AXIS: #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS @@ -1077,8 +1341,10 @@ void isar_renderSplitGetMultiBinPoseData( case YAW_PITCH: { num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; - break; + move16(); + BREAK; } #ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS case ROLL: @@ -1086,14 +1352,18 @@ void isar_renderSplitGetMultiBinPoseData( case YAW_ROLL: { num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; - break; + move16(); + BREAK; } case PITCH_ROLL: { num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + move16(); num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; - break; + move16(); + BREAK; } default: { @@ -1101,54 +1371,66 @@ void isar_renderSplitGetMultiBinPoseData( } } } - else if ( pSplit_rend_config->dof == 3 ) + ELSE IF( EQ_16( pSplit_rend_config->dof, 3 ) ) { - if ( pSplit_rend_config->hq_mode == 1 ) + IF( EQ_16( pSplit_rend_config->hq_mode, 1 ) ) { - relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles_hq; - relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles_hq; - relative_roll_angles = isar_split_rend_relative_roll_pos_angles_hq; + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq_fx; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq_fx; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq_fx; num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + move16(); num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + move16(); } - else + ELSE { - relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles; - relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles; - relative_roll_angles = isar_split_rend_relative_roll_pos_angles; + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_fx; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_fx; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_fx; num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); num_pitch_poses = 1; + move16(); num_roll_poses = 1; + move16(); } } - pMultiBinPoseData->num_poses = num_yaw_poses + num_pitch_poses + num_roll_poses + 1; - assert( pMultiBinPoseData->num_poses <= MAX_HEAD_ROT_POSES ); + pMultiBinPoseData->num_poses = add( add( num_yaw_poses, num_pitch_poses ), add( num_roll_poses, 1 ) ); + assert( LE_16( pMultiBinPoseData->num_poses, MAX_HEAD_ROT_POSES ) ); - for ( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ ) { - pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] = relative_yaw_angles[pos_idx]; + pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] = relative_yaw_angles[pos_idx]; + move32(); } - for ( pos_idx = 0; pos_idx < num_pitch_poses; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < num_pitch_poses; pos_idx++ ) { - pMultiBinPoseData->relative_head_poses[pos_idx + num_yaw_poses + 1][1] = relative_pitch_angles[pos_idx]; + pMultiBinPoseData->relative_head_poses_fx[pos_idx + num_yaw_poses + 1][1] = relative_pitch_angles[pos_idx]; + move32(); } - for ( pos_idx = 0; pos_idx < num_roll_poses; pos_idx++ ) + FOR( pos_idx = 0; pos_idx < num_roll_poses; pos_idx++ ) { - pMultiBinPoseData->relative_head_poses[pos_idx + num_yaw_poses + num_pitch_poses + 1][2] = relative_roll_angles[pos_idx]; + pMultiBinPoseData->relative_head_poses_fx[pos_idx + num_yaw_poses + num_pitch_poses + 1][2] = relative_roll_angles[pos_idx]; + move32(); } pMultiBinPoseData->dof = pSplit_rend_config->dof; + move16(); pMultiBinPoseData->hq_mode = pSplit_rend_config->hq_mode; + move16(); pMultiBinPoseData->rot_axis = rot_axis; + move32(); pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; + move32(); return; } - /*------------------------------------------------------------------------- * Function isar_renderSplitUpdateNoCorrectionPoseData() * @@ -1160,10 +1442,13 @@ void isar_renderSplitUpdateNoCorrectionPoseData( MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) { pMultiBinPoseData->num_poses = 1; + move16(); assert( pSplit_rend_config->dof == 0 ); pMultiBinPoseData->dof = pSplit_rend_config->dof; + move16(); assert( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ); pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; + move32(); return; } @@ -1175,6 +1460,58 @@ void isar_renderSplitUpdateNoCorrectionPoseData( * *------------------------------------------------------------------------*/ +void isar_init_multi_bin_pose_data_fx( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + Word16 pos_idx; + + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0; + move32(); + } + pMultiBinPoseData->num_poses = 1; + move16(); + pMultiBinPoseData->dof = 3; + move16(); + pMultiBinPoseData->hq_mode = 0; + move16(); + pMultiBinPoseData->rot_axis = DEFAULT_AXIS; + move32(); + + return; +} + +/* Copy for encoder, to be removed */ +void isar_init_multi_bin_pose_data_fx_enc( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + Word16 pos_idx; + + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0; + move32(); + } + pMultiBinPoseData->num_poses = 1; + move16(); + pMultiBinPoseData->dof = 3; + move16(); + pMultiBinPoseData->hq_mode = 0; + move16(); + pMultiBinPoseData->rot_axis = DEFAULT_AXIS; + move32(); + + return; +} void isar_init_multi_bin_pose_data( MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) { @@ -1219,7 +1556,6 @@ ivas_error isar_framesize_to_ms( } #endif - /*------------------------------------------------------------------------- * Function isar_split_rend_choose_default_codec() * @@ -1231,45 +1567,49 @@ ivas_error isar_split_rend_choose_default_codec( #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */ #endif - int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ - const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ - const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ - const int16_t num_subframes /* i : number of subframes */ + Word16 *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const Word16 cldfb_in_flag, /* i : flag indicating rendering in TD */ + const Word16 pcm_out_flag, /* i : flag to indicate PCM output */ + const Word16 num_subframes /* i : number of subframes */ ) { - if ( pcm_out_flag == 0 ) + IF( EQ_16( pcm_out_flag, 0 ) ) { - if ( *pCodec == ISAR_SPLIT_REND_CODEC_DEFAULT ) + IF( EQ_32( *pCodec, ISAR_SPLIT_REND_CODEC_DEFAULT ) ) { *pCodec = cldfb_in_flag ? ISAR_SPLIT_REND_CODEC_LCLD : ISAR_SPLIT_REND_CODEC_LC3PLUS; + move32(); } } - else + ELSE { *pCodec = ISAR_SPLIT_REND_CODEC_NONE; + move32(); } - if ( *pCodec_frame_size_ms == 0 ) /* codec frame size hasn't been set yet - use default for current configuration */ + IF( EQ_16( *pCodec_frame_size_ms, 0 ) ) /* codec frame size hasn't been set yet - use default for current configuration */ { - switch ( *pCodec ) + SWITCH( *pCodec ) { case ISAR_SPLIT_REND_CODEC_LCLD: - *pCodec_frame_size_ms = num_subframes * 5; - break; + *pCodec_frame_size_ms = DEPR_i_mult( num_subframes, 5 ); + BREAK; case ISAR_SPLIT_REND_CODEC_LC3PLUS: case ISAR_SPLIT_REND_CODEC_NONE: *pCodec_frame_size_ms = 5; - break; + move16(); + BREAK; default: return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" ); } } #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - if ( *pIsar_frame_size_ms == 0 ) /* isar frame size hasn't been set yet - use default for current configuration */ + IF( *pIsar_frame_size_ms == 0 ) /* isar frame size hasn't been set yet - use default for current configuration */ { *pIsar_frame_size_ms = 20; } #endif + return IVAS_ERR_OK; } @@ -1279,11 +1619,123 @@ ivas_error isar_split_rend_choose_default_codec( * *-------------------------------------------------------------------*/ -int32_t get_bit( - const int32_t state, - const int32_t bit_id ) +Word32 get_bit( + const Word32 state, + const Word32 bit_id ) +{ + return L_and( state, ( L_shl( 1, (Word16) bit_id ) ) ); +} + +void set16_fx( + Word16 y[], /* i/o: Vector to set */ + const Word16 a, /* i : Value to set the vector to */ + const Word16 N /* i : Lenght of the vector */ +) +{ + Word16 i; + + for ( i = 0; i < N; i++ ) + { + y[i] = a; + } + + return; +} + +void set32_fx( + Word32 y[], /* i/o: Vector to set */ + const Word32 a, /* i : Value to set the vector to */ + const Word16 N /* i : Length of the vector */ +) { - return ( state & ( 1 << bit_id ) ); + Word16 i; + + FOR( i = 0; i < N; i++ ) + { + y[i] = a; + move32(); + } + + return; } +/*-------------------------------------------------------------------* + * ceil_log_2() + * + * calculates ceil(log2(val)) + *-------------------------------------------------------------------*/ + +Word16 ceil_log_2( + UWord64 val ) +{ + + IF( val <= 0 ) + { + assert( 0 ); + } + return val <= 1 ? 0 : val <= 2 ? 1 + : val <= 4 ? 2 + : val <= 8 ? 3 + : val <= 16 ? 4 + : val <= 32 ? 5 + : val <= 64 ? 6 + : val <= 128 ? 7 + : val <= 256 ? 8 + : val <= 512 ? 9 + : val <= 1024 ? 10 + : val <= 2048 ? 11 + : val <= 4096 ? 12 + : val <= 8192 ? 13 + : val <= 16384 ? 14 + : val <= 32768 ? 15 + : val <= 65536 ? 16 + : val <= 131072 ? 17 + : val <= 262144 ? 18 + : val <= 524288 ? 19 + : val <= 1048576 ? 20 + : val <= 2097152 ? 21 + : val <= 4194304 ? 22 + : val <= 8388608 ? 23 + : val <= 16777216 ? 24 + : val <= 33554432 ? 25 + : val <= 67108864 ? 26 + : val <= 134217728 ? 27 + : val <= 268435456 ? 28 + : val <= 536870912 ? 29 + : val <= 1073741824 ? 30 + : val <= 2147483648 ? 31 + : val <= 4294967296 ? 32 + : val <= 8589934592 ? 33 + : val <= 17179869184 ? 34 + : val <= 34359738368 ? 35 + : val <= 68719476736 ? 36 + : val <= 137438953472 ? 37 + : val <= 274877906944 ? 38 + : val <= 549755813888 ? 39 + : val <= 1099511627776 ? 40 + : val <= 2199023255552 ? 41 + : val <= 4398046511104 ? 42 + : val <= 8796093022208 ? 43 + : val <= 17592186044416 ? 44 + : val <= 35184372088832 ? 45 + : val <= 70368744177664 ? 46 + : val <= 140737488355328 ? 47 + : val <= 281474976710656 ? 48 + : val <= 562949953421312 ? 49 + : val <= 1125899906842624 ? 50 + : val <= 2251799813685248 ? 51 + : val <= 4503599627370496 ? 52 + : val <= 9007199254740992 ? 53 + : val <= 18014398509481984 ? 54 + : val <= 36028797018963968 ? 55 + : val <= 72057594037927936 ? 56 + : val <= 144115188075855872 ? 57 + : val <= 288230376151711744 ? 58 + : val <= 576460752303423488 ? 59 + : val <= 1152921504606846976 ? 60 + : val <= 2305843009213693952 ? 61 + : val <= 4611686018427387904 ? 62 + : val <= 9223372036854775807 ? 63 + : 64; +} #endif diff --git a/lib_isar/isar_stat.h b/lib_isar/isar_stat.h index 1451cc7bf..e94d23e18 100644 --- a/lib_isar/isar_stat.h +++ b/lib_isar/isar_stat.h @@ -63,7 +63,7 @@ typedef struct int8_t headRotEnabled; IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - float crossfade[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 crossfade_fx[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; } ISAR_POST_REND_HeadRotData; @@ -111,23 +111,28 @@ typedef struct isar_binaural_head_rot_split_rendering_huff_struct /* binaural split rendering head rotation data structure */ typedef struct isar_binaural_head_rot_split_rendering_md_struct { - float pred_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float pred_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 pred_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q25 */ + Word16 exp_pred_mat_re; + Word32 pred_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q25 */ + Word16 exp_pred_mat_im; #ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS - float pred_mat_re2[BINAURAL_CHANNELS]; + Word32 pred_mat_re2[BINAURAL_CHANNELS]; + Word16 exp_pred_mat_re2; #endif - float gd; - float gd2; + Word32 gd_fx; /* Q25 */ + Word32 gd2_fx; /* Q25 */ + Word16 exp_gd; + Word16 exp_gd2; int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; int16_t gd_idx; int16_t gd2_idx; } ISAR_BIN_HR_SPLIT_REND_MD, *ISAR_BIN_HR_SPLIT_REND_MD_HANDLE; - typedef struct isar_binaural_head_rot_split_pre_rendering_struct { ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + Word32 fix_pos_rot_mat_fx[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg; @@ -140,7 +145,6 @@ typedef struct isar_binaural_head_rot_split_pre_rendering_struct #endif } ISAR_BIN_HR_SPLIT_PRE_REND, *ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE; - /*----------------------------------------------------------------------------------* * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...) *----------------------------------------------------------------------------------*/ @@ -148,53 +152,52 @@ typedef struct isar_binaural_head_rot_split_pre_rendering_struct typedef struct isar_binaural_head_rot_split_rendering_lcld_enc_struct { void *pLcld_enc; - int16_t iChannels; + Word16 iChannels; LCLDEncoder *psLCLDEncoder; - float ***pppfLCLDReal; - float ***pppfLCLDImag; + Word32 ***pppfLCLDReal_fx; + Word32 ***pppfLCLDImag_fx; #ifdef CLDFB_DEBUG FILE *cldfbIn; int16_t numFrame; #endif - int16_t iNumIterations; - int16_t iNumBlocks; + Word16 iNumIterations; + Word16 iNumBlocks; } ISAR_BIN_HR_SPLIT_LCLD_ENC, *ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE; typedef struct { - float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; - float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; -} ISAR_CLDFB_PLC, *ISAR_CLDFB_PLC_HANDLE; + Word32 Cldfb_Prev_BinReal_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_Prev_BinImag_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + Word16 Q_Prev_Bin_fx; + Word32 xf_bet_fx[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; +} ISAR_CLDFB_PLC, *ISAR_CLDFB_PLC_HANDLE; typedef struct { ISAR_CLDFB_PLC CldfbPLC_state; - int16_t prev_bfi; - int16_t bf_count; - int16_t iNumSubSets; + Word16 prev_bfi; + Word16 bf_count; + Word16 iNumSubSets; } ISAR_SPLIT_REND_PLC_STRUCT, *ISAR_SPLIT_REND_PLC_HANDLE; - typedef struct isar_binaural_head_rot_split_rendering_lcld_dec_struct { void *pLcld_dec; - int32_t iChannels; + Word32 iChannels; LCLDDecoder *psLCLDDecoder; - float ***pppfDecLCLDReal; - float ***pppfDecLCLDImag; + Word32 ***pppfDecLCLDReal_fx; + Word32 ***pppfDecLCLDImag_fx; #ifdef CLDFB_DEBUG FILE *cldfbOut; int16_t numFrame; #endif ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC; - int16_t iNumBlocks; - int16_t iNumIterations; + Word16 iNumBlocks; + Word16 iNumIterations; } ISAR_BIN_HR_SPLIT_LCLD_DEC, *ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE; - typedef struct isar_binaural_head_rot_split_post_rendering_struct { ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; @@ -202,16 +205,17 @@ typedef struct isar_binaural_head_rot_split_post_rendering_struct int16_t low_Res; float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 fix_pos_rot_mat_fx[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q31 */ ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - float mixer_mat_re[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mixer_mat_im[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float gd_mem[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; + Word32 mixer_mat_re_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mixer_mat_im_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 gd_mem_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; #else - float mixer_mat_re[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mixer_mat_im[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float gd_mem[1][MAX_SPLIT_REND_MD_BANDS]; + Word32 mixer_mat_re_fx[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mixer_mat_im_fx[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 gd_mem_fx[1][MAX_SPLIT_REND_MD_BANDS]; #endif int16_t cf_flag; HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; @@ -226,6 +230,7 @@ typedef struct { int16_t num_poses; float relative_head_poses[MAX_HEAD_ROT_POSES][3]; + Word32 relative_head_poses_fx[MAX_HEAD_ROT_POSES][3]; /* Q22 */ int16_t dof; int16_t hq_mode; ISAR_SPLIT_REND_ROT_AXIS rot_axis; @@ -243,6 +248,7 @@ typedef struct } ISAR_SPLIT_POST_REND_WRAPPER; + typedef struct { MULTI_BIN_REND_POSE_DATA multiBinPoseData; @@ -250,10 +256,12 @@ typedef struct ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; ISAR_LC3PLUS_ENC_HANDLE hLc3plusEnc; - float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ - int32_t lc3plusDelaySamples; - + float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ + Word32 *lc3plusDelayBuffers_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ + Word16 lc3plusDelayBuffers_q; + Word32 lc3plusDelaySamples; } SPLIT_REND_WRAPPER; + #endif #endif /* ISAR_STAT_H */ diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c index af43d273e..178718a60 100644 --- a/lib_isar/lib_isar_post_rend.c +++ b/lib_isar/lib_isar_post_rend.c @@ -37,7 +37,7 @@ #include "isar_prot.h" #include "prot.h" #include "ivas_prot.h" - +#include "prot_fx2.h" #ifndef SPLIT_REND_WITH_HEAD_ROT int32_t ISAR_POST_REND_void_func( void ) @@ -51,6 +51,7 @@ int32_t ISAR_POST_REND_void_func( void ) #include #include #include "wmc_auto.h" +#include "prot_fx2.h" /*-------------------------------------------------------------------* @@ -100,7 +101,7 @@ typedef struct AUDIO_CONFIG inConfig; ISAR_POST_REND_InputId id; IVAS_REND_AudioBuffer inputBuffer; - float gain; /* Linear, not in dB */ + Word32 gain_fx; /* Linear, not in dB */ rendering_context ctx; int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */ } input_base; @@ -109,7 +110,7 @@ typedef struct { input_base base; ISAR_SPLIT_POST_REND_WRAPPER splitPostRendWrapper; - float *bufferData; + Word32 *bufferData_fx; int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ ISAR_POST_REND_BitstreamBuffer *hBits; } input_split_post_rend; @@ -142,28 +143,26 @@ struct ISAR_POST_REND * * *-------------------------------------------------------------------*/ - ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( const AUDIO_CONFIG config ) { ISAR_POST_REND_AudioConfigType type; - switch ( config ) + SWITCH( config ) { case IVAS_AUDIO_CONFIG_BINAURAL: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL; - break; + BREAK; default: type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN; - break; + BREAK; } return type; } - /*-------------------------------------------------------------------* * Local function prototypes *-------------------------------------------------------------------*/ @@ -171,24 +170,22 @@ ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ - -static ivas_error allocateInputBaseBufferData( - float **data, - const int16_t data_size ) +static ivas_error allocateInputBaseBufferData_fx( + Word32 **data, + const Word16 data_size ) { - *data = (float *) malloc( data_size * sizeof( float ) ); - if ( *data == NULL ) + *data = (Word32 *) malloc( data_size * sizeof( Word32 ) ); + IF( *data == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for input base buffer data" ); } return IVAS_ERR_OK; } - -static void freeInputBaseBufferData( - float **data ) +static void freeInputBaseBufferData_fx( + Word32 **data ) { - if ( *data != NULL ) + IF( *data != NULL ) { free( *data ); *data = NULL; @@ -197,13 +194,12 @@ static void freeInputBaseBufferData( return; } - static IVAS_QUATERNION quaternionInit( void ) { IVAS_QUATERNION q; - q.w = 1.0f; - q.x = q.y = q.z = 0.0f; + q.w_fx = ONE_IN_Q22; + q.x_fx = q.y_fx = q.z_fx = 0; return q; } @@ -245,20 +241,20 @@ static void convertInternalBitsBuffToBitsBuffer( return; } -static void copyBufferTo2dArray( +static void copyBufferTo2dArray_fx( const IVAS_REND_AudioBuffer buffer, - float array[][L_FRAME48k] ) + Word32 array[][L_FRAME48k] ) { - uint32_t smplIdx; - uint32_t chnlIdx; - const float *readPtr; + UWord32 smplIdx; + UWord32 chnlIdx; + const Word32 *readPtr; assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); - readPtr = buffer.data; + readPtr = buffer.data_fx; - for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) + FOR( chnlIdx = 0; chnlIdx < (UWord32) buffer.config.numChannels; ++chnlIdx ) { - for ( smplIdx = 0; smplIdx < (uint32_t) buffer.config.numSamplesPerChannel; ++smplIdx ) + FOR( smplIdx = 0; smplIdx < (UWord32) buffer.config.numSamplesPerChannel; ++smplIdx ) { array[chnlIdx][smplIdx] = *readPtr++; } @@ -267,19 +263,27 @@ static void copyBufferTo2dArray( return; } -static void accumulate2dArrayToBuffer( - float array[][L_FRAME48k], - const IVAS_REND_AudioBuffer *buffer ) +static void accumulate2dArrayToBuffer_fx( + Word32 array[][L_FRAME48k], + Word16 Q_out[][BINAURAL_CHANNELS], + Word16 Q_max, + const IVAS_REND_AudioBuffer *buffer, + Word16 num_subframes, + Word16 subframe_length ) { - int16_t smplIdx, chnlIdx; - float *writePtr; + Word16 smplIdx, chnlIdx; + Word32 *writePtr; - writePtr = buffer->data; - for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) + writePtr = buffer->data_fx; + FOR( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) { - for ( smplIdx = 0; smplIdx < buffer->config.numSamplesPerChannel; ++smplIdx ) + FOR( Word16 sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - *writePtr++ += array[chnlIdx][smplIdx]; + FOR( smplIdx = 0; smplIdx < subframe_length; ++smplIdx ) + { + //*writePtr++ += (float) array[chnlIdx][( sf_idx * subframe_length ) + smplIdx] / powf( 2, Q_out[sf_idx][chnlIdx] ); + *writePtr++ += L_shl( array[chnlIdx][( sf_idx * subframe_length ) + smplIdx], sub( Q_max, Q_out[sf_idx][chnlIdx] ) ); + } } } @@ -294,49 +298,44 @@ static void accumulate2dArrayToBuffer( #ifndef DISABLE_LIMITER /*! r: number of clipped output samples */ -static int32_t limitRendererOutput( +static Word32 limitRendererOutput_fx( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - float *output, /* i/o: I/O buffer */ - const int16_t output_frame, /* i : number of samples per channel in the buffer */ - const float threshold /* i : signal amplitude above which limiting starts to be applied */ -) + Word32 *output, /* i/o: I/O buffer */ + const Word16 output_frame, /* i : number of samples per channel in the buffer */ + const Word32 threshold, /* i : signal amplitude above which limiting starts to be applied */ + Word16 q_factor ) /* i : q factor of output samples */ { - int16_t i; - float **channels; - int16_t num_channels; - int32_t numClipping = 0; + Word16 i; + Word32 **channels; + Word16 num_channels; + Word32 numClipping = 0; /* return early if given bad parameters */ - if ( hLimiter == NULL || output == NULL || output_frame <= 0 ) + IF( hLimiter == NULL || output == NULL || output_frame <= 0 ) { return 0; } - channels = hLimiter->channel_ptrs; + channels = hLimiter->channel_ptrs_fx; num_channels = hLimiter->num_channels; - for ( i = 0; i < num_channels; ++i ) + FOR( i = 0; i < num_channels; ++i ) { channels[i] = output + i * output_frame; } - limiter_process( hLimiter, output_frame, threshold, 0, NULL ); + limiter_process_fx( hLimiter, output_frame, threshold, 0, NULL, q_factor ); /* Apply clipping to buffer in case the limiter let through some samples > 1.0f */ - for ( i = 0; i < output_frame * num_channels; ++i ) + FOR( i = 0; i < output_frame * num_channels; ++i ) { -#ifdef DEBUGGING - if ( output[i] < INT16_MIN || output[i] > INT16_MAX ) - { - ++numClipping; - } -#endif - output[i] = min( max( INT16_MIN, output[i] ), INT16_MAX ); + output[i] = min( max( L_shl( INT16_MIN, q_factor ), output[i] ), L_shl( INT16_MAX, q_factor ) ); } return numClipping; } + #endif @@ -345,19 +344,18 @@ static int32_t limitRendererOutput( * * *-------------------------------------------------------------------*/ - static ivas_error validateOutputSampleRate( - const int32_t sampleRate, + const Word32 sampleRate, const AUDIO_CONFIG outConfig ) { - if ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && sampleRate != 48000 ) + IF( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && NE_32( sampleRate, 48000 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); } - else + ELSE { /* Otherwise rendering to binaural, support the same set as IVAS decoder */ - switch ( sampleRate ) + SWITCH( sampleRate ) { case 8000: case 16000: @@ -370,31 +368,29 @@ static ivas_error validateOutputSampleRate( } } - /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ - static ivas_error initLimiter( IVAS_LIMITER_HANDLE *phLimiter, - const int16_t numChannels, - const int32_t sampleRate ) + const Word16 numChannels, + const Word32 sampleRate ) { ivas_error error; /* If re-initializing with unchanged values, return early */ - if ( *phLimiter != NULL && ( *phLimiter )->num_channels == numChannels && ( *phLimiter )->sampling_rate == sampleRate ) + IF( *phLimiter != NULL && ( *phLimiter )->num_channels == numChannels && ( *phLimiter )->sampling_rate == sampleRate ) { return IVAS_ERR_OK; } /* Support re-init: close if already allocated */ - if ( *phLimiter != NULL ) + IF( *phLimiter != NULL ) { - ivas_limiter_close( phLimiter ); + ivas_limiter_close_splitRend( phLimiter ); } - if ( ( error = ivas_limiter_open( phLimiter, numChannels, sampleRate ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_limiter_open_splitRend( phLimiter, numChannels, sampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -402,26 +398,25 @@ static ivas_error initLimiter( return IVAS_ERR_OK; } - static ivas_error initHeadRotation( ISAR_POST_REND_HANDLE hIvasRend ) { - int16_t i, crossfade_len; - float tmp; + Word16 i, crossfade_len; + Word32 tmp; /* Head rotation is enabled by default */ hIvasRend->headRotData.headRotEnabled = 1; /* Initialize 5ms crossfade */ - crossfade_len = L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES; - tmp = 1.f / ( crossfade_len - 1 ); - for ( i = 0; i < crossfade_len; i++ ) + crossfade_len = 240 /*L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES*/; + tmp = 8985287 /*1.f / ( crossfade_len - 1 )*/; + FOR( i = 0; i < crossfade_len; i++ ) { - hIvasRend->headRotData.crossfade[i] = i * tmp; + hIvasRend->headRotData.crossfade_fx[i] = W_extract_l( W_mult0_32_32( i, tmp ) ); } /* Initialize with unit quaternions */ - for ( i = 0; i < hIvasRend->num_subframes; ++i ) + FOR( i = 0; i < hIvasRend->num_subframes; ++i ) { hIvasRend->headRotData.headPositions[i] = quaternionInit(); } @@ -430,34 +425,31 @@ static ivas_error initHeadRotation( return IVAS_ERR_OK; } - - -static void initRendInputBase( +static void initRendInputBase_fx( input_base *inputBase, const AUDIO_CONFIG inConfig, const IVAS_REND_InputId id, const rendering_context rendCtx, - float *dataBuf, - const int16_t dataBufSize ) + Word32 *dataBuf, + const Word16 dataBufSize ) { inputBase->inConfig = inConfig; inputBase->id = id; - inputBase->gain = 1.0f; + inputBase->gain_fx = MAX_32; inputBase->ctx = rendCtx; inputBase->numNewSamplesPerChannel = 0; inputBase->inputBuffer.config.numSamplesPerChannel = 0; inputBase->inputBuffer.config.numChannels = 0; - inputBase->inputBuffer.data = dataBuf; - if ( inputBase->inputBuffer.data != NULL ) + inputBase->inputBuffer.data_fx = dataBuf; + IF( inputBase->inputBuffer.data_fx != NULL ) { - set_zero( inputBase->inputBuffer.data, dataBufSize ); + set_l( inputBase->inputBuffer.data_fx, 0, dataBufSize ); } return; } - static rendering_context getRendCtx( ISAR_POST_REND_HANDLE hIvasRend ) { @@ -480,7 +472,7 @@ static rendering_context getRendCtx( static ivas_error getRendInputNumChannels( const void *rendInput, - int16_t *numInChannels ) + Word16 *numInChannels ) { /* Using a void pointer for this function to be reusable for any input type (input_ism, input_mc, input_sba). Assumptions: - input_base is always the first member in the input struct */ @@ -491,7 +483,6 @@ static ivas_error getRendInputNumChannels( return IVAS_ERR_OK; } - static ivas_error updateSplitPostRendPanGains( input_split_post_rend *inputSplitPostRend, const AUDIO_CONFIG outConfig, @@ -505,12 +496,12 @@ static ivas_error updateSplitPostRendPanGains( ivas_error error; rendering_context rendCtx; LC3PLUS_CONFIG config; - int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + Word16 iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; (void) outConfig; rendCtx = inputSplitPostRend->base.ctx; - isar_renderSplitGetMultiBinPoseData( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); + isar_renderSplitGetMultiBinPoseData_fx( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS config.high_res_mode_enabled = ( hRendCfg->lc3plus_highres != 0 ); @@ -519,31 +510,31 @@ static ivas_error updateSplitPostRendPanGains( #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS config.isar_frame_duration_us = hRendCfg->isar_frame_size_ms * 1000; #else - if ( num_subframes != MAX_PARAM_SPATIAL_SUBFRAMES ) + IF( NE_16( num_subframes, MAX_PARAM_SPATIAL_SUBFRAMES ) ) { - if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) { - config.isar_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; + config.ivas_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; } - else + ELSE { - config.isar_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; + config.ivas_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; } iNumLCLDIterationsPerFrame = 1; } - else + ELSE { - config.isar_frame_duration_us = 20000; + config.ivas_frame_duration_us = 20000; } #endif - if ( hRendCfg->codec_frame_size_ms > 0 ) + IF( GT_16( hRendCfg->codec_frame_size_ms, 0 ) ) { - iNumLCLDIterationsPerFrame = (int16_t) config.isar_frame_duration_us / ( 1000 * hRendCfg->codec_frame_size_ms ); + iNumLCLDIterationsPerFrame = (Word16) config.isar_frame_duration_us / ( 1000 * hRendCfg->codec_frame_size_ms ); iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); iNumBlocksPerFrame = CLDFB_NO_COL_MAX * hRendCfg->codec_frame_size_ms / 20; } - else + ELSE { iNumLCLDIterationsPerFrame = 1; iNumBlocksPerFrame = CLDFB_NO_COL_MAX; @@ -552,23 +543,23 @@ static ivas_error updateSplitPostRendPanGains( config.channels = BINAURAL_CHANNELS; config.samplerate = *inputSplitPostRend->base.ctx.pOutSampleRate; - if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LCLD ) + IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LCLD ) { - if ( ( error = isar_splitBinLCLDDecOpen( &inputSplitPostRend->splitPostRendWrapper.hSplitBinLCLDDec, *inputSplitPostRend->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK ) + IF( ( error = isar_splitBinLCLDDecOpen( &inputSplitPostRend->splitPostRendWrapper.hSplitBinLCLDDec, *inputSplitPostRend->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK ) { return error; } } - else if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + ELSE IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) { - if ( ( error = ISAR_LC3PLUS_DEC_Open( config, - &inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) + IF( ( error = ISAR_LC3PLUS_DEC_Open( config, + &inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) { return error; } } - if ( ( error = isar_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + IF( ( error = isar_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -576,7 +567,6 @@ static ivas_error updateSplitPostRendPanGains( return IVAS_ERR_OK; } - static ivas_error setRendInputActiveSplitPostRend( void *input, const AUDIO_CONFIG inConfig, @@ -597,12 +587,13 @@ static ivas_error setRendInputActiveSplitPostRend( rendCtx = inputSplitPostRend->base.ctx; outConfig = *rendCtx.pOutConfig; - if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + IF( ( error = allocateInputBaseBufferData_fx( &inputSplitPostRend->bufferData_fx, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) { return error; } - initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ); + initRendInputBase_fx( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData_fx, MAX_CLDFB_BIN_BUFFER_LENGTH ); + inputSplitPostRend->numCachedSamples = 0; if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg @@ -618,7 +609,6 @@ static ivas_error setRendInputActiveSplitPostRend( return IVAS_ERR_OK; } - static void clearInputSplitRend( input_split_post_rend *inputSplitRend ) { @@ -626,21 +616,21 @@ static void clearInputSplitRend( rendCtx = inputSplitRend->base.ctx; - freeInputBaseBufferData( &inputSplitRend->bufferData ); + freeInputBaseBufferData_fx( &inputSplitRend->bufferData_fx ); - initRendInputBase( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); + initRendInputBase_fx( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); - if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) + IF( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) { isar_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); } - if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + IF( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) { isar_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); } - if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) + IF( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) { ISAR_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); } @@ -654,39 +644,37 @@ static void clearInputSplitRend( * * *------------------------------------------------------------------------*/ - ivas_error ISAR_POST_REND_open( ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ - const int32_t outputSampleRate, /* i : output sampling rate */ - const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const Word32 outputSampleRate, /* i : output sampling rate */ + const AUDIO_CONFIG outConfig, /* i : output audio config */ const bool asHrtfBinary, /* i : load hrtf binary file */ - const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ - const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ - const int16_t num_subframes /* i : number of subframes */ -) + const Word16 nonDiegeticPan, /* i : non-diegetic object flag */ + const Word32 nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const Word16 num_subframes ) /* i : number of subframes */ { - int16_t i; + Word16 i; ISAR_POST_REND_HANDLE hIvasRend; ivas_error error; - int16_t numOutChannels; + Word16 numOutChannels; (void) asHrtfBinary; (void) nonDiegeticPan; (void) nonDiegeticPanGain; /* Validate function arguments */ - if ( phIvasRend == NULL ) + IF( phIvasRend == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) + IF( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) { return error; } *phIvasRend = (ISAR_POST_REND_HANDLE) malloc( sizeof( struct ISAR_POST_REND ) ); - if ( *phIvasRend == NULL ) + IF( *phIvasRend == NULL ) { return IVAS_ERR_FAILED_ALLOC; } @@ -702,51 +690,49 @@ ivas_error ISAR_POST_REND_open( hIvasRend->num_subframes = num_subframes; /* Initialize limiter */ - if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + IF( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK ) + IF( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK ) { return error; } /* Initialize headrotation data */ - if ( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) + IF( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) { return error; } /* Initialize inputs */ - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + initRendInputBase_fx( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); isar_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper ); hIvasRend->splitRendBFI = 0; - hIvasRend->inputsSplitPost[i].bufferData = NULL; + hIvasRend->inputsSplitPost[i].bufferData_fx = NULL; } return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_NumOutChannels() * * *-------------------------------------------------------------------*/ - ivas_error ISAR_POST_REND_NumOutChannels( ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - int16_t *numOutChannels /* o : number of output channels */ + Word16 *numOutChannels /* o : number of output channels */ ) { /* Validate function arguments */ - if ( hIvasRend == NULL || numOutChannels == NULL ) + IF( hIvasRend == NULL || numOutChannels == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -756,24 +742,22 @@ ivas_error ISAR_POST_REND_NumOutChannels( return IVAS_ERR_OK; } - static IVAS_REND_InputId makeInputId( AUDIO_CONFIG config, - const int32_t inputIndex ) + const Word32 inputIndex ) { /* Put config type in second byte (from LSB), put index + 1 in first byte * * Index is incremented here so that a valid ID can never be 0. */ - return (IVAS_REND_InputId) ( ( ( (uint32_t) isar_getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) ); + return (IVAS_REND_InputId) ( ( ( (UWord32) isar_getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) ); } - static ivas_error getInputById( ISAR_POST_REND_HANDLE hIvasRend, const IVAS_REND_InputId inputId, void **ppInput ) { - int32_t inputIndex; + Word32 inputIndex; IVAS_REND_AudioConfigType configType; input_base *pInputBase; @@ -782,11 +766,11 @@ static ivas_error getInputById( configType = ( inputId & 0xFF00 ) >> 8; /* Validate values derived from input ID */ - if ( inputIndex < 0 ) + IF( inputIndex < 0 ) { return IVAS_ERR_INVALID_INPUT_ID; } - switch ( configType ) + SWITCH( configType ) { case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) @@ -794,13 +778,13 @@ static ivas_error getInputById( return IVAS_ERR_INVALID_INPUT_ID; } pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; - break; + BREAK; default: return IVAS_ERR_INVALID_INPUT_ID; } /* Ensure input ID matches and that input is active */ - if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + IF( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) { return IVAS_ERR_INVALID_INPUT_ID; } @@ -816,29 +800,28 @@ static ivas_error getInputById( * * *-------------------------------------------------------------------*/ - ivas_error ISAR_POST_REND_SetInputGain( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ - const float gain /* i : linear gain (not in dB) */ + const Word32 gain /* i : linear gain (not in dB) */ ) { input_base *inputBase; ivas_error error; /* Validate function arguments */ - if ( hIvasRend == NULL ) + IF( hIvasRend == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) { printf( "Hoo\n" ); return error; } - inputBase->gain = gain; + inputBase->gain_fx = gain; return IVAS_ERR_OK; } @@ -848,7 +831,7 @@ static ivas_error getConstInputById( const ISAR_POST_REND_InputId inputId, const void **ppInput ) { - int32_t inputIndex; + Word32 inputIndex; IVAS_REND_AudioConfigType configType; const input_base *pInputBase; @@ -857,25 +840,25 @@ static ivas_error getConstInputById( configType = ( inputId & 0xFF00 ) >> 8; /* Validate values derived from input ID */ - if ( inputIndex < 0 ) + IF( inputIndex < 0 ) { return IVAS_ERR_INVALID_INPUT_ID; } - switch ( configType ) + SWITCH( configType ) { case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: - if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + IF( inputIndex > RENDERER_MAX_BIN_INPUTS ) { return IVAS_ERR_INVALID_INPUT_ID; } pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; - break; + BREAK; default: return IVAS_ERR_INVALID_INPUT_ID; } /* Ensure input ID matches and that input is active */ - if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + IF( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) { return IVAS_ERR_INVALID_INPUT_ID; } @@ -886,12 +869,11 @@ static ivas_error getConstInputById( return IVAS_ERR_OK; } - static ivas_error findFreeInputSlot( const void *inputs, - const int32_t inputStructSize, - const int32_t maxInputs, - int32_t *inputIndex ) + const Word32 inputStructSize, + const Word32 maxInputs, + Word32 *inputIndex ) { /* Using a void pointer and a separately provided size is a hack for this function to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa). @@ -900,27 +882,28 @@ static ivas_error findFreeInputSlot( - provided size is correct */ - int32_t i; + Word32 i; bool canAddInput; - const uint8_t *pByte; + const UWord8 *pByte; const input_base *pInputBase; canAddInput = false; - + pByte = inputs; /* Find first unused input in array */ - for ( i = 0, pByte = inputs; i < maxInputs; ++i, pByte += inputStructSize ) + FOR( i = 0; i < maxInputs; ++i ) { pInputBase = (const input_base *) pByte; - if ( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + IF( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) { *inputIndex = i; canAddInput = true; - break; + BREAK; } + pByte += inputStructSize; } - if ( !canAddInput ) + IF( !canAddInput ) { return IVAS_ERR_TOO_MANY_INPUTS; } @@ -928,7 +911,6 @@ static ivas_error findFreeInputSlot( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_AddInput() * @@ -942,37 +924,37 @@ ivas_error ISAR_POST_REND_AddInput( ) { ivas_error error; - int32_t maxNumInputsOfType; + Word32 maxNumInputsOfType; void *inputsArray; - int32_t inputStructSize; + Word32 inputStructSize; ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, ISAR_SPLIT_REND_CONFIG_DATA * #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS , int16_t #endif ); - int32_t inputIndex; + Word32 inputIndex; /* Validate function arguments */ - if ( hIvasRend == NULL || inputId == NULL ) + IF( hIvasRend == NULL || inputId == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - switch ( isar_getAudioConfigType( inConfig ) ) + SWITCH( isar_getAudioConfigType( inConfig ) ) { case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS; inputsArray = hIvasRend->inputsSplitPost; inputStructSize = sizeof( *hIvasRend->inputsSplitPost ); activateInput = setRendInputActiveSplitPostRend; - break; + BREAK; default: return IVAS_ERR_INVALID_INPUT_FORMAT; } /* Find first free input in array corresponding to input type */ - if ( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) + IF( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) { return error; } @@ -991,7 +973,6 @@ ivas_error ISAR_POST_REND_AddInput( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_GetInputNumChannels() * @@ -1001,24 +982,24 @@ ivas_error ISAR_POST_REND_AddInput( ivas_error ISAR_POST_REND_GetInputNumChannels( ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ - int16_t *numChannels /* o : number of channels of the input */ + Word16 *numChannels /* o : number of channels of the input */ ) { ivas_error error; const input_base *pInput; /* Validate function arguments */ - if ( hIvasRend == NULL || numChannels == NULL ) + IF( hIvasRend == NULL || numChannels == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK ) + IF( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK ) + IF( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK ) { return error; } @@ -1026,7 +1007,6 @@ ivas_error ISAR_POST_REND_GetInputNumChannels( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_GetDelay() * @@ -1035,16 +1015,16 @@ ivas_error ISAR_POST_REND_GetInputNumChannels( ivas_error ISAR_POST_REND_GetDelay( ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */ - int16_t *nSamples, /* o : Renderer delay in samples */ - int32_t *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ + Word16 *nSamples, /* o : Renderer delay in samples */ + Word32 *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ ) { - int16_t i; - int32_t latency_ns; - int32_t max_latency_ns; + Word16 i; + Word32 latency_ns; + Word32 max_latency_ns; /* Validate function arguments */ - if ( hIvasRend == NULL || nSamples == NULL || timeScale == NULL ) + IF( hIvasRend == NULL || nSamples == NULL || timeScale == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1054,41 +1034,37 @@ ivas_error ISAR_POST_REND_GetDelay( max_latency_ns = 0; /* Compute the maximum delay across all inputs */ - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) - { - if ( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) - { + FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ){ + IF( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ){ latency_ns = 0; - if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL ) - { - int32_t lc3plusDelaySamples; - ISAR_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples ); - latency_ns = (int32_t) roundf( lc3plusDelaySamples * 1000000000.f / *timeScale ); - } - if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - latency_ns += IVAS_FB_DEC_DELAY_NS; - } - else if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL ) - { - latency_ns += IVAS_FB_DEC_DELAY_NS; - } - max_latency_ns = max( max_latency_ns, latency_ns ); - } + IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL ) + { + int32_t lc3plusDelaySamples; + ISAR_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples ); + latency_ns = (Word32) ( ( ( (Word64) lc3plusDelaySamples * 1000000000 ) + ( *timeScale / 2 ) ) / *timeScale ); } + IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + ELSE IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + max_latency_ns = max( max_latency_ns, latency_ns ); +} +} - *nSamples = (int16_t) roundf( (float) max_latency_ns * *timeScale / 1000000000.f ); +*nSamples = (Word16) ( ( ( (Word64) max_latency_ns * *timeScale ) + 500000000 ) / 1000000000 ); - return IVAS_ERR_OK; +return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_FeedInputAudio() * * *-------------------------------------------------------------------*/ - ivas_error ISAR_POST_REND_FeedInputAudio( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ @@ -1097,68 +1073,66 @@ ivas_error ISAR_POST_REND_FeedInputAudio( { ivas_error error; input_base *inputBase; - int16_t numInputChannels; - int16_t cldfb2tdSampleFact; + Word16 numInputChannels; + Word16 cldfb2tdSampleFact; /* Validate function arguments */ - if ( hIvasRend == NULL || inputAudio.data == NULL ) + IF( hIvasRend == NULL || inputAudio.data_fx == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } cldfb2tdSampleFact = ( inputAudio.config.is_cldfb ) ? 2 : 1; - if ( inputAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 0 ) || - ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 1 ) ) + IF( LE_16( inputAudio.config.numSamplesPerChannel, 0 ) || ( LT_16( MAX_BUFFER_LENGTH_PER_CHANNEL, inputAudio.config.numSamplesPerChannel ) && EQ_16( inputAudio.config.is_cldfb, 0 ) ) || + ( LT_16( DEPR_i_mult( MAX_BUFFER_LENGTH_PER_CHANNEL, cldfb2tdSampleFact ), inputAudio.config.numSamplesPerChannel ) && EQ_16( inputAudio.config.is_cldfb, 1 ) ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" ); } - if ( inputAudio.config.numChannels <= 0 || MAX_INPUT_CHANNELS < inputAudio.config.numChannels ) + IF( LE_16( inputAudio.config.numChannels, 0 ) || LT_16( MAX_INPUT_CHANNELS, inputAudio.config.numChannels ) ) { return IVAS_ERR_WRONG_NUM_CHANNELS; } - if ( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && - hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && - hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && - ( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut ) + IF( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + ( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut ) { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } - if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) { printf( "Foo\n" ); return error; } - if ( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK ) + IF( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK ) { return error; } - if ( numInputChannels != inputAudio.config.numChannels ) + IF( numInputChannels != inputAudio.config.numChannels ) { return IVAS_ERR_WRONG_NUM_CHANNELS; } inputBase->inputBuffer.config = inputAudio.config; - mvr2r( inputAudio.data, inputBase->inputBuffer.data, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); + mvl2l( inputAudio.data_fx, inputBase->inputBuffer.data_fx, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel / cldfb2tdSampleFact; return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_InitConfig() * * *-------------------------------------------------------------------*/ - ivas_error ISAR_POST_REND_InitConfig( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const AUDIO_CONFIG outAudioConfig /* i : output audioConfig */ @@ -1168,16 +1142,16 @@ ivas_error ISAR_POST_REND_InitConfig( rendererConfigEnabled = ( isar_getAudioConfigType( outAudioConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ); - if ( rendererConfigEnabled ) + IF( rendererConfigEnabled ) { hIvasRend->rendererConfigEnabled = 1; } - else + ELSE { hIvasRend->rendererConfigEnabled = 0; } - if ( rendererConfigEnabled ) + IF( rendererConfigEnabled ) { hIvasRend->splitRenderConfig.splitRendBitRate = SPLIT_REND_768k; hIvasRend->splitRenderConfig.dof = 3; @@ -1195,21 +1169,19 @@ ivas_error ISAR_POST_REND_InitConfig( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_GetRenderConfig() * * *-------------------------------------------------------------------*/ - -int16_t ISAR_POST_REND_GetRenderConfig( +Word16 ISAR_POST_REND_GetRenderConfig( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ ) { ISAR_SPLIT_REND_CONFIG_DATA hRCin; - if ( hIvasRend == NULL ) + IF( hIvasRend == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1230,13 +1202,11 @@ int16_t ISAR_POST_REND_GetRenderConfig( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_FeedSplitBinauralBitstream() * * *-------------------------------------------------------------------*/ - ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_REND_InputId inputId, /* i : ID of the input */ @@ -1248,12 +1218,12 @@ ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( input_split_post_rend *inputSplitPostRend; /* Validate function arguments */ - if ( hIvasRend == NULL || hBits == NULL ) + IF( hIvasRend == NULL || hBits == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) { printf( "Goo\n" ); return error; @@ -1265,7 +1235,6 @@ ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_SetHeadRotation() * @@ -1277,18 +1246,18 @@ ivas_error ISAR_POST_REND_SetHeadRotation( const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ - const int16_t sf_idx /* i : subframe index */ + const Word16 sf_idx /* i : subframe index */ ) { IVAS_QUATERNION rotQuat; /* Validate function arguments */ - if ( hIvasRend == NULL ) + IF( hIvasRend == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( isar_getAudioConfigType( hIvasRend->outputConfig ) != ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ) + IF( isar_getAudioConfigType( hIvasRend->outputConfig ) != ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ) { /* Head rotation can be set only with binaural output */ return IVAS_ERR_INVALID_OUTPUT_FORMAT; @@ -1297,11 +1266,11 @@ ivas_error ISAR_POST_REND_SetHeadRotation( hIvasRend->headRotData.headRotEnabled = 1; /* check for Euler angle signaling */ - if ( headRot.w == -3.0f ) + IF( EQ_32( headRot.w_fx, -12582912 ) ) { - Euler2Quat( deg2rad( headRot.x ), deg2rad( headRot.y ), deg2rad( headRot.z ), &rotQuat ); + Euler2Quat_fx( deg2rad_fx( headRot.x_fx ), deg2rad_fx( headRot.y_fx ), deg2rad_fx( headRot.z_fx ), &rotQuat ); } - else + ELSE { rotQuat = headRot; } @@ -1322,7 +1291,7 @@ ivas_error ISAR_POST_REND_SetHeadRotation( ivas_error ISAR_POST_REND_SetSplitRendBFI( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const int16_t bfi /* i: BFI flag */ + const Word16 bfi /* i: BFI flag */ ) { hIvasRend->splitRendBFI = bfi; @@ -1335,28 +1304,27 @@ ivas_error ISAR_POST_REND_SetSplitRendBFI( * Local functions *-------------------------------------------------------------------*/ - static ivas_error splitBinLc3plusDecode( ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin, ISAR_SPLIT_REND_BITS_HANDLE bits, - float outputBuffer[BINAURAL_CHANNELS][L_FRAME48k], + Word32 outputBuffer[BINAURAL_CHANNELS][L_FRAME48k], #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction, #endif const int16_t SplitRendBFI ) { ivas_error error; - float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + Word32 *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - int32_t lc3plusBitstreamSize; + Word32 lc3plusBitstreamSize; #else - int32_t lc3plusBitrateId, lc3plusBitstreamSize; + Word32 lc3plusBitrateId, lc3plusBitstreamSize; #endif push_wmops( "splitBinLc3plusDecode" ); assert( hSplitBin->hLc3plusDec != NULL ); - for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + for ( Word16 i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) { channel_ptrs[i] = outputBuffer[i]; } @@ -1375,7 +1343,7 @@ static ivas_error splitBinLc3plusDecode( #else /* Read LC3plus bitstream size info */ lc3plusBitrateId = ISAR_SPLIT_REND_BITStream_read_int32( bits, 8 ); - lc3plusBitstreamSize = isar_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.isar_frame_duration_us / 1000 ) ); + lc3plusBitstreamSize = isar_get_lc3plus_size_from_id( (Word8) lc3plusBitrateId, pose_correction, (Word16) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) ); #endif if ( ( error = ISAR_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) @@ -1395,34 +1363,39 @@ static ivas_error splitBinLc3plusDecode( return IVAS_ERR_OK; } - static ivas_error renderSplitBinauralWithPostRot( input_split_post_rend *splitBinInput, IVAS_REND_AudioBuffer outAudio, - const int16_t SplitRendBFI, - const int16_t num_subframes ) + const Word16 SplitRendBFI, + const Word16 num_subframes ) { - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; ivas_error error; - float Cldfb_RealBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_RealBuffer_Binaural_5ms_fx[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 Cldfb_ImagBuffer_Binaural_5ms_fx[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; int16_t sf_idx, ch_idx; ISAR_SPLIT_REND_BITS_DATA bits; - float tmpCrendBuffer[BINAURAL_CHANNELS][L_FRAME48k]; - float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k]; + Word32 tmpCrendBuffer_fx[BINAURAL_CHANNELS][L_FRAME48k] = { 0 }; + Word32 tmpCrendBuffer_sf_fx[BINAURAL_CHANNELS][L_FRAME48k] = { 0 }; + ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin; - int8_t isPostRendInputCldfb; - int16_t chnlIdx, slotIdx, smplIdx; - int16_t preRendFrameSize_ms; - int16_t outBufNumSamplesPerChannel, outBufNumColPerChannel; - int16_t numSamplesPerChannelCacheSize, numColPerChannelCacheSize; - float *readPtr, *writePtr; + Word8 isPostRendInputCldfb; + Word16 chnlIdx, slotIdx, smplIdx; + Word16 preRendFrameSize_ms; + Word16 outBufNumSamplesPerChannel, outBufNumColPerChannel; + Word16 numSamplesPerChannelCacheSize, numColPerChannelCacheSize; + + Word32 *readPtr_fx, *writePtr_fx; + Word16 Q_cldfb_final[MAX_PARAM_SPATIAL_SUBFRAMES] = { 0 }; + Word16 Q_out[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS] = { 0 }; + #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS uint32_t ivas_frame_duration_us; #endif - int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + Word16 iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; const ISAR_POST_REND_HeadRotData *pHeadRotData; isPostRendInputCldfb = 0; @@ -1450,33 +1423,33 @@ static ivas_error renderSplitBinauralWithPostRot( iNumLCLDIterationsPerFrame = 1; iNumBlocksPerFrame = CLDFB_NO_COL_MAX; - if ( splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + IF( splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) { iNumBlocksPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumBlocks; iNumLCLDIterationsPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumIterations; } outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / num_subframes; - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { QuaternionsPost[sf_idx] = pHeadRotData->headPositions[sf_idx]; } - if ( !SplitRendBFI ) + IF( !SplitRendBFI ) { hSplitBin->first_good_frame_received = 1; } - if ( hSplitBin->first_good_frame_received == 1 ) + IF( EQ_16( hSplitBin->first_good_frame_received, 1 ) ) { - if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { - if ( !SplitRendBFI ) + IF( !SplitRendBFI ) { #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); + isar_splitBinPostRendMdDec_fx( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); #else - isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); + isar_splitBinPostRendMdDec_fx( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); #endif } } @@ -1485,9 +1458,9 @@ static ivas_error renderSplitBinauralWithPostRot( hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; /* decode audio */ - if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + IF( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { - if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) { isPostRendInputCldfb = 1; } @@ -1500,173 +1473,200 @@ static ivas_error renderSplitBinauralWithPostRot( #endif outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; - numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel; + numColPerChannelCacheSize = sub( DEPR_i_mult( iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ), outBufNumColPerChannel ); - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - if ( splitBinInput->numCachedSamples == 0 ) + IF( splitBinInput->numCachedSamples == 0 ) { - if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) { - isar_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, SplitRendBFI ); + isar_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, &Q_cldfb_final[sf_idx], SplitRendBFI ); // Q_cldfb_final /* copy data over to 5ms buffer */ - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) { - for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) + FOR( slotIdx = 0; slotIdx < 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; ++slotIdx ) { - mvr2r( Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx], Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); + mvl2l( Cldfb_RealBuffer_Binaural_fx[chnlIdx][slotIdx], Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); + mvl2l( Cldfb_ImagBuffer_Binaural_fx[chnlIdx][slotIdx], Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); } } /* cache the remaining 15ms */ splitBinInput->numCachedSamples = numColPerChannelCacheSize; - writePtr = splitBinInput->bufferData; - for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ); ++slotIdx ) + writePtr_fx = splitBinInput->bufferData_fx; + FOR( slotIdx = 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; slotIdx < DEPR_i_mult( iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ); ++slotIdx ) { - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) { - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) { - *writePtr++ = Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + *writePtr_fx++ = Cldfb_RealBuffer_Binaural_fx[chnlIdx][slotIdx][smplIdx]; } - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) { - *writePtr++ = Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + *writePtr_fx++ = Cldfb_ImagBuffer_Binaural_fx[chnlIdx][slotIdx][smplIdx]; } } } } - else + ELSE { - if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, + Q_out[sf_idx][0] = 0; + Q_out[sf_idx][1] = 0; + if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer_fx, #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS bits.pose_correction, #endif - SplitRendBFI ) ) != IVAS_ERR_OK ) + SplitRendBFI ) ) != IVAS_ERR_OK ) // Q0 { return error; } - /* cache the remaining decoded audio */ + /* cache the remaining 15ms */ splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; - mvr2r( &tmpCrendBuffer[0][outBufNumSamplesPerChannel], splitBinInput->bufferData, numSamplesPerChannelCacheSize ); - mvr2r( &tmpCrendBuffer[1][outBufNumSamplesPerChannel], splitBinInput->bufferData + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); + mvl2l( &tmpCrendBuffer_fx[0][outBufNumSamplesPerChannel], splitBinInput->bufferData_fx, numSamplesPerChannelCacheSize ); + mvl2l( &tmpCrendBuffer_fx[1][outBufNumSamplesPerChannel], splitBinInput->bufferData_fx + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); } } - else + ELSE { /* copy from cache */ - if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) { - int16_t readOffset = ( numColPerChannelCacheSize - splitBinInput->numCachedSamples ); - readPtr = splitBinInput->bufferData; + Word16 readOffset = sub( numColPerChannelCacheSize, splitBinInput->numCachedSamples ); + readPtr_fx = splitBinInput->bufferData_fx; + Q_cldfb_final[sf_idx] = Q_cldfb_final[sf_idx - 1]; isPostRendInputCldfb = 1; - readPtr += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; - for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) + readPtr_fx += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; + FOR( slotIdx = 0; slotIdx < 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; ++slotIdx ) { - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) { - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) { - Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr_fx++; } - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) { - Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr_fx++; } } } splitBinInput->numCachedSamples -= outBufNumColPerChannel; } - else + ELSE { - int16_t readOffset = numSamplesPerChannelCacheSize - splitBinInput->numCachedSamples; - mvr2r( splitBinInput->bufferData + readOffset, &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); - mvr2r( splitBinInput->bufferData + readOffset + numSamplesPerChannelCacheSize, &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + Word16 readOffset = numSamplesPerChannelCacheSize - splitBinInput->numCachedSamples; + mvl2l( splitBinInput->bufferData_fx + readOffset, &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvl2l( splitBinInput->bufferData_fx + readOffset + numSamplesPerChannelCacheSize, &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + Q_out[sf_idx][0] = Q_out[sf_idx - 1][0]; + Q_out[sf_idx][1] = Q_out[sf_idx - 1][1]; splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel; } } } } - else + ELSE { - copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); - if ( splitBinInput->numCachedSamples == 0 ) + copyBufferTo2dArray_fx( splitBinInput->base.inputBuffer, tmpCrendBuffer_fx ); + IF( splitBinInput->numCachedSamples == 0 ) { #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS preRendFrameSize_ms = splitBinInput->base.ctx.pSplitRenderConfig->isar_frame_size_ms; #else preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000; #endif - numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 ); + numSamplesPerChannelCacheSize = (Word16) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 ); numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel; splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; } - else + ELSE { splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel; } } /* apply pose correction if enabled */ - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { - if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) + IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) { /* 0DOF with LCLD codec requires CLDFB synthesis */ - int16_t slot_idx; + Word16 slot_idx; - for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) { - float *RealBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 scaleFactor = 31, Q_cldfb; - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx]; + RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][ch_idx][slot_idx]; + ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][ch_idx][slot_idx]; + + scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); } + scaleFactor = sub( scaleFactor, 3 ); // guarded bits - cldfbSynthesis( RealBuffer, - ImagBuffer, - &( tmpCrendBuffer[ch_idx][sf_idx * outBufNumSamplesPerChannel] ), - hSplitBin->hBinHrSplitPostRend->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, - hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + } + Q_cldfb = scaleFactor + Q_cldfb_final[sf_idx]; + Scale_sig32( hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) ); + cldfbSynthesis_ivas_fx( RealBuffer_fx, + ImagBuffer_fx, + &( tmpCrendBuffer_fx[ch_idx][sf_idx * outBufNumSamplesPerChannel] ), + hSplitBin->hBinHrSplitPostRend->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1 + Scale_sig32( hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) ); + Q_out[sf_idx][ch_idx] = sub( Q_cldfb, 1 ); } } - else if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + ELSE IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { - mvr2r( &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[0], outBufNumSamplesPerChannel ); - mvr2r( &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[1], outBufNumSamplesPerChannel ); + mvl2l( &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf_fx[0], outBufNumSamplesPerChannel ); + mvl2l( &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf_fx[1], outBufNumSamplesPerChannel ); - isar_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms[sf_idx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx], tmpCrendBuffer_sf, isPostRendInputCldfb ); + isar_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx], Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx], Q_cldfb_final[sf_idx], tmpCrendBuffer_sf_fx, Q_out[sf_idx], isPostRendInputCldfb ); // Q_out[2] - mvr2r( tmpCrendBuffer_sf[0], &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); - mvr2r( tmpCrendBuffer_sf[1], &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvl2l( tmpCrendBuffer_sf_fx[0], &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvl2l( tmpCrendBuffer_sf_fx[1], &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); } } } - else + ELSE { - if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + IF( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { - for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) { - set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel ); + set_l( tmpCrendBuffer_fx[ch_idx], 0, outAudio.config.numSamplesPerChannel ); } } - else + ELSE { - copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + copyBufferTo2dArray_fx( splitBinInput->base.inputBuffer, tmpCrendBuffer_fx ); } } convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits ); - accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + Word16 Q_max = 0, Q_temp; + FOR( Word16 i = 0; i < num_subframes; i++ ) + { + maximum_s( Q_out[i], BINAURAL_CHANNELS, &Q_temp ); + Q_max = s_max( Q_max, Q_temp ); + } + Q_max = s_min( Q_max, Q13 ); + accumulate2dArrayToBuffer_fx( tmpCrendBuffer_fx, Q_out, Q_max, &outAudio, num_subframes, outBufNumSamplesPerChannel ); + *outAudio.q_data_fx = Q_max; pop_wmops(); return error; @@ -1676,8 +1676,8 @@ static ivas_error renderInputSplitBin( input_split_post_rend *splitBinInput, const AUDIO_CONFIG outConfig, IVAS_REND_AudioBuffer outAudio, - const int16_t SplitRendBFI, - const int16_t num_subframes ) + const Word16 SplitRendBFI, + const Word16 num_subframes ) { ivas_error error; IVAS_REND_AudioBuffer inAudio; @@ -1687,15 +1687,16 @@ static ivas_error renderInputSplitBin( splitBinInput->base.numNewSamplesPerChannel = 0; /* Apply input gain to new audio */ - v_multc( inAudio.data, - splitBinInput->base.gain, - inAudio.data, - inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); - switch ( outConfig ) + v_multc_fixed( inAudio.data_fx, + splitBinInput->base.gain_fx, + inAudio.data_fx, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + + SWITCH( outConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL: error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI, num_subframes ); - break; + BREAK; default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; } @@ -1710,25 +1711,26 @@ static ivas_error renderActiveInputsSplitBin( int16_t i; input_split_post_rend *pCurrentInput; ivas_error error; - - for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput ) + pCurrentInput = hIvasRend->inputsSplitPost; + FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) { - if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + IF( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) { /* Skip inactive inputs */ + ++pCurrentInput; continue; } - if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + IF( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } + ++pCurrentInput; } return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * ISAR_POST_REND_getSamples() * @@ -1741,48 +1743,48 @@ ivas_error ISAR_POST_REND_getSamples( ) { ivas_error error; - int16_t numOutChannels; - int16_t cldfb2tdSampleFact; + Word16 numOutChannels; + Word16 cldfb2tdSampleFact; /* Validate function arguments */ - if ( hIvasRend == NULL || outAudio.data == NULL ) + IF( hIvasRend == NULL || outAudio.data_fx == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } cldfb2tdSampleFact = ( outAudio.config.is_cldfb ) ? 2 : 1; - if ( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) || - ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) ) + IF( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) || + ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) ) { return IVAS_ERR_INVALID_BUFFER_SIZE; } - if ( outAudio.config.numChannels <= 0 || MAX_OUTPUT_CHANNELS < outAudio.config.numChannels ) + IF( LT_16( outAudio.config.numChannels, 0 ) || LT_16( MAX_OUTPUT_CHANNELS, outAudio.config.numChannels ) ) { return IVAS_ERR_WRONG_NUM_CHANNELS; } - if ( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && - ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) + IF( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && + ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } - if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + IF( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { return error; } - if ( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + IF( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { return IVAS_ERR_WRONG_NUM_CHANNELS; } /* Clear original output buffer */ - set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); + set_l( outAudio.data_fx, 0, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); - if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + IF( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -1791,7 +1793,8 @@ ivas_error ISAR_POST_REND_getSamples( #ifdef DEBUGGING hIvasRend->numClipping += #endif - limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); + Word32 limiter_thresold = L_lshl( IVAS_LIMITER_THRESHOLD, *outAudio.q_data_fx ); + limitRendererOutput_fx( hIvasRend->hLimiter, outAudio.data_fx, outAudio.config.numSamplesPerChannel, limiter_thresold, *outAudio.q_data_fx ); #endif return IVAS_ERR_OK; @@ -1810,7 +1813,7 @@ ivas_error ISAR_POST_REND_GetSplitBinauralSamples( { ivas_error error; - if ( ( error = ISAR_POST_REND_getSamples( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + IF( ( error = ISAR_POST_REND_getSamples( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -1825,27 +1828,26 @@ ivas_error ISAR_POST_REND_GetSplitBinauralSamples( * * *-------------------------------------------------------------------*/ - void ISAR_POST_REND_Close( ISAR_POST_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */ ) { - uint16_t i; + UWord16 i; ISAR_POST_REND_HANDLE hIvasRend; /* Validate function arguments */ - if ( phIvasRend == NULL || *phIvasRend == NULL ) + IF( phIvasRend == NULL || *phIvasRend == NULL ) { return; } hIvasRend = *phIvasRend; - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) { clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); } - ivas_limiter_close( &hIvasRend->hLimiter ); + ivas_limiter_close_splitRend( &hIvasRend->hLimiter ); free( hIvasRend ); *phIvasRend = NULL; @@ -1866,7 +1868,7 @@ ivas_error ISAR_REND_SetSplitRendBitstreamHeader( #endif ) { - if ( hIvasRend == NULL ) + IF( hIvasRend == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } diff --git a/lib_isar/lib_isar_post_rend.h b/lib_isar/lib_isar_post_rend.h index d5fdd605b..cc32086fa 100644 --- a/lib_isar/lib_isar_post_rend.h +++ b/lib_isar/lib_isar_post_rend.h @@ -33,9 +33,8 @@ #ifndef LIB_ISAR_POST_REND_H #define LIB_ISAR_POST_REND_H -#include #include "common_api_types.h" - +#include #ifndef SPLIT_REND_WITH_HEAD_ROT @@ -83,7 +82,7 @@ typedef enum typedef struct { IVAS_REND_AudioBufferConfig config; - const float *data; + const Word32 *data_fx; } ISAR_POST_REND_ReadOnlyAudioBuffer; typedef struct ISAR_POST_REND *ISAR_POST_REND_HANDLE; @@ -105,22 +104,20 @@ typedef enum _ISAR_POST_REND_COMPLEXITY_LEVEL *----------------------------------------------------------------------------------*/ /* Functions to be called before rendering */ - ivas_error ISAR_POST_REND_open( ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ - const int32_t outputSampleRate, /* i : output sampling rate */ + const Word32 outputSampleRate, /* i : output sampling rate */ const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ const bool asHrtfBinary, /* i : load hrtf binary file */ - const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ - const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ - const int16_t num_subframes /* i : number of subframes */ + const Word16 nonDiegeticPan, /* i : non-diegetic object flag */ + const Word32 nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const Word16 num_subframes /* i : number of subframes */ ); /* Functions to be called before/during rendering */ - ivas_error ISAR_POST_REND_NumOutChannels( ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - int16_t *numOutChannels /* o : number of output channels */ + Word16 *numOutChannels /* o : number of output channels */ ); ivas_error ISAR_POST_REND_AddInput( @@ -132,19 +129,18 @@ ivas_error ISAR_POST_REND_AddInput( ivas_error ISAR_POST_REND_SetInputGain( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ - const float gain /* i : linear gain (not in dB) */ + const Word32 gain /* i : linear gain (not in dB) */ ); ivas_error ISAR_POST_REND_GetInputNumChannels( - ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ - int16_t *numChannels /* o : number of channels of the input */ + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + Word16 *numChannels /* o : number of channels of the input */ ); - ivas_error ISAR_POST_REND_GetDelay( - ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - int16_t *nSamples, /* o : Renderer delay in samples */ - int32_t *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */ + Word16 *nSamples, /* o : Renderer delay in samples */ + Word32 *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ ); /* Functions to be called during rendering */ @@ -159,12 +155,10 @@ ivas_error ISAR_POST_REND_InitConfig( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_AUDIO_CONFIG outAudioConfig /* i : output audioConfig */ ); - -int16_t ISAR_POST_REND_GetRenderConfig( - ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ - const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ +Word16 ISAR_POST_REND_GetRenderConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ ); - ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ @@ -178,19 +172,18 @@ ivas_error ISAR_POST_REND_GetSplitBinauralSamples( ); ivas_error ISAR_POST_REND_SetHeadRotation( - ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ - const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ - const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ - const int16_t sf_idx /* i : subframe index */ + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ + const Word16 sf_idx /* i : subframe index */ ); ivas_error ISAR_POST_REND_SetSplitRendBFI( - ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const int16_t bfi /* i: BFI flag */ + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const Word16 bfi /* i: BFI flag */ ); - ivas_error ISAR_POST_REND_getSamples( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ @@ -203,9 +196,9 @@ void ISAR_POST_REND_Close( ); ivas_error ISAR_REND_SetSplitRendBitstreamHeader( - ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ - const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ const int16_t codec_frame_size_ms /* i: codec frame size setting */ #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS , @@ -214,6 +207,7 @@ ivas_error ISAR_REND_SetSplitRendBitstreamHeader( #endif ); + #ifdef DEBUGGING int32_t ISAR_POST_REND_GetNoCLipping( ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ diff --git a/lib_isar/lib_isar_pre_rend.c b/lib_isar/lib_isar_pre_rend.c index 56d3edf55..2149d2225 100644 --- a/lib_isar/lib_isar_pre_rend.c +++ b/lib_isar/lib_isar_pre_rend.c @@ -36,7 +36,7 @@ #include #include "ivas_prot.h" #include "prot.h" -#include "ivas_cnst.h" +#include "isar_cnst.h" #include "isar_rom_post_rend.h" #include "lib_isar_pre_rend.h" #include "isar_prot.h" @@ -77,23 +77,21 @@ int32_t ISAR_PRE_REND_void_func( void ) *------------------------------------------------------------------------*/ ivas_error ISAR_PRE_REND_open( - SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ - ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ - const int32_t output_Fs, /* i: output sampling rate */ - const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ - const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ + SPLIT_REND_WRAPPER *hSplitRendWrapper, + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const Word32 OutSampleRate, + const Word16 cldfb_in_flag, + const Word16 pcm_out_flag, #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */ + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */ #else const int16_t num_subframes, /* i: number of subframes */ #endif - const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */ -) + const int16_t mixed_td_cldfb_flag ) { ivas_error error, ch, num_ch; - uint8_t isCldfbNeeded = 0; - - int16_t cldfb_in_flag_local = cldfb_in_flag; + UWord8 isCldfbNeeded = 0; + Word16 cldfb_in_flag_local = cldfb_in_flag; if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ), #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS @@ -117,67 +115,67 @@ ivas_error ISAR_PRE_REND_open( cldfb_in_flag_local = 0; } - if ( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) + IF( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) { return error; } - if ( cldfb_in_flag_local == 0 ) + IF( EQ_16( cldfb_in_flag_local, 0 ) ) { isCldfbNeeded = 1; } - else if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag_local ) + ELSE IF( EQ_16( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && cldfb_in_flag_local ) { isCldfbNeeded = 1; } - else if ( pcm_out_flag && cldfb_in_flag_local ) + ELSE IF( pcm_out_flag && cldfb_in_flag_local ) { isCldfbNeeded = 1; } - hSplitBinRend->hCldfbHandles = NULL; + hSplitRendWrapper->hCldfbHandles = NULL; - if ( isCldfbNeeded ) + IF( isCldfbNeeded ) { - if ( ( hSplitBinRend->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + IF( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); } num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) + FOR( ch = 0; ch < num_ch; ch++ ) { - hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; } - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; + hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; } - num_ch = hSplitBinRend->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) + FOR( ch = 0; ch < num_ch; ch++ ) { - if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbAna[ch] ), + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, - output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } } - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } } } - if ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + IF( EQ_16( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) { - if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData + if ( ( error = isar_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, &hSplitRendWrapper->multiBinPoseData #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG , OutSampleRate @@ -188,11 +186,11 @@ ivas_error ISAR_PRE_REND_open( } } - if ( pcm_out_flag == 0 ) + IF( EQ_16( pcm_out_flag, 0 ) ) { - if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + IF( EQ_16( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) ) { - if ( ( error = split_renderer_open_lc3plus( hSplitBinRend, pSplitRendConfig, output_Fs, + if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS ivas_frame_size #else @@ -203,12 +201,12 @@ ivas_error ISAR_PRE_REND_open( return error; } } - else + ELSE { - int16_t iNumBlocksPerFrame; + Word16 iNumBlocksPerFrame; iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20; - if ( ( error = isar_splitBinLCLDEncOpen( &hSplitBinRend->hSplitBinLCLDEnc, output_Fs, BINAURAL_CHANNELS, isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitBinRend->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK ) + IF( ( error = isar_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK ) { return error; } @@ -223,68 +221,74 @@ ivas_error ISAR_PRE_REND_open( * * *------------------------------------------------------------------------*/ - void ISAR_PRE_REND_close( SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ ) { - int16_t i; + Word16 i; - if ( hSplitBinRend->hBinHrSplitPreRend != NULL ) + IF( hSplitBinRend->hBinHrSplitPreRend != NULL ) { isar_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); } - if ( hSplitBinRend->hSplitBinLCLDEnc != NULL ) + IF( hSplitBinRend->hSplitBinLCLDEnc != NULL ) { isar_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); } - if ( hSplitBinRend->hCldfbHandles != NULL ) + IF( hSplitBinRend->hCldfbHandles != NULL ) { - int16_t num_ch, ch; + Word16 num_ch, ch; num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) + FOR( ch = 0; ch < num_ch; ch++ ) { - if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) + IF( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) { deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; } } - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - if ( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL ) + IF( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL ) { deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ); hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; } } +#endif free( hSplitBinRend->hCldfbHandles ); hSplitBinRend->hCldfbHandles = NULL; } - if ( hSplitBinRend->hLc3plusEnc != NULL ) + IF( hSplitBinRend->hLc3plusEnc != NULL ) { ISAR_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); } - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) { - if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) + IF( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) { free( hSplitBinRend->lc3plusDelayBuffers[i] ); hSplitBinRend->lc3plusDelayBuffers[i] = NULL; } + if ( hSplitBinRend->lc3plusDelayBuffers_fx[i] != NULL ) + { + free( hSplitBinRend->lc3plusDelayBuffers_fx[i] ); + hSplitBinRend->lc3plusDelayBuffers_fx[i] = NULL; + } } - if ( pSplitRendEncBuffer != NULL ) + IF( pSplitRendEncBuffer != NULL ) { - if ( pSplitRendEncBuffer->data != NULL ) + IF( pSplitRendEncBuffer->data != NULL ) { free( pSplitRendEncBuffer->data ); pSplitRendEncBuffer->data = NULL; @@ -297,6 +301,7 @@ void ISAR_PRE_REND_close( return; } + /*-------------------------------------------------------------------------* * ISAR_PRE_REND_GetMultiBinPoseData() * @@ -309,7 +314,7 @@ void ISAR_PRE_REND_GetMultiBinPoseData( const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ ) { - isar_renderSplitGetMultiBinPoseData( pSplit_rend_config, pMultiBinPoseData, rot_axis ); + isar_renderSplitGetMultiBinPoseData_fx( pSplit_rend_config, pMultiBinPoseData, rot_axis ); } /*------------------------------------------------------------------------- @@ -317,149 +322,258 @@ void ISAR_PRE_REND_GetMultiBinPoseData( * * *------------------------------------------------------------------------*/ - ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ - const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */ - const int32_t SplitRendBitRate, /* i: Split renderer bitrate */ - ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const Word32 SplitRendBitRate, + ISAR_SPLIT_REND_CODEC splitCodec, #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - const int16_t isar_frame_size_ms, /* i: ISAR framesize */ + const Word16 isar_frame_size_ms, /* i: ISAR framesize */ #endif - int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */ - ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */ - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ - const int16_t max_bands, /* i: CLDFB bands */ - float *output[], /* i/o: PCM in/out buffer */ - const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */ - const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ - const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ - const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */ -) + Word16 codec_frame_size_ms, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 max_bands, + float *output[], + Word32 *pOutput_fx[], + const Word16 low_res_pre_rend_rot, + const Word16 cldfb_in_flag, + const Word16 pcm_out_flag, + const Word16 ro_md_flag, + Word16 Q_buff, + Word16 *Q_out ) { ivas_error error; #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - int32_t bit_len, target_md_bits, available_bits; + int32_t bit_len, target_md_bits, available_bits, tmp_32; #else - int32_t bit_len, target_md_bits, actual_md_bits, available_bits; + Word32 bit_len, target_md_bits, actual_md_bits, available_bits, tmp_32; #endif - + Word16 q1 = 31, q2 = 31, q_final, Q_cldfb, tmp, tmp_e; + Word16 i, j; error = IVAS_ERR_OK; - push_wmops( "isar_pre_rend_MultiBinToSplitBinaural" ); - - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + Word16 Q_buff_re, Q_buff_im; + push_wmops( "ISAR_PRE_REND_MultiBinToSplitBinaural" ); +#ifdef CLDFB_SYNTH_DEBUG + /* FILE *fp = fopen( "Fixed_code_output.txt", "ab+" ); + FILE *fp1 = fopen( "Fixed_code_cldfb_state.txt", "ab+" ); + FILE *fp = fopen( "Float_code_output.txt", "ab+" ); + FILE *fp1 = fopen( "Float_code_cldfb_state.txt", "ab+" );*/ +#endif + output; + Q_buff_re = Q_buff; + move16(); + Q_buff_im = Q_buff; + move16(); + IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { - set_fix_rotation_mat( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat, &hSplitBin->multiBinPoseData ); - set_pose_types( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData ); + set_fix_rotation_mat_fx( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat_fx, &hSplitBin->multiBinPoseData ); + set_pose_types_fx( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData ); } - if ( cldfb_in_flag == 0 ) + IF( EQ_16( cldfb_in_flag, 0 ) ) { - /*TD input*/ - /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ - error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, - headPosition, - SplitRendBitRate, + error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS isar_frame_size_ms, #endif - codec_frame_size_ms, - pBits, - max_bands, - output, - low_res_pre_rend_rot, - pcm_out_flag, - ro_md_flag ); + codec_frame_size_ms, pBits, max_bands, pOutput_fx, Q_out[0], low_res_pre_rend_rot, pcm_out_flag, ro_md_flag ); pop_wmops(); return error; } - if ( splitCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + IF( splitCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { /* Time-align pose correction to delay of LC3plus */ - lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag ); + lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, &Q_buff ); + Q_buff_re = Q_buff; + move16(); + Q_buff_im = Q_buff; + move16(); } #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS actual_md_bits = pBits->bits_written; #endif - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; #ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS actual_md_bits = pBits->bits_written; #endif - - isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); + /*float2fix, to be removed*/ + Word16 Q_Cldfb_re = 31, Q_Cldfb_im = 31; + move16(); + move16(); + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Q_Cldfb_re = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX ), Q_Cldfb_re ); + Q_Cldfb_im = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX ), Q_Cldfb_im ); + } + } + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, Q_Cldfb_re ); + Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, Q_Cldfb_im ); + } + } + Q_buff_re = add( Q_Cldfb_re, Q_buff ); + Q_buff_im = add( Q_Cldfb_im, Q_buff ); + Word16 exp_cldfb_re = sub( 31, Q_buff_re ); + Word16 exp_cldfb_im = sub( 31, Q_buff_im ); + isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); } - if ( pcm_out_flag == 0 ) + IF( EQ_16( pcm_out_flag, 0 ) ) { pBits->codec = splitCodec; pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + IF( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) { - available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + // available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + available_bits = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( available_bits, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e ); + available_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - available_bits -= pBits->bits_written; + available_bits = L_sub( available_bits, pBits->bits_written ); #else - actual_md_bits = pBits->bits_written - actual_md_bits; - available_bits -= actual_md_bits; + actual_md_bits = L_sub( pBits->bits_written, actual_md_bits ); + available_bits = L_sub( available_bits, actual_md_bits ); #endif pBits->codec_frame_size_ms = codec_frame_size_ms; - isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); + q_final = sub( s_min( Q_buff_re, Q_buff_im ), 2 ); + FOR( i = 0; i < hSplitBin->hSplitBinLCLDEnc->iChannels; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) ); + Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) ); + } + } + isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, available_bits, pBits, &q_final ); + Q_buff_re = q_final; + move16(); + Q_buff_im = q_final; + move16(); } - else + ELSE { - int16_t ch, slot_idx, num_slots, ivas_fs; - ivas_fs = (int16_t) hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; - num_slots = (int16_t) ( CLDFB_NO_COL_MAX * ivas_fs ) / 20; + Word16 ch, slot_idx, num_slots, ivas_fs; + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e ); + ivas_fs = shr( tmp, sub( 15, tmp_e ) ); // Q0 + // ivas_fs = (Word16) hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( L_mult0( CLDFB_NO_COL_MAX, ivas_fs ), 20, &tmp_e ); + num_slots = shr( tmp, sub( 15, tmp_e ) ); // Q0 + // num_slots = (Word16) CLDFB_NO_COL_MAX * ivas_fs / 20; /* CLDFB synthesis of main pose */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; - float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; + Word32 *Cldfb_In_BinReal_p_fx[CLDFB_NO_COL_MAX]; + Word32 *Cldfb_In_BinImag_p_fx[CLDFB_NO_COL_MAX]; + q1 = 31; + q2 = 31; + move16(); + move16(); + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + q1 = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q1 ); + q2 = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q2 ); + } + q_final = s_min( q1, q2 ); + q_final = s_min( add( Q_buff_re, q_final ), add( Q_buff_im, q_final ) ); + q_final = sub( q_final, 3 ); // guard bits + q_final = s_min( q_final, Q25 ); + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) ); + Scale_sig32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) ); + } - for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) { - Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; - Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; + Cldfb_In_BinReal_p_fx[slot_idx] = Cldfb_In_BinReal_fx[ch][slot_idx]; + move32(); + Cldfb_In_BinImag_p_fx[slot_idx] = Cldfb_In_BinImag_fx[ch][slot_idx]; + move32(); } - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); + Q_cldfb = q_final; + move16(); + Scale_sig32( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length, sub( sub( Q_cldfb, 1 ), hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split ) ); + cldfbSynthesis_ivas_fx( Cldfb_In_BinReal_p_fx, Cldfb_In_BinImag_p_fx, pOutput_fx[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); // Q_cldfb - 1 + Q_out[ch] = sub( Q_cldfb, 1 ); + move16(); + hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split = Q_out[ch]; + move16(); + fixedToFloat_arrL( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state, hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length ); } #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, output ) ) != IVAS_ERR_OK ) + IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, pOutput_fx, Q_out[0] ) ) != IVAS_ERR_OK ) #else - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK ) + IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, pOutput_fx ) ) != IVAS_ERR_OK ) #endif { return error; } } } - else + ELSE { - int16_t ch, slot_idx; + Word16 ch, slot_idx; /* CLDFB synthesis of main pose */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; - float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; + Word32 *Cldfb_In_BinReal_p_fx[CLDFB_NO_COL_MAX]; + Word32 *Cldfb_In_BinImag_p_fx[CLDFB_NO_COL_MAX]; + q1 = 31; + move16(); + q2 = 31; + move16(); + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + q1 = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q1 ); + q2 = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q2 ); + } + q_final = s_min( q1, q2 ); + q_final = s_min( add( Q_buff_re, q_final ), add( Q_buff_im, q_final ) ); + q_final = sub( q_final, 3 ); // guard bits + q_final = s_min( q_final, Q25 ); + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) ); + Scale_sig32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) ); + } - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) { - Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; - Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; + Cldfb_In_BinReal_p_fx[slot_idx] = Cldfb_In_BinReal_fx[ch][slot_idx]; + move32(); + Cldfb_In_BinImag_p_fx[slot_idx] = Cldfb_In_BinImag_fx[ch][slot_idx]; + move32(); } - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); + Q_cldfb = q_final; + move16(); + Scale_sig32( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length, sub( sub( Q_cldfb, 1 ), hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split ) ); + cldfbSynthesis_ivas_fx( Cldfb_In_BinReal_p_fx, Cldfb_In_BinImag_p_fx, pOutput_fx[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); // Q_cldfb - 1 + Q_out[ch] = sub( Q_cldfb, 1 ); + move16(); + hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split = Q_out[ch]; + move16(); } pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; @@ -467,30 +581,45 @@ ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( } /*zero pad*/ - if ( pcm_out_flag ) + IF( pcm_out_flag ) { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( SplitRendBitRate, FRAMES_PER_SEC, &tmp_e ); + bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0 + // bit_len = SplitRendBitRate / FRAMES_PER_SEC; } - else + ELSE { - if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + IF( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) { - bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + // bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + + bit_len = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( bit_len, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e ); + bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 } - else + ELSE { - bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; - bit_len = SplitRendBitRate * bit_len / 1000; + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e ); + bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0 + // bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + // bit_len = SplitRendBitRate * bit_len / 1000; + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_mult0_32_32( SplitRendBitRate, bit_len ) ), 1000, &tmp_e ); + bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 } } - while ( pBits->bits_written < bit_len ) + WHILE( LT_32( pBits->bits_written, bit_len ) ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); } pop_wmops(); - + /* fclose(fp); + fclose(fp1);*/ return error; } diff --git a/lib_isar/lib_isar_pre_rend.h b/lib_isar/lib_isar_pre_rend.h index 938787314..fe64e4911 100644 --- a/lib_isar/lib_isar_pre_rend.h +++ b/lib_isar/lib_isar_pre_rend.h @@ -41,7 +41,6 @@ int32_t ISAR_PRE_REND_void_func( void ); #else - ivas_error ISAR_PRE_REND_open( SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ @@ -68,24 +67,26 @@ void ISAR_PRE_REND_GetMultiBinPoseData( ); ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ - const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */ - const int32_t SplitRendBitRate, /* i: Split renderer bitrate */ - ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ + const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */ + const Word32 SplitRendBitRate, /* i: Split renderer bitrate */ + ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS - const int16_t isar_frame_size_ms, /* i: ISAR framesize */ + const Word16 isar_frame_size_ms, /* i: ISAR framesize */ #endif - int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */ - ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */ - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ - const int16_t max_bands, /* i: CLDFB bands */ - float *output[], /* i/o: PCM in/out buffer */ - const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */ - const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ - const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ - const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */ -); + Word16 codec_frame_size_ms, /* i/o: Split renderer codec framesize */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: Split renderer bitstream handle */ + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ + const Word16 max_bands, /* i: CLDFB bands */ + float *output[], /* i/o: PCM in/out buffer */ + Word32 *pOutput_fx[], /* i: low time resolution pre-renderer flag */ + const Word16 low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */ + const Word16 cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ + const Word16 pcm_out_flag, /* i: Flag to indicate PCM output */ + const Word16 ro_md_flag, /* i: Flag to indicate real only metadata for yaw */ + Word16 Q_buff, + Word16 *Q_out ); #endif #endif /* LIB_ISAR_PRE_REND_H */ diff --git a/lib_lc3plus/adjust_global_gain.c b/lib_lc3plus/adjust_global_gain.c deleted file mode 100644 index 24eb596c8..000000000 --- a/lib_lc3plus/adjust_global_gain.c +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, LC3_INT* gainChange, LC3_INT fs_idx - , LC3_INT16 hrmode, LC3_INT16 frame_dms - ) -{ - LC3_FLOAT delta; - LC3_INT delta2; - LC3_INT gg_idx_inc; -#ifdef CR8_G_ADD_75MS - LC3_FLOAT factor; -#else - LC3_INT factor; -#endif - - if (frame_dms == 25) - { - if (target < 520) - { - factor = 3; - } else { - factor = 4; - } - } else if (frame_dms == 50) - { - factor = 2; - } -#ifdef CR8_G_ADD_75MS - else if (frame_dms == 75) - { - factor = 1.2; - } -#endif - else - { - factor = 1; - } - - if (nBits < gg_p1[fs_idx]) { - delta = (nBits + 48.0) / 16.0; - } else if (nBits < gg_p2[fs_idx]) { - delta = (nBits + gg_d[fs_idx]) * gg_c[fs_idx]; - } else if (nBits < gg_p3[fs_idx]) { - delta = nBits / 48.0; - } else { - delta = gg_p3[fs_idx] / 48.0; - } - - delta = round(delta); - delta2 = delta + 2; - - *gainChange = 0; - - if (*gg_idx == 255 && nBits > target) { - *gainChange = 1; - } - - if ((*gg_idx < 255 && nBits > target) || (*gg_idx > 0 && nBits < target - delta2)) { - if (hrmode) - { - if (nBits > target) { - gg_idx_inc = (int) (factor * (((nBits - target)/ delta) + 1)); - gg_idx_inc = MIN(gg_idx_inc, 10 * factor); - - *gg_idx += gg_idx_inc; - } - - *gg_idx = MIN(*gg_idx, 255); - } - else - { - if (nBits < target - delta2) { - *gg_idx = *gg_idx - 1; - } else if (*gg_idx == 254 || nBits < target + delta) { - *gg_idx = *gg_idx + 1; - } else { - *gg_idx = *gg_idx + 2; - } - } - - *gg_idx = MAX(*gg_idx, gg_idx_min - gg_idx_off); - *gain = LC3_POW(10, (LC3_FLOAT)(*gg_idx + gg_idx_off) / 28); - *gainChange = 1; - } -} diff --git a/lib_lc3plus/adjust_global_gain_fx.c b/lib_lc3plus/adjust_global_gain_fx.c new file mode 100644 index 000000000..c6067b591 --- /dev/null +++ b/lib_lc3plus/adjust_global_gain_fx.c @@ -0,0 +1,186 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + + + +void processAdjustGlobalGain_fx(Word16 *gg_idx, Word16 gg_idx_min, Word16 gg_idx_off, +#ifdef ENABLE_HR_MODE + Word32 *gain, +#else + Word16 *gain, +#endif + Word16 *gain_e, + Word16 target, Word16 nBits, Word16 *gainChange, Word16 fs_idx +#ifdef ENABLE_HR_MODE + , Word16 hrmode, Word16 frame_dms +#endif + ) +{ + + Word32 L_tmp; + Word16 delta, delta2; +#ifdef ENABLE_HR_MODE + Word16 gg_idx_inc; + Word16 gg_idx_inc_max; + Word16 gg_idx_inc_s; +# ifdef CR8_G_ADD_75MS + Word32 factor; +# else + Word16 factor; +# endif +#endif + +#ifdef DYNMEM_COUNT +#if defined(ENABLE_HR_MODE) + Dyn_Mem_In("processAdjustGlobalGain_fx", sizeof(struct { + Word32 L_tmp; + Word16 delta, delta2; + Word16 gg_idx_inc; + Word16 gg_idx_inc_max; + Word16 gg_idx_inc_s; + Word16 factor; + })); +#else + Dyn_Mem_In("processAdjustGlobalGain_fx", sizeof(struct { + Word32 L_tmp; + Word16 delta, delta2; + })); +#endif /* ENABLE_HR_MODE */ +#endif /* DYNMEM_COUNT */ + +#ifdef ENABLE_HR_MODE + IF (sub(frame_dms, 25) == 0) + { + IF (sub(target, 520) < 0) + { + factor = 3; move16(); + gg_idx_inc_max = 30; move16(); + } ELSE { + factor = 4; move16(); + gg_idx_inc_max = 40; move16(); + } + } + ELSE IF (sub(frame_dms, 50) == 0) + { + factor = 2; move16(); + gg_idx_inc_max = 20; move16(); + } +#ifdef CR8_G_ADD_75MS + ELSE IF (sub(frame_dms, 75) == 0) + { + factor = 40265318; move16(); // factor = 1.2 * 2^25 + gg_idx_inc_max = 12 ; move16(); + } +#endif + ELSE + { + factor = 1; move16(); + gg_idx_inc_max = 10; move16(); + } +#endif + + IF (sub(nBits, adjust_global_gain_tables[0][fs_idx]) < 0) + { + delta = mult_r(add(nBits, 48), 2048); + } + ELSE IF (sub(nBits, adjust_global_gain_tables[1][fs_idx]) < 0) + { + delta = mult_r(add(nBits, adjust_global_gain_tables[4][fs_idx]), adjust_global_gain_tables[3][fs_idx]); + } + ELSE IF (sub(nBits, adjust_global_gain_tables[2][fs_idx]) < 0) + { + delta = mult_r(nBits, 683); + } + ELSE + { + delta = mult_r(adjust_global_gain_tables[2][fs_idx], 683); + } + delta2 = add(delta, 2); + + *gainChange = 0; move16(); + + test(); + IF (sub(*gg_idx, 255) == 0 && sub(nBits, target) > 0) + { + *gainChange = 1; move16(); + } + + test(); test(); test(); + IF ((sub(*gg_idx, 255) < 0 && sub(nBits, target) > 0) || (*gg_idx > 0 && sub(nBits, sub(target, delta2)) < 0)) + { +#ifdef ENABLE_HR_MODE + IF (hrmode) + { + IF (sub(nBits, target) > 0) + { + gg_idx_inc = sub(nBits, target); +#ifdef CR8_G_ADD_75MS + IF (sub(frame_dms, 75) == 0) + { + gg_idx_inc = extract_l(L_shr_pos(Mpy_32_16_lc3plus(factor, gg_idx_inc), 10)); // Mpy_32_16_lc3plus(1.2*2^25, gg_idx_inc), 25 - 15) + gg_idx_inc = BASOP_Util_Divide1616_Scale_lc3plus(gg_idx_inc, delta, &gg_idx_inc_s); + gg_idx_inc = shr_sat(gg_idx_inc, sub(15, gg_idx_inc_s)); + gg_idx_inc = add(gg_idx_inc, 1); // adding 1 instead of 1.2 + } + ELSE +#endif + { + gg_idx_inc = extract_l(L_mult0(gg_idx_inc, factor)); + gg_idx_inc = BASOP_Util_Divide1616_Scale_lc3plus(gg_idx_inc, delta, &gg_idx_inc_s); + gg_idx_inc = shr_sat(gg_idx_inc, sub(15, gg_idx_inc_s)); + gg_idx_inc = add(gg_idx_inc, factor); + } + gg_idx_inc = s_min(gg_idx_inc, gg_idx_inc_max); + + *gg_idx = add(*gg_idx, gg_idx_inc); move16(); + } + + *gg_idx = s_min(*gg_idx, 255); move16(); + } + ELSE +#endif + { + test(); + IF (sub(nBits, sub(target, delta2)) < 0) + { + *gg_idx = sub(*gg_idx, 1); move16(); + } + ELSE IF (sub(*gg_idx, 254) == 0 || sub(nBits, add(target, delta)) < 0) + { + *gg_idx = add(*gg_idx, 1); move16(); + } + ELSE + { + *gg_idx = add(*gg_idx, 2); move16(); + } + } + + *gg_idx = s_max(*gg_idx, sub(gg_idx_min, gg_idx_off)); move16(); + +#ifdef ENABLE_HR_MODE + L_tmp = Mpy_32_16_lc3plus(0x3CBE6B83, L_shl_pos(add(*gg_idx, gg_idx_off), 7)); +#else + L_tmp = L_shl_pos(L_mult0(add(*gg_idx, gg_idx_off), 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */ +#endif + *gain_e = add(extract_l(L_shr_pos(L_tmp, 25)), 1); /* get exponent */ +#ifdef ENABLE_HR_MODE + *gain = BASOP_Util_InvLog2_lc3plus(L_or(L_tmp, (Word32)0xFE000000)); +#else + *gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(L_tmp, (Word32)0xFE000000))); +#endif + *gainChange = 1; move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/al_fec.c b/lib_lc3plus/al_fec.c new file mode 100644 index 000000000..7579a21b0 --- /dev/null +++ b/lib_lc3plus/al_fec.c @@ -0,0 +1,2379 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" + + +#include "functions.h" +#include "rom_basop_util.h" +#include +#include +#include +#include + +/* channel coder specific constants and macros */ +#define RS16_CW_LEN_MAX 15 + +#define FEC_N_MODES 4 +#define FEC_N_SYNDROMES_MAX 6 +#define FEC_N_ERR_POS_MAX 3 +#define FEC_N_ELP_COEFF_MAX 4 +#define FEC_N_ERR_SYMB_MAX 3 +#define FEC_N_MODE_DETECTION_CW 6 + +#define SYNDROME_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_SYNDROMES_MAX) +#define ELP_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ELP_COEFF_MAX) +#define ERR_POS_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_POS_MAX) +#define ERR_SYMB_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_SYMB_MAX) +#define DEG_ELP_IDX(mode_index, cw_index) ((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) + +#define FEC_TOTAL_SYNDROME_SIZE (FEC_N_SYNDROMES_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ELP_SIZE (FEC_N_ELP_COEFF_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ERR_POS_SIZE (FEC_N_ERR_POS_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ERROR_SIZE (FEC_N_ERR_SYMB_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_DEG_ELP_SIZE (FEC_N_MODES * FEC_N_MODE_DETECTION_CW) + +#define ERROR_REPORT_BEC_MASK ((0x0FFF)>>1) +#define ERROR_REPORT_EP1_OK ((0x1000)>>1) +#define ERROR_REPORT_EP2_OK ((0x2000)>>1) +#define ERROR_REPORT_EP3_OK ((0x4000)>>1) +#define ERROR_REPORT_EP4_OK ((0x8000)>>1) +#define ERROR_REPORT_ALL_OK (ERROR_REPORT_EP1_OK | ERROR_REPORT_EP2_OK | ERROR_REPORT_EP3_OK | ERROR_REPORT_EP4_OK) + +/* debugging switches */ + +/* constants concerning mode detection */ +#define EP_RISK_THRESH_NS_M 21990 +#define EP_RISK_THRESH_NS_E -23 +#define EP_RISK_THRESH_OS_M 25166 +#define EP_RISK_THRESH_OS_E -10 + +#define SIMPLE_FLOAT_1_MANTISSA 16384 + +#define FEC_STATIC static + +/* DISCLAIMER: Strict instrumentation of GF16 arithmetic would have to take into account + * the initial conversion of the arguments from UWord8 to Word16 (one move16() per argument). + * Behind this is the assumption that one would store GF16 elements in Word16 for strict BASOP + * implementation. + */ + +#define GF16_MUL(a, b) (UWord8)(move16(), gf16_mult_table[s_or((a), shl((b), 4))]) +#define GF16_MUL0(a, b) (UWord8)(move16(), gf16_mult_table[s_or((a), (b))]) +#define GF16_ADD(a, b) (UWord8) s_xor((a), (b)) + +/* tables for finite field arithmetic */ +/* tables for arithmetic in GF(16) * + * generator polynomial: 19 + * unit group generator (g): 2 + */ + +static const UWord8 gf16_g_pow[16] = {1, 2, 4, 8, 3, 6, 12, 11, 5, 10, 7, 14, 15, 13, 9, 1}; +/* g_pow[i] contains g^i*/ + +static const UWord8 gf16_log_g[16] = {255, 0, 1, 4, 2, 8, 5, 10, 3, 14, 9, 7, 6, 13, 11, 12}; +/* log_g[n] contains contains the value i such that g^i = n for n=1, 2, ..., 15, log_g[0] is set to 255 */ + +static const UWord8 gf16_inv_table[16] = {255, 1, 9, 14, 13, 11, 7, 6, 15, 2, 12, 5, 10, 4, 3, 8}; +/* gf16_inv_table[n] contains the multiplicative inverse of n in GF(16) (1/0 is set to 255)*/ + +/* RS16 generating polynomials (from lowest to highest coefficient without leading 1)*/ + +static const UWord8 rs16_gp_d3[] = {8, 6}; +static const UWord8 rs16_gp_d5[] = {7, 8, 12, 13}; +static const UWord8 rs16_gp_d7[] = {12, 10, 12, 3, 9, 7}; + +/* FEC mode signaling polynomials */ + +#define EP_SIG_POLY_DEG 12 + +static const UWord8 sig_polys[4][15] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {7, 15, 5, 6, 14, 9, 1, 3, 12, 10, 13, 3, 2, 0, 0}, + {7, 11, 14, 1, 2, 3, 12, 11, 6, 15, 7, 6, 12, 0, 0}, + {6, 15, 12, 2, 9, 15, 2, 8, 12, 3, 10, 5, 4, 0, 0}}; + +static const UWord8 sig_poly_syndr[4][6] = { + {0, 0, 0, 0, 0, 0}, {0, 4, 5, 11, 5, 8}, {0, 5, 9, 0, 1, 7}, {0, 12, 5, 12, 9, 8}}; + +/* bit count table for error report (0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111) */ + +static const UWord8 rs16_bit_count_table[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + +/* List of RS16 generators by Hamming distance */ + +static const UWord8 *const rs16_gp_by_hd[8] = {NULL, NULL, NULL, rs16_gp_d3, NULL, rs16_gp_d5, NULL, rs16_gp_d7}; + +/* fec config data */ + +static const UWord8 hamming_distance_by_mode0[] = {1, 3, 3, 5, 7}; +static const UWord8 hamming_distance_by_mode1[] = {1, 1, 3, 5, 7}; + +static const UWord8 crc1_bytes_by_mode0[] = {0, 3, 2, 2, 2}; +static const UWord8 crc1_bytes_by_mode1[] = {0, 3, 3, 3, 3}; +static const UWord8 crc2_bytes_by_mode[] = {0, 0, 2, 2, 2}; + +/* fec mode risk table */ +typedef struct +{ + UWord32 mantissa; + Word16 exponent; +} simple_float; + +static const simple_float risk_table_f[4][4] = {{{16384, 0}, {16384, 0}, {16384, 0}, {16384, 0}}, + {{16384, -8}, {26880, -1}, {16384, 0}, {16384, 0}}, + {{16384, -16}, {26880, -9}, {20475, -2}, {16384, 0}}, + {{16384, -24}, {26880, -17}, {20475, -10}, {19195, -4}}}; +/* bit error limits for slot size 40 */ +static Word16 const low_br_max_bit_errors_by_mode[] = {0, 0, 3, 9, 18}; + +/* +corresponding float values: + {1.f, 1.f, 1.f, 1.f}, + {0.00390625f, 0.820312f, 1.f, 1.f}, + {1.52588e-05f, 0.00320435f, 0.312424f, 1.f}, + {5.96046e-08f, 1.2517e-05f, 0.00122041f, 0.0732243f} +*/ + +/* internal encoder routines */ + +FEC_STATIC void fec_interleave_pack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords); + +FEC_STATIC void rs16_enc(UWord8 *iobuf, Word16 codeword_length, Word16 hamming_distance, Word16 fec_mode, + Word16 signal_mode); + +/* internal decoder routines */ + +FEC_STATIC void fec_deinterleave_unpack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords); + +FEC_STATIC Word16 fec_data_preproc(Word16 mode, Word16 epmr, UWord8 *iobuf, UWord8 *cw_buf, Word16 data_bytes, + Word16 slot_bytes, Word16 pc_split); + +FEC_STATIC void fec_data_postproc(Word16 mode, Word16 *epmr, UWord8 *iobuf, Word16 data_bytes, UWord8 *cw_buf, + Word16 slot_bytes, Word16 pc_split, int *bfi); + +FEC_STATIC int rs16_detect_and_correct(UWord8 *iobuf, int n_symb, int n_codewords, Word16 *epmr, Word16 *error_report, + int *bfi, UWord8 *array_of_trust, int ccc_flag_flag, Word16 *n_pccw, void *scratch); + +FEC_STATIC void rs16_calculate_six_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg); + +FEC_STATIC void rs16_calculate_four_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg); + +FEC_STATIC void rs16_calculate_two_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg); + +FEC_STATIC Word8 rs16_calculate_elp(UWord8 *elp, UWord8 *syndromes, Word16 hamming_distance); + +FEC_STATIC Word16 rs16_factorize_elp(UWord8 *error_locations, UWord8 *elp, Word16 deg_elp, Word16 max_pos); + +FEC_STATIC void rs16_calculate_errors(UWord8 *errors, UWord8 *err_pos, UWord8 *syndromes, Word8 deg_elp, Word8 t); + +/* auxiliary routines */ + +FEC_STATIC Word16 crc1(UWord8 *data, Word16 data_size, Word16 epmr, UWord8 *hash, Word16 hash_size, Word16 check); + +FEC_STATIC Word16 fec_estimate_epmr_from_cw0(UWord8 *cw0, Word8 *t, UWord8 *syndromes, UWord8 *elp, Word8 *deg_elp, + UWord8 *err_pos, UWord8 *err_symb, Word16 n_codewords, Word16 n_symb); + +FEC_STATIC void dw0_bitswap(UWord8 *dw0, Word16 mode, Word16 slot_bytes); + +FEC_STATIC Word16 cw0_get_epmr(UWord8 *cw0, Word16 epmr_position); + +FEC_STATIC Word16 dw0_get_epmr(UWord8 *dw0, Word16 mode, Word16 slot_size); + +FEC_STATIC Word16 crc2(UWord8 *data, Word16 data_size, UWord8 *hash, Word16 hash_size, Word16 check); + +FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2); + +FEC_STATIC Word16 simple_float_cmp(simple_float op1, simple_float op2); + +FEC_STATIC Word16 get_total_crc_size(Word16 slot_bytes, Word16 fec_mode, Word16 pc_split); + +FEC_STATIC Word16 get_n_codewords(Word16 slot_bytes); + +FEC_STATIC Word16 get_codeword_length(Word16 n_codewords, Word16 slot_nibbles, Word16 codeword_index); + + + +Word16 fec_get_n_pccw(Word16 slot_bytes, Word16 fec_mode, Word16 ccc_flag) +{ + Dyn_Mem_Deluxe_In( + Word16 n_pccw; + ); + + IF (sub(fec_mode, 3) == 0) + { + n_pccw = round_fx(L_sub(L_mult(2636, slot_bytes), 117377)); + } + ELSE IF (sub(fec_mode, 4) == 0) + { + n_pccw = round_fx(L_sub(L_mult(2178, slot_bytes), 129115)); + } + ELSE + { + n_pccw = 0; move16(); + } + + if (ccc_flag == 1 || sub(slot_bytes, 80) < 0) + { + n_pccw = 0; move16(); + } + + Dyn_Mem_Deluxe_Out(); + return n_pccw; +} + +FEC_STATIC Word16 get_total_crc_size(Word16 slot_bytes, Word16 fec_mode, Word16 pc_split) +{ + Dyn_Mem_Deluxe_In( + Word16 n_crc; + ); + + n_crc = crc1_bytes_by_mode1[fec_mode]; move16(); + if (sub(slot_bytes, 40) == 0) + { + n_crc = crc1_bytes_by_mode0[fec_mode]; move16(); + } + + IF (pc_split > 0) + { + n_crc = add(n_crc, crc2_bytes_by_mode[fec_mode]); + } + Dyn_Mem_Deluxe_Out(); + return n_crc; +} + +FEC_STATIC Word16 get_n_codewords(Word16 slot_bytes) +{ + Dyn_Mem_Deluxe_In( + Word16 i; + ); + + slot_bytes = shl(slot_bytes, 1); + + FOR (i = 0; slot_bytes > 0; i++) + { + slot_bytes = sub(slot_bytes, RS16_CW_LEN_MAX); + } + + Dyn_Mem_Deluxe_Out(); + return i; +} + +FEC_STATIC Word16 get_codeword_length(Word16 n_codewords, Word16 slot_nibbles, Word16 codeword_index) +{ + Dyn_Mem_Deluxe_In( + Word16 i; + ); + + slot_nibbles = sub(slot_nibbles, add(codeword_index, 1)); + slot_nibbles = sub(slot_nibbles, DEPR_i_mult(n_codewords, 13)); + + FOR (i = 12; slot_nibbles >= 0; i++) + { + slot_nibbles = sub(slot_nibbles, n_codewords); + } + + Dyn_Mem_Deluxe_Out(); + return add(i, 1); +} + +/* Encoder */ + +Word16 fec_get_data_size(Word16 fec_mode, Word16 ccc_flag, Word16 slot_bytes) +/* not time critical */ +{ + Dyn_Mem_Deluxe_In( + Word16 n_codewords, payload_size; + ); + + n_codewords = get_n_codewords(slot_bytes); + + assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); + payload_size = slot_bytes; move16(); + + IF (fec_mode > 0) + { + IF (fec_mode == 1) + { + payload_size = sub(payload_size, 1); + } + ELSE + { + payload_size = sub(payload_size, DEPR_i_mult(sub(fec_mode, 1), n_codewords)); + } + IF (slot_bytes == 40) + { + payload_size = sub(payload_size, crc1_bytes_by_mode0[fec_mode]); move16(); + } + ELSE + { + payload_size = sub(payload_size, crc1_bytes_by_mode1[fec_mode]); move16(); + } + + IF (ccc_flag == 0 && fec_mode > 2 && slot_bytes >= 80) + { + payload_size = sub(payload_size, crc2_bytes_by_mode[fec_mode]); + } + } + + Dyn_Mem_Deluxe_Out(); + return payload_size; +} + +Word16 fec_get_n_pc(Word16 fec_mode, Word16 n_pccw, Word16 slot_bytes) +/* not time critical */ +{ + Dyn_Mem_Deluxe_In( + Word16 n_codewords, pc_split, tmp; + int i; + ); + + n_codewords = get_n_codewords(slot_bytes); + + assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); + pc_split = DEPR_i_mult(DEPR_i_mult(n_pccw, -2), sub(fec_mode, 1)); + + IF (fec_mode == 1 || slot_bytes < 80) + { + pc_split = 0; move16(); + } + ELSE + { + FOR (i = 0; i < n_pccw; i++) + { + tmp = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), sub(n_codewords, i + 1)); + assert(tmp == (2 * slot_bytes + i) / n_codewords); + pc_split = add(pc_split, tmp); + } + } + + Dyn_Mem_Deluxe_Out(); + return pc_split; +} + +/* functions for EPMR handling */ +FEC_STATIC void dw0_bitswap(UWord8 *dw0, Word16 mode, Word16 slot_bytes) +/* swap epmr bits with bits that will be positioned at 30 and 32 in code word 0 */ +{ + Dyn_Mem_Deluxe_In( + UWord8 tmp; + int ind0, ind1, position; + ); + + position = sub(get_codeword_length(get_n_codewords(slot_bytes), shl(slot_bytes, 1), 0), 1); + + IF (sub(slot_bytes, 40) == 0) + { + ind0 = sub(shl(crc1_bytes_by_mode0[mode], 1), 1); + } + ELSE + { + ind0 = sub(shl(crc1_bytes_by_mode1[mode], 1), 1); + } + + ind1 = sub(position, sub(hamming_distance_by_mode0[mode], 1)); + + /* swap bits 2 and 3 of dw0[ind0] with bits 0 and 1 of dw0[ind1] */ + tmp = (UWord8) s_and(shr(dw0[ind0],2), 3); + dw0[ind0] = (UWord8) s_and(dw0[ind0], 3); + dw0[ind0] = (UWord8) s_or(dw0[ind0], shl(s_and(dw0[ind1], 3),2)); + dw0[ind1] = (UWord8) s_and(dw0[ind1], 12); + dw0[ind1] = (UWord8) s_or(dw0[ind1], tmp); + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC Word16 cw0_get_epmr(UWord8 *cw0, Word16 position) +{ + Dyn_Mem_Deluxe_In( + Word16 epmr; + ); + epmr = s_and(cw0[position], 3); + + Dyn_Mem_Deluxe_Out(); + return epmr; +} + +FEC_STATIC Word16 dw0_get_epmr(UWord8 *dw0, Word16 mode, Word16 slot_size) +{ + Dyn_Mem_Deluxe_In( + int ncrc1; + Word16 epmr; + ); + + ncrc1 = crc1_bytes_by_mode1[mode]; + + if (sub(slot_size, 40) == 0) + { + ncrc1 = crc1_bytes_by_mode0[mode]; + } + + epmr = shr(dw0[2 * ncrc1 - 1], 2); + + Dyn_Mem_Deluxe_Out(); + return epmr; +} + + +FEC_STATIC Word16 fec_data_preproc(Word16 mode, Word16 epmr, UWord8 *iobuf, UWord8 *cw_buf, Word16 data_bytes, + Word16 slot_bytes, Word16 pc_split) +{ + Dyn_Mem_Deluxe_In( + Word16 data_offset, n_crc1, n_crc2, tmp; + int i, j; + ); + + tmp = sub(slot_bytes, data_bytes); + data_offset = add(tmp, tmp); + + /* extract and reverse data*/ + j = sub(add(slot_bytes, slot_bytes), 1); + FOR (i = 0; i < data_bytes; i++) + { + cw_buf[j--] = (UWord8)s_and(iobuf[i], 15); move16(); + cw_buf[j--] = (UWord8)shr(iobuf[i], 4); move16(); + } + + /* add crc hashes */ + IF (sub(slot_bytes, 40) == 0) + { + n_crc1 = crc1_bytes_by_mode0[mode]; move16(); + } + ELSE + { + n_crc1 = crc1_bytes_by_mode1[mode]; move16(); + } + + IF (pc_split > 0 && sub(mode, 1) > 0) + { + n_crc2 = crc2_bytes_by_mode[mode]; move16(); + } + ELSE + { + n_crc2 = 0; move16(); + } + + IF (n_crc2) + { + crc2(cw_buf + data_offset + 2 * data_bytes - pc_split, pc_split, cw_buf + data_offset - 2 * n_crc2, n_crc2, 0); + } + IF (n_crc1) + { + crc1(cw_buf + data_offset, 2 * data_bytes - pc_split, epmr, cw_buf + data_offset - 2 * (n_crc1 + n_crc2), n_crc1, + 0); + } + + tmp = add(n_crc1, n_crc2); + data_offset = sub(data_offset, add(tmp, tmp)); + + dw0_bitswap(cw_buf + data_offset, mode, slot_bytes); + + Dyn_Mem_Deluxe_Out(); + return data_offset; +} + +void fec_encoder(Word16 mode, Word16 epmr, UWord8 *iobuf, Word16 data_bytes, Word16 slot_bytes, Word16 n_pccw, + void *scratch) +{ + Dyn_Mem_Deluxe_In( + Word16 n_codewords, codeword_length, hd, redundancy_nibbles, cw_offset, dw_offset, pc_split; + int i, j; + UWord8 *cw_buf; + ); + + cw_offset = 0; move16(); + dw_offset = 0; move16(); + pc_split = 0; move16(); + cw_buf = scratch; + + n_codewords = get_n_codewords(slot_bytes); + assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); + + /* some sanity checks */ + { + int tmp = slot_bytes; + assert((slot_bytes >= FEC_SLOT_BYTES_MIN && slot_bytes <= FEC_SLOT_BYTES_MAX) && + "fec_encoder: slot_bytes out of range"); + tmp -= mode == 1 ? 1 : n_codewords * (mode - 1); // reed solomon redundancy + tmp -= slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode]; // crc1 + tmp -= (n_pccw > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0; // crc2 + assert(data_bytes == tmp && "fec_encoder: inconsistent payload size"); + assert(n_codewords - n_pccw >= 6); + } + + /* data preproc: re-ordering and hash extension */ + pc_split = fec_get_n_pc(mode, n_pccw, slot_bytes); + + dw_offset = fec_data_preproc(mode, epmr, iobuf, cw_buf, data_bytes, slot_bytes, pc_split); + + /* encoding of first data word*/ + hd = hamming_distance_by_mode0[mode]; move16(); + redundancy_nibbles = sub(hd, 1); + codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), 0); + + assert(codeword_length == (2 * slot_bytes - 1) / n_codewords + 1); + + FOR (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++)) + { + cw_buf[j] = cw_buf[dw_offset]; move16(); + } + + rs16_enc(cw_buf, codeword_length, hd, mode, 1); + + cw_offset = add(cw_offset, codeword_length); + + /* encoding of remaining data words */ + hd = hamming_distance_by_mode1[mode]; move16(); + redundancy_nibbles = sub(hd, 1); + + FOR (i = 1; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), i); + + assert(codeword_length == (2 * slot_bytes - i - 1) / n_codewords + 1); + FOR (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++)) + { + cw_buf[cw_offset + j] = cw_buf[dw_offset]; move16(); + } + + rs16_enc(cw_buf + cw_offset, codeword_length, hd, mode, sub(i, 6) < 0); + + cw_offset = add(cw_offset, codeword_length); + } + + assert(cw_offset == 2 * slot_bytes && dw_offset == 2 * slot_bytes); + + fec_interleave_pack(iobuf, cw_buf, add(slot_bytes, slot_bytes), n_codewords); + + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC void rs16_enc(UWord8 *iobuf, Word16 codeword_length, Word16 hamming_distance, Word16 fec_mode, + Word16 signal_mode) +/* expects (data polynomial) * x^(hamming_distance - 1) in iobuf */ +{ + + Dyn_Mem_Deluxe_In( + UWord8 const *gp; + UWord8 shift_buffer[RS16_CW_LEN_MAX + 1], lc; + int i, j, deg_gp; + ); + + basop_memset(shift_buffer, 0, sizeof(shift_buffer)); + gp = rs16_gp_by_hd[hamming_distance]; move16(); + deg_gp = sub(hamming_distance, 1); + + IF (sub(hamming_distance, 1) > 0) + { + assert(codeword_length > deg_gp); + + /* initialize redundancy part to zero */ + basop_memset(iobuf, 0, deg_gp); + + /* initialize shift_buffer */ + basop_memmove(shift_buffer + 1, iobuf + codeword_length - deg_gp, deg_gp); + + /* calculate remainder */ + FOR (i = codeword_length - deg_gp - 1; i >= 0; i--) + { + shift_buffer[0] = iobuf[i]; move16(); + lc = (UWord8)shl(shift_buffer[deg_gp], 4); move16(); + FOR (j = deg_gp - 1; j >= 0; j--) + { + shift_buffer[j + 1] = GF16_ADD(shift_buffer[j], GF16_MUL0(gp[j], lc)); move16(); + } + } + + /* add remainder to shifted data polynomial */ + FOR (i = 0; i < deg_gp; i++) + { + iobuf[i] = shift_buffer[i + 1]; move16(); + } + + /* add signaling polynomial */ + IF (signal_mode) + { + assert(codeword_length > EP_SIG_POLY_DEG); + FOR (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[i] = GF16_ADD(iobuf[i], sig_polys[fec_mode - 1][i]); move16(); + } + } + } + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC void fec_interleave_pack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords) +{ + Dyn_Mem_Deluxe_In( + Word16 out_offset, cw_offset, codeword_length; + int i, j; + ); + + out_offset = 0; move16(); + cw_offset = 0; move16(); + + /* initialize output buffer to zero */ + basop_memset(out, 0, shr(n_nibbles, 1)); + + /* interleave and pack codewords */ + FOR (i = 0; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, n_nibbles, i); + + assert(codeword_length == (n_nibbles - i - 1) / n_codewords + 1); + FOR (j = 0; j < codeword_length; j++) + { + out_offset = add(DEPR_i_mult(j, n_codewords), i); + out_offset = sub(n_nibbles, add(out_offset, 1)); + out[out_offset >> 1] = + (UWord8)s_or(out[out_offset >> 1], shl(in[cw_offset], shl(s_and(out_offset, 1), 2))); move16(); + cw_offset = add(cw_offset, 1); + } + } + + assert(cw_offset == n_nibbles); + Dyn_Mem_Deluxe_Out(); +} + +/* Decoder */ +FEC_STATIC void fec_data_postproc(Word16 mode, Word16 *epmr, UWord8 *obuf, Word16 data_bytes, UWord8 *cw_buf, + Word16 slot_bytes, Word16 pc_split, int *bfi) +{ + Dyn_Mem_Deluxe_In( + Word16 i; + Word16 n_crc1, n_crc2; + Word16 cw_buf_len; + Word16 tmp_epmr; + ); + + n_crc1 = crc1_bytes_by_mode1[mode]; move16(); + if (sub(slot_bytes, 40) == 0) + { + n_crc1 = crc1_bytes_by_mode0[mode]; move16(); + } + + n_crc2 = 0; move16(); + if (pc_split > 0) + { + n_crc2 = crc2_bytes_by_mode[mode]; move16(); + } + + assert(n_crc1 == (slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode])); + assert(n_crc2 == ((pc_split > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0)); + + cw_buf_len = 2 * (data_bytes + n_crc1 + n_crc2); + + IF (sub(mode, 1)) + { + /* reverse bit-swap */ + dw0_bitswap(cw_buf, mode, slot_bytes); + tmp_epmr = dw0_get_epmr(cw_buf, mode, slot_bytes); + + IF (crc1(cw_buf + shl(add(n_crc1, n_crc2), 1), sub(shl(data_bytes, 1), pc_split), tmp_epmr, cw_buf, n_crc1, 1)) + { + *bfi = 1; move32(); + + Dyn_Mem_Deluxe_Out(); + return; + } + else + { + *epmr = tmp_epmr; + } + } + + test(); + IF (pc_split > 0 && sub(*bfi, 2) != 0) + { + IF (crc2(cw_buf + sub(shl(add(data_bytes, add(n_crc1, n_crc2)), 1), pc_split), pc_split, + cw_buf + shl(n_crc1, 1), n_crc2, 1)) + { + *bfi = 2; move32(); + } + } + + FOR (i = 0; i < data_bytes; i++) + { + obuf[i] = (UWord8)s_or(cw_buf[cw_buf_len - 2 * i - 1], shl(cw_buf[cw_buf_len - 2 * i - 2], 4)); move16(); + } + Dyn_Mem_Deluxe_Out(); +} + +int fec_decoder(UWord8 *iobuf, Word16 slot_bytes, int *data_bytes, Word16 *epmr, Word16 ccc_flag, Word16 *n_pccw, + int *bfi, Word16 *be_bp_left, Word16 *be_bp_right, Word16 *n_pc, Word16 *m_fec, void *scratch) +{ + Dyn_Mem_Deluxe_In( + UWord8 *my_scratch; + UWord8 *cw_buf; + UWord8 *array_of_trust; + Word16 i, j; + Word16 cw_offset, dw_offset; + Word16 n_codewords, redundancy_nibbles, codeword_length; + Word16 mode, error_report; + Word16 n_crc; + Word16 first_bad_cw; + Word16 pc_split; + ); + + IF (*bfi == 1) + { + Dyn_Mem_Deluxe_Out(); + return ERROR_REPORT_BEC_MASK; + } + + if (slot_bytes < FEC_SLOT_BYTES_MIN || slot_bytes > FEC_SLOT_BYTES_MAX) + { + *bfi = 1; + return ERROR_REPORT_BEC_MASK; + } + + my_scratch = (UWord8 *)scratch; move32(); + cw_buf = my_scratch; move32(); + my_scratch += 2 * slot_bytes; + + IF (ccc_flag == 0) + { + *be_bp_left = -1; move16(); + *be_bp_right = -1; move16(); + } + + n_codewords = get_n_codewords(slot_bytes); + + array_of_trust = my_scratch; move32(); + my_scratch += n_codewords; + + /* extract and de-interleave nibbles */ + fec_deinterleave_unpack(cw_buf, iobuf, 2 * slot_bytes, n_codewords); + + /* mode detection and error correction */ + mode = rs16_detect_and_correct(cw_buf, 2 * slot_bytes, n_codewords, epmr, &error_report, bfi, array_of_trust, + ccc_flag, n_pccw, (void *)my_scratch); + + /* for normal slots the maximal number of bit errors is limited */ + test(); +#ifndef APPLY_MAX_ERRORS + IF (sub(slot_bytes, 40) == 0 && mode > 0) + { + IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[mode]) > 0) + { + error_report &= ERROR_REPORT_BEC_MASK; + mode = -1; move16(); + *bfi = 1; move32(); + } + ELSE + { + IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[2]) > 0) + { + error_report &= ~ERROR_REPORT_EP2_OK; + } + IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[3])>0) + { + error_report &= ~ERROR_REPORT_EP3_OK; + } + } + } +#endif + + IF (sub(*bfi, 1) == 0) + { + *data_bytes = 0; move16(); + + Dyn_Mem_Deluxe_Out(); + return error_report; + } + + /* initialization for decoding */ + *data_bytes = fec_get_data_size(mode, ccc_flag, slot_bytes); move32(); + pc_split = fec_get_n_pc(mode, *n_pccw, slot_bytes); + n_crc = get_total_crc_size(slot_bytes, mode, pc_split); + + /* decoding of first code word */ + redundancy_nibbles = sub(hamming_distance_by_mode0[mode], 1); + codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), 0); + + dw_offset = 0; move16(); + cw_offset = 0; move16(); + + FOR (j = redundancy_nibbles; j < codeword_length; j++) + { + cw_buf[dw_offset++] = cw_buf[j]; move16(); + } + cw_offset = add(cw_offset, codeword_length); + + /* decoding of remaining code words */ + redundancy_nibbles = sub(hamming_distance_by_mode1[mode], 1); + + FOR (i = 1; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), i); + + FOR (j = redundancy_nibbles; j < codeword_length; j++) + { + cw_buf[dw_offset++] = cw_buf[j + cw_offset]; move16(); + } + + cw_offset = add(cw_offset, codeword_length); + } + + assert(2 * (*data_bytes + n_crc) == dw_offset && 2 * slot_bytes == cw_offset); + + /* data postproc: hash validation and re-ordering */ + + fec_data_postproc(mode, epmr, iobuf, *data_bytes, cw_buf, slot_bytes, pc_split, bfi); + + IF (sub(*bfi, 1) == 0) + { + *data_bytes = 0; move32(); + error_report &= ERROR_REPORT_BEC_MASK; + Dyn_Mem_Deluxe_Out(); + return error_report; + } + + IF (*bfi == 2) + { + first_bad_cw = 0; move16(); + array_of_trust[*n_pccw] = 0; move16(); + WHILE (array_of_trust[first_bad_cw] != 0) + { + first_bad_cw = add(first_bad_cw, 1); + } + IF (sub(first_bad_cw, *n_pccw) == 0) + { + /* this is the case when CRC failed */ + *be_bp_left = 0; move16(); + } + ELSE + { + *be_bp_left = extract_l(L_mult0(fec_get_n_pc(mode, first_bad_cw, slot_bytes), 4)); move16(); + } + + FOR (i = *n_pccw - 1; i >= 0; i--) + { + if (!array_of_trust[i]) + { + BREAK; + } + } + IF (i < 0) + { + i = sub(*n_pccw, 1); + } + *be_bp_right = sub(extract_l(L_mult0(fec_get_n_pc(mode, i+1, slot_bytes), 4)), 1); move16(); + + } + + IF (ccc_flag == 0) + { + *n_pc = pc_split; move16(); + *m_fec = mode; move16(); + } + + + Dyn_Mem_Deluxe_Out(); + return error_report; +} + +FEC_STATIC void fec_deinterleave_unpack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords) +{ + Dyn_Mem_Deluxe_In( + Word16 in_offset, out_offset, codeword_length; + int i, j; + ); + + in_offset = 0; move16(); + out_offset = 0; move16(); + + /* unpack nibbles in input buffer and deinterleave codewords */ + FOR (i = 0; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, n_nibbles, i); + FOR (j = 0; j < codeword_length; (j++, out_offset++)) + { + in_offset = add(DEPR_i_mult(j, n_codewords), i); + in_offset = sub(n_nibbles, add(in_offset, 1)); + out[out_offset] = (UWord8)s_and(shr(in[in_offset >> 1], shl(s_and(in_offset, 1), 2)), 15); move16(); + } + } + + assert(out_offset == n_nibbles); + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC Word16 fec_estimate_epmr_from_cw0(UWord8 *cw0, Word8 *t, UWord8 *syndromes, UWord8 *elp, Word8 *deg_elp, + UWord8 *err_pos, UWord8 *err_symb, Word16 n_codewords, Word16 n_symb) +{ + Dyn_Mem_Deluxe_In( + int epmr_lowest_risk_exp; + int start, inc, i, n_candidates; + int first_codeword_length; + int mode_counter; + Word16 epmr; + ); + + epmr_lowest_risk_exp = 0; + first_codeword_length = get_codeword_length(n_codewords, n_symb, 0); + start = 2; + inc = 1; + n_candidates = 0; + + /* test if first code word decodes in mode 0 or 1 without error correction */ + test(); + IF (s_or(syndromes[SYNDROME_IDX(0, 0)], syndromes[SYNDROME_IDX(0, 0) + 1]) == 0 || + s_or(syndromes[SYNDROME_IDX(1, 0)], syndromes[SYNDROME_IDX(1, 0) + 1]) == 0) + { + epmr_lowest_risk_exp = risk_table_f[1][0].exponent; move16(); + } + /* test if first code word decodes in mode 2 or 3 with lower risk */ + IF (sub(deg_elp[DEG_ELP_IDX(2, 0)], t[2]) <= 0) + { + IF (add(risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]].exponent, 8) <= 0) + { + n_candidates++; + start = 2; + } + } + + IF (sub(deg_elp[DEG_ELP_IDX(3, 0)], t[3]) <= 0) + { + IF (add(risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]].exponent, 8) <= 0) + { + n_candidates++; + start = 3; + } + } + + IF (sub(n_candidates, 1) > 0) + { + /* decide on order if mode 2 and 3 are considered */ + IF (simple_float_cmp(risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]], risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]]) < + 0) + { + start = 2; + inc = 1; + } + ELSE + { + start = 3; + inc = -1; + } + } + + FOR ((mode_counter = start, i = 0); i < n_candidates; (mode_counter += inc, i++)) + { + IF (sub(risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent, epmr_lowest_risk_exp) < 0) + { + IF (!rs16_factorize_elp(err_pos + ERR_POS_IDX(mode_counter, 0), elp + ELP_IDX(mode_counter, 0), + deg_elp[DEG_ELP_IDX(mode_counter, 0)], sub(first_codeword_length, 1))) + { + /* code word is decodable with error correction */ + epmr_lowest_risk_exp = risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent; + + rs16_calculate_errors(err_symb + ERR_SYMB_IDX(mode_counter, 0), err_pos + ERR_POS_IDX(mode_counter, 0), + syndromes + SYNDROME_IDX(mode_counter, 0), deg_elp[DEG_ELP_IDX(mode_counter, 0)], + t[mode_counter]); + + FOR (i = 0; i < deg_elp[DEG_ELP_IDX(mode_counter, 0)]; i++) + { + cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]] = GF16_ADD( + cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]], err_symb[ERR_SYMB_IDX(mode_counter, 0) + i]); + } + BREAK; + } + } + } + + epmr = cw0_get_epmr(cw0, sub(first_codeword_length, 1)); + + IF (add(epmr_lowest_risk_exp, 16) > 0) + { + epmr = add(epmr, 4); move16(); + } + IF (add(epmr_lowest_risk_exp, 8) > 0) + { + epmr = add(epmr, 4); move16(); + } + + Dyn_Mem_Deluxe_Out(); + return epmr; +} + +FEC_STATIC int rs16_detect_and_correct(UWord8 *iobuf, int n_symb, int n_codewords, Word16 *epmr, Word16 *error_report, + int *bfi, UWord8 *array_of_trust, int ccc_flag, Word16 *n_pccw, void *scratch) +{ + Dyn_Mem_Deluxe_In( + UWord8 * syndromes; + UWord8 * elp; + UWord8 * err_pos; + UWord8 * err_symb; + Word8 t[FEC_N_MODES]; + Word8 * deg_elp; + UWord8 * my_scratch; + UWord8 blacklist[FEC_N_MODES]; + UWord8 const *hamming_distance; + + Word16 i, cw_counter, mode_counter, cw_offset; + Word16 codeword_length; + Word16 mode; + Word16 mode_candidates[4]; + Word16 mode_broken[4]; + Word16 error_report_ep_ok[4]; + Word16 n_mode_candidates; + Word16 broken_cw, n_broken_cw; + Word16 j, idx_min; + Word16 n_pccw0; + simple_float val_min_f; + Word16 tmp; + Word16 epmr_position; + simple_float dec_risk_f[FEC_N_MODES]; + simple_float risk_min_f; + simple_float ep_risk_thresh; + + int epmr_dec_fail_increment; + + void (*syndr_calc[3])(UWord8 *, UWord8 *, int); + ); + + /* initialization */ + blacklist[0] = 0; move16(); + blacklist[1] = 0; move16(); + blacklist[2] = 0; move16(); + blacklist[3] = 0; move16(); + mode_broken[0] = 0; move16(); + mode_broken[1] = 0; move16(); + mode_broken[2] = 0; move16(); + mode_broken[3] = 0; move16(); + error_report_ep_ok[0] = ERROR_REPORT_EP1_OK; + error_report_ep_ok[1] = ERROR_REPORT_EP2_OK; + error_report_ep_ok[2] = ERROR_REPORT_EP3_OK; + error_report_ep_ok[3] = ERROR_REPORT_EP4_OK; + my_scratch = (UWord8 *)scratch; + hamming_distance = &hamming_distance_by_mode0[1]; + mode = -1; move16(); + n_mode_candidates = 0; move16(); + risk_min_f.mantissa = SIMPLE_FLOAT_1_MANTISSA; move16(); + risk_min_f.exponent = 0; move16(); + + IF (n_symb <= 80) + { + ep_risk_thresh.mantissa = EP_RISK_THRESH_NS_M; move16(); + ep_risk_thresh.exponent = EP_RISK_THRESH_NS_E; move16(); + } + ELSE + { + ep_risk_thresh.mantissa = EP_RISK_THRESH_OS_M; move16(); + ep_risk_thresh.exponent = EP_RISK_THRESH_OS_E; move16(); + } + + syndr_calc[0] = &rs16_calculate_two_syndromes; + syndr_calc[1] = &rs16_calculate_four_syndromes; + syndr_calc[2] = &rs16_calculate_six_syndromes; + + FOR (i = 0; i < FEC_N_MODES; i++) + { + t[i] = (Word8)shr(sub(hamming_distance[i], 1), 1); move16(); + } + + syndromes = my_scratch; + my_scratch += FEC_TOTAL_SYNDROME_SIZE; + elp = my_scratch; + my_scratch += FEC_TOTAL_ELP_SIZE; + err_pos = my_scratch; + my_scratch += FEC_TOTAL_ERR_POS_SIZE; + err_symb = my_scratch; + my_scratch += FEC_TOTAL_ERROR_SIZE; + deg_elp = (Word8 *)my_scratch; + my_scratch += FEC_TOTAL_DEG_ELP_SIZE; + + *error_report = 0; move16(); + *bfi = 0; move32(); + + /* mode detection (stage 1) */ + codeword_length = get_codeword_length(n_codewords, n_symb, 0); + + epmr_position = sub(codeword_length, 1); + + rs16_calculate_two_syndromes(syndromes + SYNDROME_IDX(0, 0), iobuf, sub(codeword_length, 1)); + + IF (s_or(syndromes[0 + SYNDROME_IDX(0, 0)], syndromes[1 + SYNDROME_IDX(0, 0)]) == 0) + { + + /* data validation for fec mode 1 */ + *epmr = cw0_get_epmr(iobuf, epmr_position); + + dw0_bitswap(iobuf + 2, 1, n_symb / 2); + + IF (!crc1(iobuf + 8, sub(n_symb, 8), *epmr, iobuf + 2, 3, 1)) + { + mode = 0; move16(); + *error_report |= ERROR_REPORT_ALL_OK; + Dyn_Mem_Deluxe_Out(); + return add(mode, 1); + } + ELSE + { + /* reverse bit swap */ + dw0_bitswap(iobuf + 2, 1, n_symb / 2); + + *epmr = add(*epmr, 4); move16(); + } + } + + blacklist[0] = 1; move16(); + + /* mode detection (stage 2) */ + + /* calculate syndromes of code words 0 to 5 and modes 1 to 3 */ + cw_offset = 0; move16(); + + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + rs16_calculate_six_syndromes(syndromes + SYNDROME_IDX(1, cw_counter), iobuf + cw_offset, + sub(codeword_length, 1)); + + cw_offset = add(cw_offset, codeword_length); + + FOR (mode_counter = FEC_N_MODES - 1; mode_counter >= 1; mode_counter--) + { + FOR (i = 0; i < sub(hamming_distance[mode_counter], 1); i++) + { + syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i] = GF16_ADD( + syndromes[SYNDROME_IDX(1, cw_counter) + i], sig_poly_syndr[mode_counter][i]); move16(); + } + } + } + + /* check for valid code words */ + FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + n_broken_cw = 0; + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + broken_cw = 0; + FOR (i = 0; i < sub(hamming_distance[mode_counter], 1); i++) + { + broken_cw = s_or(broken_cw, syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i]); move16(); + } + IF (broken_cw != 0) + { + n_broken_cw = add(n_broken_cw, 1); + } + } + + IF (n_broken_cw == 0) + { + mode = mode_counter; move16(); + cw_offset = 0; move16(); + + *epmr = cw0_get_epmr(iobuf, epmr_position); + + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + FOR (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]); + } + cw_offset = add(cw_offset, codeword_length); + } + } + } + + IF (mode < 0) /* mode hasn't been detected so far -> errors occurred in transmission */ + { + /* calculate error locator polynomials for code words 0 to 5 */ + FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)] = rs16_calculate_elp( + elp + ELP_IDX(mode_counter, cw_counter), syndromes + SYNDROME_IDX(mode_counter, cw_counter), + t[mode_counter]); move16(); + IF (sub(deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)], t[mode_counter]) > 0) + { + blacklist[mode_counter] = 1; move16(); + BREAK; + } + } + } + + /* risk analysis for mode candidate selection */ + FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + dec_risk_f[mode_counter].mantissa = SIMPLE_FLOAT_1_MANTISSA; move16(); + dec_risk_f[mode_counter].exponent = 0; move16(); + + IF (blacklist[mode_counter] == 0) + { + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + dec_risk_f[mode_counter] = simple_float_mul( + dec_risk_f[mode_counter], + risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)]]); move16(); + } + + IF (simple_float_cmp(dec_risk_f[mode_counter], ep_risk_thresh) <= 0) + { + mode_candidates[n_mode_candidates++] = mode_counter; move16(); + } + + IF (simple_float_cmp(dec_risk_f[mode_counter], risk_min_f) < 0) + { + risk_min_f = dec_risk_f[mode_counter]; move16(); + } + } + } + assert(n_mode_candidates <= 4); // suppress false gcc warning when OPTIM=3 + + /* sort mode candidates by risk */ + FOR (i = 0; i < n_mode_candidates; i++) + { + idx_min = i; move16(); + val_min_f = dec_risk_f[mode_candidates[i]]; move16(); + + FOR (j = i + 1; j < n_mode_candidates; j++) + { + IF (simple_float_cmp(dec_risk_f[mode_candidates[j]], val_min_f) < 0) + { + val_min_f = dec_risk_f[mode_candidates[j]]; move16(); + idx_min = j; move16(); + } + } + + IF (sub(idx_min, i) > 0) + { + tmp = mode_candidates[i]; move16(); + mode_candidates[i] = mode_candidates[idx_min]; move16(); + mode_candidates[idx_min] = tmp; move16(); + } + } + + /* try out candidate modes */ + FOR (i = 0; i < n_mode_candidates; i++) + { + mode = mode_candidates[i]; move16(); + + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + IF (deg_elp[DEG_ELP_IDX(mode, cw_counter)]) + { + IF (rs16_factorize_elp(err_pos + ERR_POS_IDX(mode, cw_counter), elp + ELP_IDX(mode, cw_counter), + deg_elp[DEG_ELP_IDX(mode, cw_counter)], sub(codeword_length, 1))) + { + /* elp did not split into distinct linear factors or error position was out of range */ + mode = -1; move16(); + BREAK; + } + } + } + IF (mode > 0) + { + /* decodable mode with lowest risk has been found */ + BREAK; + } + } + + IF (mode < 0) + { + /* no decodable mode has been found */ + *error_report = ERROR_REPORT_BEC_MASK; move16(); + *bfi = 1; move32(); + mode = -1; move16(); + + *epmr = fec_estimate_epmr_from_cw0(iobuf, t, syndromes, elp, deg_elp, err_pos, err_symb, n_codewords, + n_symb); + + Dyn_Mem_Deluxe_Out(); + return mode; + } + + /* perform error correction */ + cw_offset = 0; move16(); + *error_report = 0; move16(); + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + IF (deg_elp[DEG_ELP_IDX(mode, cw_counter)]) + { + rs16_calculate_errors( + err_symb + ERR_SYMB_IDX(mode, cw_counter), err_pos + ERR_POS_IDX(mode, cw_counter), + syndromes + SYNDROME_IDX(mode, cw_counter), deg_elp[DEG_ELP_IDX(mode, cw_counter)], t[mode]); + + /* correct errors and sum up number of corrected bits */ + FOR (i = 0; i < deg_elp[DEG_ELP_IDX(mode, cw_counter)]; i++) + { + iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset] = + GF16_ADD(iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset], + err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]); + *error_report = add(*error_report, + rs16_bit_count_table[err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]]); move16(); + } + + FOR (i = 0; i < mode; i ++) + { + IF(deg_elp[DEG_ELP_IDX(mode, cw_counter)] > i) + { + mode_broken[i] = 1; + } + } + } + + FOR (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]); + } + cw_offset = add(cw_offset, codeword_length); + } + + /* set epmr according to risk value of cw0 */ + epmr_dec_fail_increment = 8; + + IF (add(risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent, 8) <= 0) + { + epmr_dec_fail_increment = sub(epmr_dec_fail_increment, 4); + } + IF (add(risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent, 16) <= 0) + { + epmr_dec_fail_increment = sub(epmr_dec_fail_increment, 4); + } + + *epmr = cw0_get_epmr(iobuf, epmr_position) + epmr_dec_fail_increment; + } + + /* mode has been successfully detected -> now check and try to correct remaining code words*/ + *n_pccw = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag); + IF (ccc_flag == 0) + { + n_pccw0 = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag); + *n_pccw = n_pccw0; + } + ELSE + { + n_pccw0 = 0; + } + + FOR (cw_counter = 6; cw_counter < n_codewords; cw_counter++) + { + /* usual error correction scheme: syndromes -> elp's, errors, etc. */ + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + array_of_trust[n_codewords - 1 - cw_counter] = 1; move16(); + + syndr_calc[sub(t[mode], 1)](syndromes, iobuf + cw_offset, sub(codeword_length, 1)); + + deg_elp[0] = rs16_calculate_elp(elp, syndromes, t[mode]); move16(); + + FOR (i = 0; i < mode; i ++) + { + IF(deg_elp[0] > i) + { + mode_broken[i] = 1; + } + } + IF (sub(deg_elp[0], t[mode]) > 0) + { + FOR (i = 0; i < 4; i ++) + { + mode_broken[i] = 1; + } + cw_offset = add(cw_offset, codeword_length); + IF (cw_counter < n_codewords - n_pccw0) + { + *error_report = ERROR_REPORT_BEC_MASK; move16(); + mode = -1; move16(); + *bfi = 1; move32(); + + BREAK; + } + ELSE + { + *bfi = 2; move32(); + array_of_trust[n_codewords - 1 - cw_counter] = 0; move16(); + CONTINUE; + } + } + + IF (deg_elp[0]) + { + IF (rs16_factorize_elp(err_pos, elp, deg_elp[0], sub(codeword_length, 1))) + { + cw_offset = add(cw_offset, codeword_length); + FOR (i = 0; i < 4; i ++) + { + mode_broken[i] = 1; + } + IF (add(n_pccw0, sub(cw_counter, n_codewords)) < 0) + { + *error_report = ERROR_REPORT_BEC_MASK; move16(); + mode = -1; move16(); + *bfi = 1; move32(); + + BREAK; + } + ELSE + { + *bfi = 2; move32(); + array_of_trust[n_codewords - 1 - cw_counter] = 0; move16(); + CONTINUE; + } + } + + rs16_calculate_errors(err_symb, err_pos, syndromes, deg_elp[0], t[mode]); + + /* correct errors and sum up number of corrected bits */ + FOR (i = 0; i < deg_elp[0]; i++) + { + iobuf[err_pos[i] + cw_offset] = GF16_ADD(iobuf[err_pos[i] + cw_offset], err_symb[i]); + *error_report = add(*error_report, rs16_bit_count_table[err_symb[i]]); + } + } + cw_offset = add(cw_offset, codeword_length); + if (add(risk_table_f[mode][deg_elp[0]].exponent, 16) > 0) + { + array_of_trust[n_codewords - 1 - cw_counter] = 0; move16(); + } + } + + *error_report &= ERROR_REPORT_BEC_MASK; + FOR (i = 0; i < 4; i ++) + { + IF (!mode_broken[i]) + { + *error_report |= error_report_ep_ok[i]; + } + } + + Dyn_Mem_Deluxe_Out(); + IF (mode >= 0) + { + return add(mode, 1); + } + + return -1; +} + +FEC_STATIC void rs16_calculate_six_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg) +{ + Dyn_Mem_Deluxe_In( + int i; + UWord8 buffer[15]; + ); + + assert(cw_poly_deg >= 12); + + FOR (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; move16(); + } + + syndromes[0] = buffer[0]; move16(); + syndromes[1] = buffer[0]; move16(); + syndromes[2] = buffer[0]; move16(); + syndromes[3] = buffer[0]; move16(); + syndromes[4] = buffer[0]; move16(); + syndromes[5] = buffer[0]; move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[1], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[1], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[2], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[2], 240)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[3], 16)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[3], 128)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[4], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[4], 160)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[5], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[5], 16)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[6], 16)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[6], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[7], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[7], 240)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[8], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[8], 128)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[9], 16)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[9], 160)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[10], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[10], 16)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[11], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[11], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[12], 16)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[12], 240)); move16(); + + IF (sub(cw_poly_deg, 13) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[13], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[13], 128)); move16(); + } + + IF (sub(cw_poly_deg, 14) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[14], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[14], 160)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC void rs16_calculate_four_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg) +{ + Dyn_Mem_Deluxe_In( + int i; + UWord8 buffer[15]; + ); + + assert(cw_poly_deg >= 12); + + FOR (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; move16(); + } + + syndromes[0] = buffer[0]; move16(); + syndromes[1] = buffer[0]; move16(); + syndromes[2] = buffer[0]; move16(); + syndromes[3] = buffer[0]; move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); move16(); + + IF (sub(cw_poly_deg, 13) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); move16(); + } + + IF (sub(cw_poly_deg, 14) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC void rs16_calculate_two_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg) +{ + Dyn_Mem_Deluxe_In( + int i; + UWord8 buffer[15]; + ); + + assert(cw_poly_deg >= 12); + + FOR (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; move16(); + } + + syndromes[0] = buffer[0]; move16(); + syndromes[1] = buffer[0]; move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16(); + + IF (sub(cw_poly_deg, 13) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16(); + } + + IF (sub(cw_poly_deg, 14) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC Word8 rs16_calculate_elp(UWord8 *elp, UWord8 *syndromes, Word16 t) +/* calculates error locator polynomial vie Petterson's algorithm */ +{ + Dyn_Mem_Deluxe_In( + Word8 ret; + UWord8 det, det_inv, aux, all_s, *s; + UWord8 s22, s33, s44, s13, s14, s15; + UWord8 s23, s24, s25, s34, s35; + UWord8 a, b, c, d, e, f; + ); + + ret = 0; move16(); + all_s = 0; move16(); + s = syndromes; move16(); + elp[0] = 1; move16(); + basop_memset(elp + 1, 0, 3); + + SWITCH (t) + { + case 3: + { + /* check for errors */ + all_s = (UWord8)s_or(s[0], s_or(s[1], s_or(s[2], s_or(s[3], s_or(s[4], s[5]))))); + + IF (all_s == 0) + { + BREAK; + } + + /* assume 3 errors */ + s22 = GF16_MUL(s[1], s[1]); + s33 = GF16_MUL(s[2], s[2]); + s44 = GF16_MUL(s[3], s[3]); + s13 = GF16_MUL(s[0], s[2]); + + det = GF16_ADD(GF16_ADD(GF16_MUL(s13, s[4]), GF16_MUL(s44, s[0])), + GF16_ADD(GF16_MUL(s22, s[4]), GF16_MUL(s33, s[2]))); + + IF (det) + { + det_inv = (UWord8)shl(gf16_inv_table[det], 4); + + s14 = GF16_MUL(s[0], s[3]); + s15 = GF16_MUL(s[0], s[4]); + + s23 = GF16_MUL(s[1], s[2]); + s24 = GF16_MUL(s[1], s[3]); + s25 = GF16_MUL(s[1], s[4]); + + s34 = GF16_MUL(s[2], s[3]); + s35 = GF16_MUL(s[2], s[4]); + + a = GF16_ADD(s35, s44) << 4; + b = GF16_ADD(s15, s33) << 4; + c = GF16_ADD(s13, s22) << 4; + d = GF16_ADD(s34, s25) << 4; + e = GF16_ADD(s23, s14) << 4; + f = GF16_ADD(s24, s33) << 4; + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(a, s[3]), GF16_MUL0(d, s[4])), GF16_MUL0(f, s[5])); + elp[3] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(d, s[3]), GF16_MUL0(b, s[4])), GF16_MUL0(e, s[5])); + elp[2] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(f, s[3]), GF16_MUL0(e, s[4])), GF16_MUL0(c, s[5])); + elp[1] = GF16_MUL0(aux, det_inv); + + IF (elp[3] == 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 3; move16(); + } + BREAK; + } + + /* assume two errors */ + det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1])); + + IF (det) + { + det_inv = (UWord8)shl(gf16_inv_table[det], 4); + + aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3])); + elp[1] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3])); + elp[2] = GF16_MUL0(aux, det_inv); + + /* check remaining LSF relations */ + aux = (UWord8)s_or(GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[2]), GF16_MUL(elp[1], s[3])), s[4]), + GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[3]), GF16_MUL(elp[1], s[4])), s[5])); + + aux = (UWord8)s_or(aux, elp[2] == 0); + + IF (aux != 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 2; move16(); + } + BREAK; + } + + /* assume one error */ + IF (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + + /* check remaining LSF relations */ + aux = (UWord8)s_or(s_or(GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]), GF16_ADD(GF16_MUL(elp[1], s[2]), s[3])), + s_or(GF16_ADD(GF16_MUL(elp[1], s[3]), s[4]), GF16_ADD(GF16_MUL(elp[1], s[4]), s[5]))); + + aux = (UWord8)s_or(aux, elp[1] == 0); + + IF (aux != 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 1; move16(); + } + BREAK; + } + + ret = (Word8) add(t, 1); + BREAK; + } + case 2: + { + all_s = (UWord8)s_or(s[0], s_or(s[1], s_or(s[2], s[3]))); + + IF (all_s == 0) + { + BREAK; + } + + /* assume two errors */ + det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1])); + + IF (det) + { + det_inv = (UWord8)shl(gf16_inv_table[det], 4); + + aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3])); + elp[1] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3])); + elp[2] = GF16_MUL0(aux, det_inv); + + IF (elp[2] == 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 2; move16(); + } + BREAK; + } + + /* assume one error */ + IF (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + + /* check remaining LSF relation */ + aux = (UWord8)s_or(GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]), GF16_ADD(GF16_MUL(elp[1], s[2]), s[3])); + aux = (UWord8)s_or(aux, elp[1] == 0); + IF (aux != 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 1; move16(); + } + BREAK; + } + + ret = (Word8) add(t, 1); + BREAK; + } + case 1: + { + all_s = (UWord8)s_or(s[0], s[1]); + + IF (all_s == 0) + { + BREAK; + } + + IF (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + IF (elp[1] == 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 1; move16(); + } + BREAK; + } + + ret = (Word8) add(t, 1); + BREAK; + } + default: assert(0 && "calculating elp of this degree not implemented"); + } + + Dyn_Mem_Deluxe_Out(); + return ret; +} + +FEC_STATIC Word16 rs16_factorize_elp(UWord8 *err_pos, UWord8 *elp, Word16 deg_elp, Word16 max_pos) +{ + Dyn_Mem_Deluxe_In( + UWord8 beta, gamma; + Word16 zeros, err_pos0, err_pos1, err_pos2, ret; + ); + + beta = 0; move16(); + gamma = 0; move16(); + zeros = 0; move16(); + ret = 0; move16(); + + SWITCH (deg_elp) + { + case 0: BREAK; + + case 1: + err_pos0 = gf16_log_g[elp[1]]; move16(); + IF (sub(err_pos0, max_pos) > 0) + { + ret = 1; move16(); + BREAK; + } + + err_pos[0] = (UWord8)err_pos0; move16(); + BREAK; + + case 2: + zeros = rs16_elp_deg2_table[s_or(elp[1], shl(elp[2], 4))]; move16(); + IF (zeros == 0) + { + Dyn_Mem_Deluxe_Out(); + return 1; + } + + err_pos0 = s_and(zeros, 15); + err_pos1 = s_and(shr(zeros, 4), 15); + + IF (sub(err_pos0, max_pos) > 0 || sub(err_pos1, max_pos) > 0) + { + ret = 1; move16(); + BREAK; + } + + err_pos[0] = (UWord8)err_pos0; move16(); + err_pos[1] = (UWord8)err_pos1; move16(); + BREAK; + + case 3: + /* beta = a*a + b, gamma = a*b + c */ + beta = GF16_ADD(GF16_MUL(elp[1], elp[1]), elp[2]); + gamma = GF16_ADD(GF16_MUL(elp[1], elp[2]), elp[3]); + zeros = rs16_elp_deg3_table[beta | gamma << 4]; + + IF (zeros == 0) + /* elp does not split over GF(16) or has multiple zeros */ + { + ret = 1; move16(); + BREAK; + } + + /* remove shift from zeros */ + err_pos0 = GF16_ADD(s_and(zeros, 15), elp[1]); + err_pos1 = GF16_ADD(s_and(shr(zeros, 4), 15), elp[1]); + err_pos2 = GF16_ADD(s_and(shr(zeros, 8), 15), elp[1]); + + IF (err_pos0 == 0 || err_pos1 == 0 || err_pos2 == 0) + { + test(); test(); + Dyn_Mem_Deluxe_Out(); + return 1; + } + + err_pos0 = gf16_log_g[err_pos0]; + err_pos1 = gf16_log_g[err_pos1]; + err_pos2 = gf16_log_g[err_pos2]; + + IF (sub(err_pos0, max_pos) > 0 || sub(err_pos1, max_pos) > 0 || sub(err_pos2, max_pos) > 0) + { + test(); test(); + ret = 1; move16(); + BREAK; + } + + err_pos[0] = (UWord8)err_pos0; move16(); + err_pos[1] = (UWord8)err_pos1; move16(); + err_pos[2] = (UWord8)err_pos2; move16(); + + BREAK; + + default: assert(0 && "invalid degree in rs16_error_locator"); + } + + Dyn_Mem_Deluxe_Out(); + return ret; +} + +FEC_STATIC void rs16_calculate_errors(UWord8 *err_symb, UWord8 *err_pos, UWord8 *syndromes, Word8 deg_elp, Word8 t) +{ + Dyn_Mem_Deluxe_In( + UWord8 det_inv; + UWord8 x0, x1, x2; + UWord8 x0sq, x1sq, x2sq; + UWord8 c0, c1, c2; + UWord8 s0, s1, s2; + UWord8 tmp; + ); + + assert(deg_elp <= t); + UNUSED(t); + + SWITCH (deg_elp) + { + case 0: BREAK; + + case 1: + err_symb[0] = GF16_MUL(gf16_g_pow[15 - err_pos[0]], syndromes[0]); move16(); + + BREAK; + + case 2: + s0 = (UWord8)shl(syndromes[0], 4); + s1 = (UWord8)shl(syndromes[1], 4); + + x0 = gf16_g_pow[err_pos[0]]; move16(); + x1 = gf16_g_pow[err_pos[1]]; move16(); + + x0sq = GF16_MUL(x0, x0); + x1sq = GF16_MUL(x1, x1); + + tmp = GF16_ADD(GF16_MUL(x0sq, x1), GF16_MUL(x1sq, x0)); + det_inv = (UWord8)shl(gf16_inv_table[tmp], 4); + + tmp = GF16_ADD(GF16_MUL0(x1sq, s0), GF16_MUL0(x1, s1)); + err_symb[0] = GF16_MUL0(tmp, det_inv); move16(); + + tmp = GF16_ADD(GF16_MUL0(x0sq, s0), GF16_MUL0(x0, s1)); + err_symb[1] = GF16_MUL0(tmp, det_inv); move16(); + + BREAK; + + case 3: + s0 = (UWord8)shl(syndromes[0], 4); + s1 = (UWord8)shl(syndromes[1], 4); + s2 = (UWord8)shl(syndromes[2], 4); + + x0 = gf16_g_pow[err_pos[0]]; move16(); + x1 = gf16_g_pow[err_pos[1]]; move16(); + x2 = gf16_g_pow[err_pos[2]]; move16(); + + x0sq = GF16_MUL(x0, x0); + x1sq = GF16_MUL(x1, x1); + x2sq = GF16_MUL(x2, x2); + + tmp = GF16_MUL(GF16_ADD(x1, x0), GF16_ADD(x2, x0)); + tmp = GF16_MUL(GF16_ADD(x2, x1), tmp); + det_inv = (UWord8)shl(gf16_inv_table[tmp], 4); + + c0 = GF16_ADD(GF16_MUL(x1, x2sq), GF16_MUL(x2, x1sq)); + c1 = GF16_ADD(x2sq, x1sq); + c2 = GF16_ADD(x2, x1); + + err_symb[0] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16(); + + c0 = GF16_ADD(GF16_MUL(x0, x2sq), GF16_MUL(x2, x0sq)); + c1 = GF16_ADD(x2sq, x0sq); + c2 = GF16_ADD(x2, x0); + + err_symb[1] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16(); + + c0 = GF16_ADD(GF16_MUL(x0, x1sq), GF16_MUL(x1, x0sq)); + c1 = GF16_ADD(x1sq, x0sq); + c2 = GF16_ADD(x1, x0); + + err_symb[2] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16(); + + tmp = GF16_MUL0(err_symb[0], det_inv); + err_symb[0] = GF16_MUL(tmp, gf16_inv_table[x0]); move16(); + + tmp = GF16_MUL0(err_symb[1], det_inv); + err_symb[1] = GF16_MUL(tmp, gf16_inv_table[x1]); move16(); + + tmp = GF16_MUL0(err_symb[2], det_inv); + err_symb[2] = GF16_MUL(tmp, gf16_inv_table[x2]); move16(); + + BREAK; + + default: assert(0 && "method not implemented\n"); BREAK; + } + + Dyn_Mem_Deluxe_Out(); +} + +/* hash functions for data validation */ + +/* hamming distance 4 */ +static const UWord32 crc14_mask[16] = {0, 17989, 35978, 51919, 71956, 89937, 103838, 119771, + 143912, 160877, 179874, 194791, 207676, 224633, 239542, 254451}; + +/* hamming distance 4 */ +static const UWord32 crc22_mask[16] = {0, 4788009, 9576018, 14356859, 19152036, 23933837, 28713718, 33500639, + 33650273, 38304072, 43214899, 47867674, 52775621, 57427436, 62346391, 67001278}; + +FEC_STATIC Word16 crc1(UWord8 *data, Word16 data_size, Word16 epmr, UWord8 *hash, Word16 hash_size, Word16 check) +{ + Dyn_Mem_Deluxe_In( + UWord32 const *mask; + int shift, i, fail; + UWord32 rem; + ); + + fail = 0; move16(); + rem = 0; move16(); + + assert(hash_size > 0); + + SWITCH (hash_size) + { + case 2: + shift = 14; move16(); + mask = crc14_mask; move32(); + BREAK; + case 3: + shift = 22; move16(); + mask = crc22_mask; move32(); + BREAK; + default: + shift = 0; + mask = 0; + assert(0 && "crc hash size not implemented"); + } + + /* data array contains 4-bit words */ + FOR (i = data_size - 1; i >= 0; i--) + { + rem = UL_xor(UL_lshl(rem, 4), data[i]); move32(); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + } + + rem = UL_xor(UL_lshl(rem, 4), UL_lshl(epmr, 2)); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + + FOR (i = 0; i < 2 * hash_size - 1; i++) + { + rem = UL_lshl(rem, 4); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + } + + rem = UL_xor(rem, UL_lshl((UWord32)epmr, shift)); move32(); + + IF (check) + { + /* test hash value */ + FOR (i = 0; i < 2 * hash_size; i++) + { + fail = s_or(fail, UL_xor(hash[i], UL_and(UL_lshr(rem, shl(i, 2)), 15))); move32(); + } + } + ELSE + { + /* write hash value */ + for (i = 0; i < 2 * hash_size; i++) + { + hash[i] = (UWord8)UL_and(UL_lshr(rem, shl(i, 2)), 15); move32(); + } + } + + Dyn_Mem_Deluxe_Out(); + return fail; +} + +/* hamming distance = 4 */ +static const UWord32 crc16_mask[16] = {0, 107243, 190269, 214486, 289937, 380538, 428972, 469319, + 579874, 621513, 671263, 761076, 832947, 857944, 938638, 1044581}; + +FEC_STATIC Word16 crc2(UWord8 *data, Word16 data_size, UWord8 *hash, Word16 hash_size, Word16 check) +{ + Dyn_Mem_Deluxe_In( + UWord32 const *mask; + int shift, i, fail; + UWord32 rem; + ); + + fail = 0; move16(); + rem = 0; move16(); + + assert(hash_size > 0); + + SWITCH (hash_size) + { + case 2: + shift = 16; move16(); + mask = crc16_mask; move32(); + BREAK; + default: + shift = 0; + mask = 0; + assert(0 && "crc hash size not implemented"); + } + + /* data array contains 4-bit words */ + FOR (i = data_size - 1; i >= 0; i--) + { + rem = UL_xor(UL_lshl(rem, 4), data[i]); move32(); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + } + + FOR (i = 0; i < 2 * hash_size; i++) + { + rem = UL_lshl(rem, 4); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + } + + IF (check) + { + /* test hash value */ + FOR (i = 0; i < 2 * hash_size; i++) + { + fail = s_or(fail, UL_xor(hash[i], UL_and(UL_lshr(rem, shl(i, 2)), 15))); move32(); + } + } + ELSE + { + /* write hash value */ + FOR (i = 0; i < 2 * hash_size; i++) + { + hash[i] = (UWord8)UL_and(UL_lshr(rem, shl(i, 2)), 15); move32(); + } + } + + Dyn_Mem_Deluxe_Out(); + return fail; +} + +/* simple float implementation */ + +FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2) +{ + Dyn_Mem_Deluxe_In( + simple_float rop; + Word32 aux; + ); + aux = L_shr(L_mult0(op1.mantissa, op2.mantissa), 14); + rop.exponent = add(op1.exponent, op2.exponent); + IF (L_and(aux, 32768L)) + { + aux = L_shr(aux, 1); + rop.exponent = add(rop.exponent, 1); + } + rop.mantissa = extract_l(aux); + Dyn_Mem_Deluxe_Out(); + return rop; +} + +/* Auxiliary */ + +FEC_STATIC Word16 simple_float_cmp(simple_float op1, simple_float op2) +/* returns 1 if op1 > op2, 0 if op1 = op2, and -1 if op1 < op2 */ +{ + Dyn_Mem_Deluxe_In( + Word16 rval; + Word16 mdiff; + Word16 ediff; + ); + + rval = 0; move16(); + + ediff = sub(op1.exponent, op2.exponent); + mdiff = sub(op1.mantissa, op2.mantissa); + + IF (ediff == 0) + { + if (mdiff > 0) + { + rval = 1; + } + if (mdiff < 0) + { + rval = -1; + } + } + ELSE + { + if (ediff > 0) + { + rval = 1; + } + if (ediff < 0) + { + rval = -1; + } + } + + Dyn_Mem_Deluxe_Out(); + return rval; +} + + diff --git a/lib_lc3plus/al_fec_fl.c b/lib_lc3plus/al_fec_fl.c deleted file mode 100644 index 92861d65b..000000000 --- a/lib_lc3plus/al_fec_fl.c +++ /dev/null @@ -1,2330 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "stdint.h" -#include -#include -#include - -#include "functions.h" - - -/* channel coder specific constants and macros */ -#define RS16_CW_LEN_MAX 15 - -#define FEC_N_MODES 4 -#define FEC_N_SYNDROMES_MAX 6 -#define FEC_N_ERR_POS_MAX 3 -#define FEC_N_ELP_COEFF_MAX 4 -#define FEC_N_ERR_SYMB_MAX 3 -#define FEC_N_MODE_DETECTION_CW 6 - -#define SYNDROME_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_SYNDROMES_MAX) -#define ELP_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ELP_COEFF_MAX) -#define ERR_POS_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_POS_MAX) -#define ERR_SYMB_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_SYMB_MAX) -#define DEG_ELP_IDX(mode_index, cw_index) ((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) - -#define FEC_TOTAL_SYNDROME_SIZE (FEC_N_SYNDROMES_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) -#define FEC_TOTAL_ELP_SIZE (FEC_N_ELP_COEFF_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) -#define FEC_TOTAL_ERR_POS_SIZE (FEC_N_ERR_POS_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) -#define FEC_TOTAL_ERROR_SIZE (FEC_N_ERR_SYMB_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) -#define FEC_TOTAL_DEG_ELP_SIZE (FEC_N_MODES * FEC_N_MODE_DETECTION_CW) - -#define ERROR_REPORT_BEC_MASK ((0x0FFF)>>1) -#define ERROR_REPORT_EP1_OK ((0x1000)>>1) -#define ERROR_REPORT_EP2_OK ((0x2000)>>1) -#define ERROR_REPORT_EP3_OK ((0x4000)>>1) -#define ERROR_REPORT_EP4_OK ((0x8000)>>1) -#define ERROR_REPORT_ALL_OK (ERROR_REPORT_EP1_OK | ERROR_REPORT_EP2_OK | ERROR_REPORT_EP3_OK | ERROR_REPORT_EP4_OK) - -/* debugging switches */ - -/* constants concerning mode detection */ -#define EP_RISK_THRESH_NS_M 21990 -#define EP_RISK_THRESH_NS_E -23 -#define EP_RISK_THRESH_OS_M 25166 -#define EP_RISK_THRESH_OS_E -10 - -#define SIMPLE_FLOAT_1_MANTISSA 16384 - -#define FEC_STATIC static - -/* DISCLAIMER: Strict instrumentation of GF16 arithmetic would have to take into account - * the initial conversion of the arguments from LC3_UINT8 to LC3_INT16 (one move16() per argument). - * Behind this is the assumption that one would store GF16 elements in LC3_INT16 for strict BASOP - * implementation. - */ -#define GF16_MUL(a, b) gf16_mult_table[(a) | (b << 4)] -#define GF16_MUL0(a, b) gf16_mult_table[(a) | (b)] -#define GF16_ADD(a, b) ((a) ^ (b)) - -/* tables for finite field arithmetic */ -/* tables for arithmetic in GF(16) * - * generator polynomial: 19 - * unit group generator (g): 2 - */ - -static const LC3_UINT8 gf16_mult_table[256] = { - /* gf16_mult_table[a | (b << 4)] contains the product of a and b in GF(16) */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 2, 4, 6, 8, 10, 12, 14, 3, 1, 7, 5, 11, 9, 15, 13, 0, 3, 6, 5, 12, 15, 10, 9, 11, 8, - 13, 14, 7, 4, 1, 2, 0, 4, 8, 12, 3, 7, 11, 15, 6, 2, 14, 10, 5, 1, 13, 9, 0, 5, 10, 15, 7, 2, 13, - 8, 14, 11, 4, 1, 9, 12, 3, 6, 0, 6, 12, 10, 11, 13, 7, 1, 5, 3, 9, 15, 14, 8, 2, 4, 0, 7, 14, 9, - 15, 8, 1, 6, 13, 10, 3, 4, 2, 5, 12, 11, 0, 8, 3, 11, 6, 14, 5, 13, 12, 4, 15, 7, 10, 2, 9, 1, 0, - 9, 1, 8, 2, 11, 3, 10, 4, 13, 5, 12, 6, 15, 7, 14, 0, 10, 7, 13, 14, 4, 9, 3, 15, 5, 8, 2, 1, 11, - 6, 12, 0, 11, 5, 14, 10, 1, 15, 4, 7, 12, 2, 9, 13, 6, 8, 3, 0, 12, 11, 7, 5, 9, 14, 2, 10, 6, 1, - 13, 15, 3, 4, 8, 0, 13, 9, 4, 1, 12, 8, 5, 2, 15, 11, 6, 3, 14, 10, 7, 0, 14, 15, 1, 13, 3, 2, 12, - 9, 7, 6, 8, 4, 10, 11, 5, 0, 15, 13, 2, 9, 6, 4, 11, 1, 14, 12, 3, 8, 7, 5, 10, -}; - -static const LC3_UINT8 rs16_elp_deg2_table[256] = { - /* If the polynomial x^2 + ax + b has distinct non-zero roots z1 and z2 in GF(16), * - * then table entry a + 16*b contains log_g(z1) | log_g(z2) << 4, and otherwise it * - * contains 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, - 105, 195, 0, 210, 0, 225, 0, 180, 120, 0, 0, 121, 0, 16, 0, 211, 0, 0, 181, 0, 0, 106, - 196, 226, 0, 0, 0, 214, 64, 0, 199, 0, 0, 0, 0, 0, 49, 184, 0, 154, 0, 229, 0, 227, - 182, 0, 0, 32, 0, 0, 0, 197, 0, 0, 122, 0, 212, 152, 0, 203, 0, 158, 128, 0, 0, 0, - 98, 113, 218, 0, 0, 0, 53, 0, 0, 65, 0, 0, 185, 110, 215, 80, 0, 0, 200, 0, 50, 0, - 0, 0, 0, 130, 205, 115, 0, 0, 160, 190, 145, 0, 0, 0, 0, 0, 0, 100, 0, 0, 168, 198, - 0, 183, 33, 0, 0, 48, 228, 213, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 179, 0, 224, 104, - 0, 194, 149, 0, 0, 209, 0, 0, 0, 189, 99, 84, 0, 129, 0, 0, 0, 144, 0, 0, 234, 114, - 0, 0, 82, 0, 0, 0, 0, 217, 202, 0, 112, 52, 232, 0, 97, 0, 0, 0, 126, 0, 81, 201, - 0, 36, 216, 186, 0, 0, 0, 96, 0, 0, 0, 0, 0, 88, 0, 0, 0, 103, 0, 148, 178, 0, - 208, 193, 0, 58, 0, 0, 0, 0, 0, 161, 206, 0, 116, 0, 101, 0, 0, 56, 146, 176, 0, 0, - 147, 162, 222, 0, 132, 0, 0, 0, 0, 0, 177, 117, 192, 0, -}; - -static const LC3_UINT16 rs16_elp_deg3_table[256] = { - /* If the polynomial x^3 + ax + b has distinct roots z1, z2 and z3 in GF(16), * - * then table entry a + 16*b contains z1) | z2 << 4 | z3 << 8, and otherwise it * - * contains 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1889, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2977, 0, 0, 0, 0, 0, 3990, 1859, 0, - 0, 0, 0, 0, 0, 0, 3521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1874, 0, 3718, 0, 0, 0, - 0, 0, 0, 2433, 0, 0, 1619, 0, 0, 0, 0, 3495, 0, 0, 0, 0, 0, 0, 4065, 0, 0, 0, - 0, 0, 0, 3255, 0, 0, 0, 1602, 0, 3735, 0, 0, 0, 0, 3238, 801, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3510, 0, 0, 0, 0, 1345, 3975, 0, 0, 0, 0, 0, 0, 0, 0, 3778, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2947, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3476, 0, 4005, 0, 3461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3748, 0, 0, 2962, 0, 0, 0, 0, 4035, 0, 0, 4020, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3221, 0, 0, 0, 0, 0, 0, 2690, - 0, 0, 0, 3795, 0, 0, 0, 4050, 0, 0, 0, 0, 0, 3204, 3765, 0, 0, 0, 0, 0, 2707, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const LC3_UINT8 gf16_g_pow[16] = {1, 2, 4, 8, 3, 6, 12, 11, 5, 10, 7, 14, 15, 13, 9, 1}; -/* g_pow[i] contains g^i*/ - -static const LC3_UINT8 gf16_log_g[16] = {255, 0, 1, 4, 2, 8, 5, 10, 3, 14, 9, 7, 6, 13, 11, 12}; -/* log_g[n] contains contains the value i such that g^i = n for n=1, 2, ..., 15, log_g[0] is set to 255 */ - -static const LC3_UINT8 gf16_inv_table[16] = {255, 1, 9, 14, 13, 11, 7, 6, 15, 2, 12, 5, 10, 4, 3, 8}; -/* gf16_inv_table[n] contains the multiplicative inverse of n in GF(16) (1/0 is set to 255)*/ - -/* RS16 generating polynomials (from lowest to highest coefficient without leading 1)*/ - -static const LC3_UINT8 rs16_gp_d3[] = {8, 6}; -static const LC3_UINT8 rs16_gp_d5[] = {7, 8, 12, 13}; -static const LC3_UINT8 rs16_gp_d7[] = {12, 10, 12, 3, 9, 7}; - -/* FEC mode signaling polynomials */ - -#define EP_SIG_POLY_DEG 12 - -static const LC3_UINT8 sig_polys[4][15] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {7, 15, 5, 6, 14, 9, 1, 3, 12, 10, 13, 3, 2, 0, 0}, - {7, 11, 14, 1, 2, 3, 12, 11, 6, 15, 7, 6, 12, 0, 0}, - {6, 15, 12, 2, 9, 15, 2, 8, 12, 3, 10, 5, 4, 0, 0}}; - -static const LC3_UINT8 sig_poly_syndr[4][6] = { - {0, 0, 0, 0, 0, 0}, {0, 4, 5, 11, 5, 8}, {0, 5, 9, 0, 1, 7}, {0, 12, 5, 12, 9, 8}}; - -/* bit count table for error report (0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111) */ - -static const LC3_UINT8 rs16_bit_count_table[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; - -/* List of RS16 generators by Hamming distance */ - -static const LC3_UINT8 *const rs16_gp_by_hd[8] = {NULL, NULL, NULL, rs16_gp_d3, NULL, rs16_gp_d5, NULL, rs16_gp_d7}; - -/* fec config data */ - -static const LC3_UINT8 hamming_distance_by_mode0[] = {1, 3, 3, 5, 7}; -static const LC3_UINT8 hamming_distance_by_mode1[] = {1, 1, 3, 5, 7}; - -static const LC3_UINT8 crc1_bytes_by_mode0[] = {0, 3, 2, 2, 2}; -static const LC3_UINT8 crc1_bytes_by_mode1[] = {0, 3, 3, 3, 3}; -static const LC3_UINT8 crc2_bytes_by_mode[] = {0, 0, 2, 2, 2}; - -/* fec mode risk table */ -typedef struct -{ - LC3_UINT32 mantissa; - LC3_INT16 exponent; -} simple_float; - -static const simple_float risk_table_f[4][4] = {{{16384, 0}, {16384, 0}, {16384, 0}, {16384, 0}}, - {{16384, -8}, {26880, -1}, {16384, 0}, {16384, 0}}, - {{16384, -16}, {26880, -9}, {20475, -2}, {16384, 0}}, - {{16384, -24}, {26880, -17}, {20475, -10}, {19195, -4}}}; -/* bit error limits for slot size 40 */ -static LC3_INT16 const low_br_max_bit_errors_by_mode[] = {0, 0, 3, 9, 18}; - -/* -corresponding float values: - {1.f, 1.f, 1.f, 1.f}, - {0.00390625f, 0.820312f, 1.f, 1.f}, - {1.52588e-05f, 0.00320435f, 0.312424f, 1.f}, - {5.96046e-08f, 1.2517e-05f, 0.00122041f, 0.0732243f} -*/ - -/* internal encoder routines */ - -FEC_STATIC void fec_interleave_pack(LC3_UINT8 *out, LC3_UINT8 *in, LC3_INT16 n_nibbles, LC3_INT16 n_codewords); - -FEC_STATIC void rs16_enc(LC3_UINT8 *iobuf, LC3_INT16 codeword_length, LC3_INT16 hamming_distance, LC3_INT16 fec_mode, - LC3_INT16 signal_mode); - -/* internal decoder routines */ - -FEC_STATIC void fec_deinterleave_unpack(LC3_UINT8 *out, LC3_UINT8 *in, LC3_INT16 n_nibbles, LC3_INT16 n_codewords); - -FEC_STATIC LC3_INT16 fec_data_preproc(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_UINT8 *cw_buf, LC3_INT16 data_bytes, - LC3_INT16 slot_bytes, LC3_INT16 pc_split); - -FEC_STATIC void fec_data_postproc(LC3_INT16 mode, LC3PLUS_EpModeRequest *epmr, LC3_UINT8 *iobuf, LC3_INT16 data_bytes, LC3_UINT8 *cw_buf, - LC3_INT16 slot_bytes, LC3_INT16 pc_split, LC3_INT32 *bfi); - -FEC_STATIC LC3_INT32 rs16_detect_and_correct(LC3_UINT8 *iobuf, LC3_INT32 n_symb, LC3_INT32 n_codewords, LC3PLUS_EpModeRequest *epmr, LC3_INT16 *error_report, - LC3_INT32 *bfi, LC3_UINT8 *array_of_trust, LC3_INT32 ccc_flag_flag, LC3_INT16 *n_pccw); - -FEC_STATIC void rs16_calculate_six_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg); - -FEC_STATIC void rs16_calculate_four_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg); - -FEC_STATIC void rs16_calculate_two_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg); - -FEC_STATIC LC3_INT8 rs16_calculate_elp(LC3_UINT8 *elp, LC3_UINT8 *syndromes, LC3_INT16 hamming_distance); - -FEC_STATIC LC3_INT16 rs16_factorize_elp(LC3_UINT8 *error_locations, LC3_UINT8 *elp, LC3_INT16 deg_elp, LC3_INT16 max_pos); - -FEC_STATIC void rs16_calculate_errors(LC3_UINT8 *errors, LC3_UINT8 *err_pos, LC3_UINT8 *syndromes, LC3_INT8 deg_elp, LC3_INT8 t); - -/* auxiliary routines */ - -FEC_STATIC LC3_INT16 crc1(LC3_UINT8 *data, LC3_INT16 data_size, LC3_INT16 epmr, LC3_UINT8 *hash_val, LC3_INT16 hash_size, LC3_INT16 check); - -FEC_STATIC LC3PLUS_EpModeRequest fec_estimate_epmr_from_cw0(LC3_UINT8 *cw0, LC3_INT8 *t, LC3_UINT8 *syndromes, LC3_UINT8 *elp, LC3_INT8 *deg_elp, - LC3_UINT8 *err_pos, LC3_UINT8 *err_symb, LC3_INT16 n_codewords, LC3_INT16 n_symb); - -FEC_STATIC void dw0_bitswap(LC3_UINT8 *dw0, LC3_INT16 mode, LC3_INT16 slot_bytes); - -FEC_STATIC LC3PLUS_EpModeRequest cw0_get_epmr(LC3_UINT8 *cw0, LC3_INT16 epmr_position); - -FEC_STATIC LC3PLUS_EpModeRequest dw0_get_epmr(LC3_UINT8 *dw0, LC3_INT16 mode, LC3_INT16 slot_size); - -FEC_STATIC LC3_INT16 crc2(LC3_UINT8 *data, LC3_INT16 data_size, LC3_UINT8 *hash_val, LC3_INT16 hash_size, LC3_INT16 check); - -FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2); - -FEC_STATIC LC3_INT16 simple_float_cmp(simple_float op1, simple_float op2); - -FEC_STATIC LC3_INT16 get_total_crc_size(LC3_INT16 slot_bytes, LC3_INT16 fec_mode, LC3_INT16 pc_split); - -FEC_STATIC LC3_INT16 get_n_codewords(LC3_INT16 slot_bytes); - -FEC_STATIC LC3_INT16 get_codeword_length(LC3_INT16 n_codewords, LC3_INT16 slot_nibbles, LC3_INT16 codeword_index); - - - -LC3_INT16 fec_get_n_pccw(LC3_INT16 slot_bytes, LC3_INT16 fec_mode, LC3_INT16 ccc_flag) -{ - LC3_INT16 n_pccw; - - if (fec_mode == 3) - { - n_pccw = (LC3_INT16) (0.080447761194030 * slot_bytes - 1.791044776119394 + 0.5); - } - else if (fec_mode == 4) - { - n_pccw = (LC3_INT16) (0.066492537313433 * slot_bytes - 1.970149253731338 + 0.5); - } - else - { - n_pccw = 0; - } - - if (ccc_flag == 1 || slot_bytes < 80) - { - n_pccw = 0; - } - - return n_pccw; -} - -FEC_STATIC LC3_INT16 get_total_crc_size(LC3_INT16 slot_bytes, LC3_INT16 fec_mode, LC3_INT16 pc_split) -{ - LC3_INT16 n_crc; - - n_crc = crc1_bytes_by_mode1[fec_mode]; - if (slot_bytes == 40) - { - n_crc = crc1_bytes_by_mode0[fec_mode]; - } - - if (pc_split > 0) - { - n_crc = n_crc + crc2_bytes_by_mode[fec_mode]; - } - - - - return n_crc; -} - -FEC_STATIC LC3_INT16 get_n_codewords(LC3_INT16 slot_bytes) -{ - return (2*slot_bytes + 14)/15; -} - -FEC_STATIC LC3_INT16 get_codeword_length(LC3_INT16 n_codewords, LC3_INT16 slot_nibbles, LC3_INT16 codeword_index) -{ - return (slot_nibbles - codeword_index - 1) / n_codewords + 1; -} - -/* Encoder */ - -LC3_INT16 fec_get_data_size(LC3_INT16 fec_mode, LC3_INT16 ccc_flag, LC3_INT16 slot_bytes) -/* not time critical */ -{ - LC3_INT16 n_codewords, payload_size; - - n_codewords = get_n_codewords(slot_bytes); - - assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); - payload_size = slot_bytes; - - if (fec_mode > 0) - { - if (fec_mode == 1) - { - payload_size --; - } - else - { - payload_size -= (fec_mode - 1) * n_codewords; - } - if (slot_bytes == 40) - { - payload_size -= crc1_bytes_by_mode0[fec_mode]; - } - else - { - payload_size -= crc1_bytes_by_mode1[fec_mode]; - } - - if (ccc_flag == 0 && fec_mode > 2 && slot_bytes >= 80) - { - payload_size -= crc2_bytes_by_mode[fec_mode]; - } - } - - - - return payload_size; -} - -LC3_INT16 fec_get_n_pc(LC3_INT16 fec_mode, LC3_INT16 n_pccw, LC3_INT16 slot_bytes) -/* not time critical */ -{ - LC3_INT16 n_codewords, pc_split; - LC3_INT32 i; - - n_codewords = get_n_codewords(slot_bytes); - - assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); - - pc_split = - 2*n_pccw*(fec_mode - 1); - - if (fec_mode == 1 || slot_bytes < 80) - { - pc_split = 0; - } - else - { - for (i = 0; i < n_pccw; i++) - { - pc_split += (2 * slot_bytes + i) / n_codewords; - } - } - - - - return pc_split; -} - -/* functions for EPMR handling */ -FEC_STATIC void dw0_bitswap(LC3_UINT8 *dw0, LC3_INT16 mode, LC3_INT16 slot_bytes) -/* swap epmr bits with bits that will be positioned at 30 and 32 in code word 0 */ -{ - LC3_UINT8 tmp; - LC3_INT32 ind0, ind1, position; - - position = get_codeword_length(get_n_codewords(slot_bytes), 2*slot_bytes, 0) - 1; - - if (slot_bytes == 40) - { - ind0 = 2*crc1_bytes_by_mode0[mode] - 1; - } - else - { - ind0 = 2*crc1_bytes_by_mode1[mode] - 1; - } - - ind1 = position - hamming_distance_by_mode0[mode] + 1; - - /* swap bits 2 and 3 of dw0[ind0] with bits 0 and 1 of dw0[ind1] */ - tmp = (dw0[ind0] >> 2) & 3; - dw0[ind0] = dw0[ind0] & 3; - dw0[ind0] = dw0[ind0] | ((dw0[ind1] & 3) << 2); - dw0[ind1] = dw0[ind1] & 12; - dw0[ind1] = dw0[ind1] | tmp; - - -} - -FEC_STATIC LC3PLUS_EpModeRequest cw0_get_epmr(LC3_UINT8 *cw0, LC3_INT16 position) -{ - return (LC3PLUS_EpModeRequest)(cw0[position] & 3); -} - -FEC_STATIC LC3PLUS_EpModeRequest dw0_get_epmr(LC3_UINT8 *dw0, LC3_INT16 mode, LC3_INT16 slot_size) -{ - LC3_INT32 ncrc1; - LC3PLUS_EpModeRequest epmr; - - ncrc1 = crc1_bytes_by_mode1[mode]; - - if (slot_size == 40) - { - ncrc1 = crc1_bytes_by_mode0[mode]; - } - - epmr = (LC3PLUS_EpModeRequest)(dw0[2 * ncrc1 - 1] >> 2); - - - - return epmr; -} - - -FEC_STATIC LC3_INT16 fec_data_preproc(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_UINT8 *cw_buf, LC3_INT16 data_bytes, - LC3_INT16 slot_bytes, LC3_INT16 pc_split) -{ - LC3_INT16 data_offset, n_crc1, n_crc2; - LC3_INT32 i, j; - - data_offset = 2*(slot_bytes - data_bytes); - - /* extract and reverse data*/ - j = 2*slot_bytes - 1; - for (i = 0; i < data_bytes; i++) - { - cw_buf[j--] = iobuf[i] & 15; - cw_buf[j--] = iobuf[i] >> 4; - } - - /* add crc hashes */ - if (slot_bytes == 40) - { - n_crc1 = crc1_bytes_by_mode0[mode]; - } - else - { - n_crc1 = crc1_bytes_by_mode1[mode]; - } - - if (pc_split > 0 && mode > 1) - { - n_crc2 = crc2_bytes_by_mode[mode]; - } - else - { - n_crc2 = 0; - } - - if (n_crc2) - { - crc2(cw_buf + data_offset + 2 * data_bytes - pc_split, pc_split, cw_buf + data_offset - 2 * n_crc2, n_crc2, 0); - } - if (n_crc1) - { - crc1(cw_buf + data_offset, 2 * data_bytes - pc_split, epmr, cw_buf + data_offset - 2 * (n_crc1 + n_crc2), n_crc1, - 0); - } - - data_offset -= 2* (n_crc1 + n_crc2); - - dw0_bitswap(cw_buf + data_offset, mode, slot_bytes); - - - - return data_offset; -} - -void fec_encoder(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_INT16 data_bytes, LC3_INT16 slot_bytes, LC3_INT16 n_pccw) -{ - LC3_INT16 n_codewords, codeword_length, hd, redundancy_nibbles, cw_offset, dw_offset, pc_split; - LC3_INT32 i, j; - LC3_UINT8 cw_buf[2 * FEC_SLOT_BYTES_MAX]; - - cw_offset = 0; - dw_offset = 0; - pc_split = 0; - - n_codewords = get_n_codewords(slot_bytes); - - /* some sanity checks */ - { - LC3_INT32 tmp = slot_bytes; - - assert((slot_bytes >= FEC_SLOT_BYTES_MIN && slot_bytes <= FEC_SLOT_BYTES_MAX) && - "fec_encoder: slot_bytes out of range"); - tmp -= mode == 1 ? 1 : n_codewords * (mode - 1); // reed solomon redundancy - tmp -= slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode]; // crc1 - tmp -= (n_pccw > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0; // crc2 - assert(data_bytes == tmp && "fec_encoder: inconsistent payload size"); - assert(n_codewords - n_pccw >= 6); - } - - /* data preproc: re-ordering and hash extension */ - pc_split = fec_get_n_pc(mode, n_pccw, slot_bytes); - - dw_offset = fec_data_preproc(mode, epmr, iobuf, cw_buf, data_bytes, slot_bytes, pc_split); - - /* encoding of first data word*/ - hd = hamming_distance_by_mode0[mode]; - redundancy_nibbles = hd - 1; - codeword_length = get_codeword_length(n_codewords, 2 * slot_bytes, 0); - - assert(codeword_length == (2 * slot_bytes - 1) / n_codewords + 1); - - for (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++)) - { - cw_buf[j] = cw_buf[dw_offset]; - } - - rs16_enc(cw_buf, codeword_length, hd, mode, 1); - - cw_offset += codeword_length; - - /* encoding of remaining data words */ - hd = hamming_distance_by_mode1[mode]; - redundancy_nibbles = hd - 1; - - for (i = 1; i < n_codewords; i++) - { - codeword_length = get_codeword_length(n_codewords, 2*slot_bytes, i); - - for (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++)) - { - cw_buf[cw_offset + j] = cw_buf[dw_offset]; - } - - rs16_enc(cw_buf + cw_offset, codeword_length, hd, mode, i < 6); - - cw_offset += codeword_length; - } - - assert(cw_offset == 2 * slot_bytes && dw_offset == 2 * slot_bytes); - - fec_interleave_pack(iobuf, cw_buf, 2 * slot_bytes, n_codewords); - - -} - -FEC_STATIC void rs16_enc(LC3_UINT8 *iobuf, LC3_INT16 codeword_length, LC3_INT16 hamming_distance, LC3_INT16 fec_mode, - LC3_INT16 signal_mode) -/* expects (data polynomial) * x^(hamming_distance - 1) in iobuf */ -{ - LC3_UINT8 const *gp; - LC3_UINT8 shift_buffer[RS16_CW_LEN_MAX + 1], lc; - LC3_INT32 i, j, deg_gp; - - memset(shift_buffer, 0, sizeof(shift_buffer)); - gp = rs16_gp_by_hd[hamming_distance]; - deg_gp = hamming_distance - 1; - - if (hamming_distance > 1) - { - assert(codeword_length > deg_gp); - - /* initialize redundancy part to zero */ - memset(iobuf, 0, deg_gp); - - /* initialize shift_buffer */ - memmove(shift_buffer + 1, iobuf + codeword_length - deg_gp, deg_gp); - - /* calculate remainder */ - for (i = codeword_length - deg_gp - 1; i >= 0; i--) - { - shift_buffer[0] = iobuf[i]; - lc = shift_buffer[deg_gp] << 4; - - for (j = deg_gp - 1; j >= 0; j--) - { - shift_buffer[j + 1] = GF16_ADD(shift_buffer[j], GF16_MUL0(gp[j], lc)); - } - } - - /* add remainder to shifted data polynomial */ - for (i = 0; i < deg_gp; i++) - { - iobuf[i] = shift_buffer[i + 1]; - } - - /* add signaling polynomial */ - if (signal_mode) - { - assert(codeword_length > EP_SIG_POLY_DEG); - for (i = 0; i <= EP_SIG_POLY_DEG; i++) - { - iobuf[i] = GF16_ADD(iobuf[i], sig_polys[fec_mode - 1][i]); - } - } - } - - -} - -FEC_STATIC void fec_interleave_pack(LC3_UINT8 *out, LC3_UINT8 *in, LC3_INT16 n_nibbles, LC3_INT16 n_codewords) -{ - LC3_INT16 out_offset, cw_offset, codeword_length; - LC3_INT32 i, j; - - out_offset = 0; - cw_offset = 0; - - /* initialize output buffer to zero */ - memset(out, 0, n_nibbles >> 1); - - /* interleave and pack codewords */ - for (i = 0; i < n_codewords; i++) - { - codeword_length = get_codeword_length(n_codewords, n_nibbles, i); - - for (j = 0; j < codeword_length; j++) - { - out_offset = n_nibbles - 1 - j*n_codewords - i; - out[out_offset >> 1] |= in[cw_offset] << ((out_offset & 1) << 2); - cw_offset = cw_offset + 1; - } - } - - - assert(cw_offset == n_nibbles); -} - -/* Decoder */ -FEC_STATIC void fec_data_postproc(LC3_INT16 mode, LC3PLUS_EpModeRequest *epmr, LC3_UINT8 *obuf, LC3_INT16 data_bytes, LC3_UINT8 *cw_buf, - LC3_INT16 slot_bytes, LC3_INT16 pc_split, LC3_INT32 *bfi) -{ - LC3_INT16 i; - LC3_INT16 n_crc1, n_crc2; - LC3_INT16 cw_buf_len; - LC3PLUS_EpModeRequest tmp_epmr; - - n_crc1 = crc1_bytes_by_mode1[mode]; - if (slot_bytes == 40) - { - n_crc1 = crc1_bytes_by_mode0[mode]; - } - - n_crc2 = 0; - if (pc_split > 0) - { - n_crc2 = crc2_bytes_by_mode[mode]; - } - - assert(n_crc1 == (slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode])); - assert(n_crc2 == ((pc_split > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0)); - - cw_buf_len = 2 * (data_bytes + n_crc1 + n_crc2); - - if ((mode - 1)) - { - /* reverse bit-swap */ - dw0_bitswap(cw_buf, mode, slot_bytes); - tmp_epmr = dw0_get_epmr(cw_buf, mode, slot_bytes); - - if (crc1(cw_buf + ((n_crc1 + n_crc2) << 1), ((data_bytes << 1) - pc_split), tmp_epmr, cw_buf, n_crc1, 1)) - { - *bfi = 1; - - return; - } - else - { - *epmr = tmp_epmr; - } - } - - if (pc_split > 0 && *bfi != 2) - { - if (crc2(cw_buf + (((data_bytes + (n_crc1 + n_crc2)) << 1) - pc_split), pc_split, - cw_buf + (n_crc1 << 1), n_crc2, 1)) - { - *bfi = 2; - } - } - - for (i = 0; i < data_bytes; i++) - { - obuf[i] = (LC3_UINT8)(cw_buf[cw_buf_len - 2 * i - 1] | (cw_buf[cw_buf_len - 2 * i - 2] << 4)); - } - - -} - -LC3_INT32 fec_decoder(LC3_UINT8 *iobuf, LC3_INT16 slot_bytes, LC3_INT32 *data_bytes, LC3PLUS_EpModeRequest *epmr, LC3_INT16 ccc_flag, LC3_INT16 *n_pccw, - LC3_INT32 *bfi, LC3_INT16 *be_bp_left, LC3_INT16 *be_bp_right, LC3_INT16 *n_pc, LC3_INT16 *m_fec) -{ - LC3_UINT8 cw_buf[2 * FEC_SLOT_BYTES_MAX]; - LC3_UINT8 array_of_trust[MAX_LEN]; - LC3_INT16 i, j; - LC3_INT16 cw_offset, dw_offset; - LC3_INT16 n_codewords, redundancy_nibbles, codeword_length; - LC3_INT16 mode, error_report; - LC3_INT16 n_crc; - LC3_INT16 first_bad_cw; - LC3_INT16 pc_split; - - UNUSED(n_crc); - - - if (*bfi == 1) - { - - return ERROR_REPORT_BEC_MASK; - } - - if (slot_bytes < FEC_SLOT_BYTES_MIN || slot_bytes > FEC_SLOT_BYTES_MAX) - { - *bfi = 1; - - return ERROR_REPORT_BEC_MASK; - } - - if (ccc_flag == 0) - { - *be_bp_left = -1; - *be_bp_right = -1; - } - - n_codewords = get_n_codewords(slot_bytes); - - /* extract and de-interleave nibbles */ - fec_deinterleave_unpack(cw_buf, iobuf, 2 * slot_bytes, n_codewords); - - /* mode detection and error correction */ - mode = rs16_detect_and_correct(cw_buf, 2 * slot_bytes, n_codewords, epmr, &error_report, bfi, array_of_trust, - ccc_flag, n_pccw); - - /* for normal slots the maximal number of bit errors is limited */ -#ifndef APPLY_MAX_ERRORS - if (slot_bytes == 40 && mode > 0) - { - if ((error_report & ERROR_REPORT_BEC_MASK) > low_br_max_bit_errors_by_mode[mode]) - { - error_report &= ERROR_REPORT_BEC_MASK; - mode = -1; - *bfi = 1; - } - else - { - if ((error_report & ERROR_REPORT_BEC_MASK) > low_br_max_bit_errors_by_mode[2]) - { - error_report &= ~ERROR_REPORT_EP2_OK; - } - if ((error_report & ERROR_REPORT_BEC_MASK) > low_br_max_bit_errors_by_mode[3]) - { - error_report &= ~ERROR_REPORT_EP3_OK; - } - } - } -#endif - - if (*bfi == 1) - { - *data_bytes = 0; - - - return error_report; - } - - /* initialization for decoding */ - *data_bytes = fec_get_data_size(mode, ccc_flag, slot_bytes); - pc_split = fec_get_n_pc(mode, *n_pccw, slot_bytes); - n_crc = get_total_crc_size(slot_bytes, mode, pc_split); - - /* decoding of first code word */ - redundancy_nibbles = hamming_distance_by_mode0[mode] - 1; - codeword_length = get_codeword_length(n_codewords, slot_bytes + slot_bytes, 0); - - dw_offset = 0; - cw_offset = 0; - - for (j = redundancy_nibbles; j < codeword_length; j++) - { - cw_buf[dw_offset++] = cw_buf[j]; - } - cw_offset = cw_offset + codeword_length; - - /* decoding of remaining code words */ - redundancy_nibbles = hamming_distance_by_mode1[mode] - 1; - - for (i = 1; i < n_codewords; i++) - { - codeword_length = get_codeword_length(n_codewords, slot_bytes + slot_bytes, i); - - for (j = redundancy_nibbles; j < codeword_length; j++) - { - cw_buf[dw_offset++] = cw_buf[j + cw_offset]; - } - - cw_offset = cw_offset + codeword_length; - } - - /* data postproc: hash validation and re-ordering */ - - fec_data_postproc(mode, epmr, iobuf, *data_bytes, cw_buf, slot_bytes, pc_split, bfi); - - if (*bfi == 1) - { - *data_bytes = 0; - - error_report &= ERROR_REPORT_BEC_MASK; - - - return error_report; - } - - if (*bfi == 2) - { - first_bad_cw = 0; - array_of_trust[*n_pccw] = 0; - while (array_of_trust[first_bad_cw] != 0) - { - first_bad_cw = first_bad_cw + 1; - } - if (first_bad_cw == *n_pccw) - { - /* this is the case when CRC failed */ - *be_bp_left = 0; - } - else - { - *be_bp_left = 4*fec_get_n_pc(mode, first_bad_cw, slot_bytes); - } - - for (i = *n_pccw - 1; i >= 0; i--) - { - if (!array_of_trust[i]) - { - break; - } - } - if (i < 0) - { - i = *n_pccw - 1; - } - *be_bp_right = 4*fec_get_n_pc(mode, i + 1, slot_bytes) - 1; - } - - if (ccc_flag == 0) - { - *n_pc = pc_split; - *m_fec = mode; - } - - - return error_report; -} - -FEC_STATIC void fec_deinterleave_unpack(LC3_UINT8 *out, LC3_UINT8 *in, LC3_INT16 n_nibbles, LC3_INT16 n_codewords) -{ - LC3_INT16 in_offset, out_offset, codeword_length; - LC3_INT32 i, j; - - in_offset = 0; - out_offset = 0; - - /* unpack nibbles in input buffer and deinterleave codewords */ - for (i = 0; i < n_codewords; i++) - { - codeword_length = get_codeword_length(n_codewords, n_nibbles, i); - for (j = 0; j < codeword_length; (j++, out_offset++)) - { - in_offset = n_nibbles - 1 - j*n_codewords - i; - out[out_offset] = (in[in_offset >> 1] >> ((in_offset & 1) << 2)) & 15; - } - } - - - assert(out_offset == n_nibbles); - -} - -FEC_STATIC LC3PLUS_EpModeRequest fec_estimate_epmr_from_cw0(LC3_UINT8 *cw0, LC3_INT8 *t, LC3_UINT8 *syndromes, LC3_UINT8 *elp, LC3_INT8 *deg_elp, - LC3_UINT8 *err_pos, LC3_UINT8 *err_symb, LC3_INT16 n_codewords, LC3_INT16 n_symb) -{ - LC3_INT32 epmr_lowest_risk_exp; - LC3_INT32 start, inc, i, n_candidates; - LC3_INT32 first_codeword_length; - LC3_INT32 mode_counter; - LC3PLUS_EpModeRequest epmr; - - epmr_lowest_risk_exp = 0; - first_codeword_length = get_codeword_length(n_codewords, n_symb, 0); - start = 2; - inc = 1; - n_candidates = 0; - - /* test if first code word decodes in mode 0 or 1 without error correction */ - if ((syndromes[SYNDROME_IDX(0, 0)] | syndromes[SYNDROME_IDX(0, 0) + 1]) == 0 || - (syndromes[SYNDROME_IDX(1, 0)] | syndromes[SYNDROME_IDX(1, 0) + 1]) == 0) - { - epmr_lowest_risk_exp = risk_table_f[1][0].exponent; - } - /* test if first code word decodes in mode 2 or 3 with lower risk */ - if (deg_elp[DEG_ELP_IDX(2, 0)] <= t[2]) - { - if (risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]].exponent <= -8) - { - n_candidates++; - start = 2; - } - } - - if (deg_elp[DEG_ELP_IDX(3, 0)] <= t[3]) - { - if (risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]].exponent <= -8) - { - n_candidates++; - start = 3; - } - } - - if (n_candidates > 1) - { - /* decide on order if mode 2 and 3 are considered */ - if (simple_float_cmp(risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]], risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]]) < - 0) - { - start = 2; - inc = 1; - } - else - { - start = 3; - inc = -1; - } - } - - for (mode_counter = start, i = 0; i < n_candidates; mode_counter += inc, i++) - { - if (risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent < epmr_lowest_risk_exp) - { - if (!rs16_factorize_elp(err_pos + ERR_POS_IDX(mode_counter, 0), elp + ELP_IDX(mode_counter, 0), - deg_elp[DEG_ELP_IDX(mode_counter, 0)], first_codeword_length - 1)) - { - /* code word is decodable with error correction */ - epmr_lowest_risk_exp = risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent; - - rs16_calculate_errors(err_symb + ERR_SYMB_IDX(mode_counter, 0), err_pos + ERR_POS_IDX(mode_counter, 0), - syndromes + SYNDROME_IDX(mode_counter, 0), deg_elp[DEG_ELP_IDX(mode_counter, 0)], - t[mode_counter]); - - for (i = 0; i < deg_elp[DEG_ELP_IDX(mode_counter, 0)]; i++) - { - cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]] = GF16_ADD( - cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]], err_symb[ERR_SYMB_IDX(mode_counter, 0) + i]); - } - break; - } - } - } - - epmr = cw0_get_epmr(cw0, first_codeword_length - 1); - - if (epmr_lowest_risk_exp > -16) - { - epmr += 4; - } - if (epmr_lowest_risk_exp > -8) - { - epmr += 4; - } - - - return epmr; -} - -FEC_STATIC LC3_INT32 rs16_detect_and_correct(LC3_UINT8 *iobuf, LC3_INT32 n_symb, LC3_INT32 n_codewords, LC3PLUS_EpModeRequest *epmr, LC3_INT16 *error_report, - LC3_INT32 *bfi, LC3_UINT8 *array_of_trust, LC3_INT32 ccc_flag, LC3_INT16 *n_pccw) -{ - - LC3_INT16 mode_broken[4]; - LC3_INT16 error_report_ep_ok[4]; - LC3_INT16 i, cw_counter, mode_counter, cw_offset; - LC3_INT16 codeword_length; - LC3_INT16 mode; - LC3_INT16 mode_candidates[4]; - LC3_INT16 n_mode_candidates; - LC3_INT16 broken_cw, n_broken_cw; - LC3_INT16 j, idx_min; - LC3_INT16 n_pccw0; - simple_float val_min_f; - LC3_INT16 tmp; - LC3_INT16 epmr_position; - simple_float dec_risk_f[FEC_N_MODES]; - simple_float risk_min_f; - simple_float ep_risk_thresh; - LC3_INT32 epmr_dec_fail_increment; - LC3_UINT8 const *hamming_distance; - LC3_UINT8 syndromes[FEC_TOTAL_SYNDROME_SIZE]; - LC3_UINT8 elp[FEC_TOTAL_ELP_SIZE]; - LC3_UINT8 err_pos[FEC_TOTAL_ERR_POS_SIZE]; - LC3_UINT8 err_symb[FEC_TOTAL_ERROR_SIZE]; - LC3_INT8 t[FEC_N_MODES]; - LC3_INT8 deg_elp[FEC_TOTAL_DEG_ELP_SIZE]; - LC3_UINT8 blacklist[FEC_N_MODES]; - LC3_INT32 rop; - - void (*syndr_calc[3])(LC3_UINT8 *, LC3_UINT8 *, LC3_INT32); - rop = 0; - - /* initialization */ - blacklist[0] = 0; - blacklist[1] = 0; - blacklist[2] = 0; - blacklist[3] = 0; - mode_broken[0] = 0; - mode_broken[1] = 0; - mode_broken[2] = 0; - mode_broken[3] = 0; - error_report_ep_ok[0] = ERROR_REPORT_EP1_OK; - error_report_ep_ok[1] = ERROR_REPORT_EP2_OK; - error_report_ep_ok[2] = ERROR_REPORT_EP3_OK; - error_report_ep_ok[3] = ERROR_REPORT_EP4_OK; - hamming_distance = &hamming_distance_by_mode0[1]; - mode = -1; - n_mode_candidates = 0; - risk_min_f.mantissa = SIMPLE_FLOAT_1_MANTISSA; - risk_min_f.exponent = 0; - - if (n_symb <= 80) - { - ep_risk_thresh.mantissa = EP_RISK_THRESH_NS_M; - ep_risk_thresh.exponent = EP_RISK_THRESH_NS_E; - } - else - { - ep_risk_thresh.mantissa = EP_RISK_THRESH_OS_M; - ep_risk_thresh.exponent = EP_RISK_THRESH_OS_E; - } - - syndr_calc[0] = &rs16_calculate_two_syndromes; - syndr_calc[1] = &rs16_calculate_four_syndromes; - syndr_calc[2] = &rs16_calculate_six_syndromes; - - for (i = 0; i < FEC_N_MODES; i++) - { - t[i] = (hamming_distance[i] -1)/2; - } - - *error_report = 0; - *bfi = 0; - - /* mode detection (stage 1) */ - codeword_length = get_codeword_length(n_codewords, n_symb, 0); - - epmr_position = codeword_length - 1; - - rs16_calculate_two_syndromes(syndromes + SYNDROME_IDX(0, 0), iobuf, codeword_length - 1); - - if ((syndromes[0 + SYNDROME_IDX(0, 0)] | syndromes[1 + SYNDROME_IDX(0, 0)]) == 0) - { - - /* data validation for fec mode 1 */ - *epmr = cw0_get_epmr(iobuf, epmr_position); - - dw0_bitswap(iobuf + 2, 1, n_symb / 2); - - if (!crc1(iobuf + 8, n_symb - 8, *epmr, iobuf + 2, 3, 1)) - { - *error_report |= ERROR_REPORT_ALL_OK; - mode = 0; - - - rop = mode + 1; - goto CLEANUP; - } - else - { - /* reverse bit swap */ - dw0_bitswap(iobuf + 2, 1, n_symb / 2); - - *epmr += 4; - } - } - - blacklist[0] = 1; - - /* mode detection (stage 2) */ - - /* calculate syndromes of code words 0 to 5 and modes 1 to 3 */ - cw_offset = 0; - - for (cw_counter = 0; cw_counter < 6; cw_counter++) - { - codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); - - rs16_calculate_six_syndromes(syndromes + SYNDROME_IDX(1, cw_counter), iobuf + cw_offset, - codeword_length - 1); - - cw_offset += codeword_length; - - for (mode_counter = FEC_N_MODES - 1; mode_counter >= 1; mode_counter--) - { - for (i = 0; i < hamming_distance[mode_counter] - 1; i++) - { - syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i] = GF16_ADD( - syndromes[SYNDROME_IDX(1, cw_counter) + i], sig_poly_syndr[mode_counter][i]); - } - } - } - - /* check for valid code words */ - for (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) - { - n_broken_cw = 0; - for (cw_counter = 0; cw_counter < 6; cw_counter++) - { - broken_cw = 0; - for (i = 0; i < hamming_distance[mode_counter] - 1; i++) - { - broken_cw |= syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i]; - } - if (broken_cw != 0) - { - n_broken_cw ++; - } - } - - if (n_broken_cw == 0) - { - mode = mode_counter; - cw_offset = 0; - - *epmr = cw0_get_epmr(iobuf, epmr_position); - - for (cw_counter = 0; cw_counter < 6; cw_counter++) - { - codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); - for (i = 0; i <= EP_SIG_POLY_DEG; i++) - { - iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]); - } - cw_offset += codeword_length; - } - } - } - - if (mode < 0) /* mode hasn't been detected so far -> errors occurred in transmission */ - { - /* calculate error locator polynomials for code words 0 to 5 */ - for (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) - { - for (cw_counter = 0; cw_counter < 6; cw_counter++) - { - deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)] = rs16_calculate_elp( - elp + ELP_IDX(mode_counter, cw_counter), syndromes + SYNDROME_IDX(mode_counter, cw_counter), - t[mode_counter]); - if (deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)] > t[mode_counter]) - { - blacklist[mode_counter] = 1; - break; - } - } - } - - /* risk analysis for mode candidate selection */ - for (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) - { - dec_risk_f[mode_counter].mantissa = SIMPLE_FLOAT_1_MANTISSA; - dec_risk_f[mode_counter].exponent = 0; - - if (blacklist[mode_counter] == 0) - { - for (cw_counter = 0; cw_counter < 6; cw_counter++) - { - dec_risk_f[mode_counter] = simple_float_mul( - dec_risk_f[mode_counter], - risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)]]); - } - - if (simple_float_cmp(dec_risk_f[mode_counter], ep_risk_thresh) <= 0) - { - mode_candidates[n_mode_candidates++] = mode_counter; - } - - if (simple_float_cmp(dec_risk_f[mode_counter], risk_min_f) < 0) - { - risk_min_f = dec_risk_f[mode_counter]; - } - } - } - assert(n_mode_candidates <= 4); // suppress false gcc warning when OPTIM=3 - - /* sort mode candidates by risk */ - for (i = 0; i < n_mode_candidates; i++) - { - idx_min = i; - val_min_f = dec_risk_f[mode_candidates[i]]; - - for (j = i + 1; j < n_mode_candidates; j++) - { - if (simple_float_cmp(dec_risk_f[mode_candidates[j]], val_min_f) < 0) - { - val_min_f = dec_risk_f[mode_candidates[j]]; - idx_min = j; - } - } - - if (idx_min > i) - { - tmp = mode_candidates[i]; - mode_candidates[i] = mode_candidates[idx_min]; - mode_candidates[idx_min] = tmp; - } - } - - /* try out candidate modes */ - for (i = 0; i < n_mode_candidates; i++) - { - mode = mode_candidates[i]; - - for (cw_counter = 0; cw_counter < 6; cw_counter++) - { - codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); - - if (deg_elp[DEG_ELP_IDX(mode, cw_counter)]) - { - if (rs16_factorize_elp(err_pos + ERR_POS_IDX(mode, cw_counter), elp + ELP_IDX(mode, cw_counter), - deg_elp[DEG_ELP_IDX(mode, cw_counter)], codeword_length - 1)) - { - /* elp did not split into distinct linear factors or error position was out of range */ - mode = -1; - break; - } - } - } - if (mode > 0) - { - /* decodable mode with lowest risk has been found */ - break; - } - } - - if (mode < 0) - { - /* no decodable mode has been found */ - *error_report = ERROR_REPORT_BEC_MASK; - *bfi = 1; - mode = -1; - - *epmr = fec_estimate_epmr_from_cw0(iobuf, t, syndromes, elp, deg_elp, err_pos, err_symb, n_codewords, - n_symb); - - - rop = mode; - goto CLEANUP; - } - - /* perform error correction */ - cw_offset = 0; - *error_report = 0; - for (cw_counter = 0; cw_counter < 6; cw_counter++) - { - codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); - - if (deg_elp[DEG_ELP_IDX(mode, cw_counter)]) - { - rs16_calculate_errors( - err_symb + ERR_SYMB_IDX(mode, cw_counter), err_pos + ERR_POS_IDX(mode, cw_counter), - syndromes + SYNDROME_IDX(mode, cw_counter), deg_elp[DEG_ELP_IDX(mode, cw_counter)], t[mode]); - - /* correct errors and sum up number of corrected bits */ - for (i = 0; i < deg_elp[DEG_ELP_IDX(mode, cw_counter)]; i++) - { - iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset] = - GF16_ADD(iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset], - err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]); - *error_report += rs16_bit_count_table[err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]]; - } - - for (i = 0; i < mode; i ++) - { - if(deg_elp[DEG_ELP_IDX(mode, cw_counter)] > i) - { - mode_broken[i] = 1; - } - } - - } - - for (i = 0; i <= EP_SIG_POLY_DEG; i++) - { - iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]); - } - cw_offset += codeword_length; - } - - /* set epmr according to risk value of cw0 */ - epmr_dec_fail_increment = 8; - - if (risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent <= -8) - { - epmr_dec_fail_increment -= 4; - } - if (risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent <= -16) - { - epmr_dec_fail_increment -= 4; - } - - *epmr = (LC3PLUS_EpModeRequest)(cw0_get_epmr(iobuf, epmr_position) + epmr_dec_fail_increment); - } - - /* mode has been successfully detected -> now check and try to correct remaining code words*/ - *n_pccw = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag); - if (ccc_flag == 0) - { - n_pccw0 = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag); - *n_pccw = n_pccw0; - } - else - { - n_pccw0 = 0; - } - - for (cw_counter = 6; cw_counter < n_codewords; cw_counter++) - { - /* usual error correction scheme: syndromes -> elp's, errors, etc. */ - codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); - array_of_trust[n_codewords - 1 - cw_counter] = 1; - - syndr_calc[t[mode] - 1](syndromes, iobuf + cw_offset, codeword_length -1); - - deg_elp[0] = rs16_calculate_elp(elp, syndromes, t[mode]); - - for (i = 0; i < mode; i ++) - { - if (deg_elp[0] > i) - { - mode_broken[i] = 1; - } - } - - if (deg_elp[0] > t[mode]) - { - for (i = 0; i < 4; i ++) - { - mode_broken[i] = 1; - } - cw_offset += codeword_length; - if (cw_counter < n_codewords - n_pccw0) - { - *error_report = ERROR_REPORT_BEC_MASK; - mode = -1; - *bfi = 1; - break; - } - else - { - *bfi = 2; - array_of_trust[n_codewords - 1 - cw_counter] = 0; - continue; - } - } - - if (deg_elp[0]) - { - if (rs16_factorize_elp(err_pos, elp, deg_elp[0], codeword_length - 1)) - { - cw_offset += codeword_length; - for (i = 0; i < 4; i ++) - { - mode_broken[i] = 1; - } - if (cw_counter < n_codewords - n_pccw0) - { - *error_report = ERROR_REPORT_BEC_MASK; - mode = -1; - *bfi = 1; - - break; - } - else - { - *bfi = 2; - array_of_trust[n_codewords - 1 - cw_counter] = 0; - continue; - } - } - - rs16_calculate_errors(err_symb, err_pos, syndromes, deg_elp[0], t[mode]); - - /* correct errors and sum up number of corrected bits */ - for (i = 0; i < deg_elp[0]; i++) - { - iobuf[err_pos[i] + cw_offset] = GF16_ADD(iobuf[err_pos[i] + cw_offset], err_symb[i]); - *error_report += rs16_bit_count_table[err_symb[i]]; - } - } - cw_offset += codeword_length; - if (risk_table_f[mode][deg_elp[0]].exponent > -16) - { - array_of_trust[n_codewords - 1 - cw_counter] = 0; - } - } - - *error_report &= ERROR_REPORT_BEC_MASK; - for (i = 0; i < 4; i ++) - { - if (!mode_broken[i]) - { - *error_report |= error_report_ep_ok[i]; - } - } - - if (mode >= 0) - { - rop = mode + 1; - } else { - rop = -1; - } - - - -CLEANUP: - return rop; -} - -FEC_STATIC void rs16_calculate_six_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg) -{ - LC3_INT32 i; - LC3_UINT8 buffer[15]; - - assert(cw_poly_deg >= 12); - - for (i = 0; i <= cw_poly_deg; i++) - { - buffer[i] = cw[i]; - } - - syndromes[0] = buffer[0]; - syndromes[1] = buffer[0]; - syndromes[2] = buffer[0]; - syndromes[3] = buffer[0]; - syndromes[4] = buffer[0]; - syndromes[5] = buffer[0]; - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[1], 96)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[1], 192)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[2], 112)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[2], 240)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[3], 16)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[3], 128)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[4], 96)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[4], 160)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[5], 112)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[5], 16)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[6], 16)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[6], 192)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[7], 96)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[7], 240)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[8], 112)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[8], 128)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[9], 16)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[9], 160)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[10], 96)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[10], 16)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[11], 112)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[11], 192)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[12], 16)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[12], 240)); - - if (cw_poly_deg >= 13) - { - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[13], 96)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[13], 128)); - } - - if (cw_poly_deg >= 14) - { - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); - syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[14], 112)); - syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[14], 160)); - } - - -} - -FEC_STATIC void rs16_calculate_four_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg) -{ - LC3_INT32 i; - LC3_UINT8 buffer[15]; - - assert(cw_poly_deg >= 12); - - for (i = 0; i <= cw_poly_deg; i++) - { - buffer[i] = cw[i]; - } - - syndromes[0] = buffer[0]; - syndromes[1] = buffer[0]; - syndromes[2] = buffer[0]; - syndromes[3] = buffer[0]; - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); - - if (cw_poly_deg >= 13) - { - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); - } - - if (cw_poly_deg >= 14) - { - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); - syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); - syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); - } - - -} - -FEC_STATIC void rs16_calculate_two_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg) -{ - LC3_INT32 i; - LC3_UINT8 buffer[15]; - - assert(cw_poly_deg >= 12); - - for (i = 0; i <= cw_poly_deg; i++) - { - buffer[i] = cw[i]; - } - - syndromes[0] = buffer[0]; - syndromes[1] = buffer[0]; - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); - - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); - - if (cw_poly_deg >= 13) - { - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); - } - - if (cw_poly_deg >= 14) - { - syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); - syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); - } - - -} - -FEC_STATIC LC3_INT8 rs16_calculate_elp(LC3_UINT8 *elp, LC3_UINT8 *syndromes, LC3_INT16 t) -/* calculates error locator polynomial vie Petterson's algorithm */ -{ - LC3_INT8 ret; - LC3_UINT8 det, det_inv, aux, all_s, *s; - LC3_UINT8 s22, s33, s44, s13, s14, s15; - LC3_UINT8 s23, s24, s25, s34, s35; - LC3_UINT8 a, b, c, d, e, f; - - ret = 0; - all_s = 0; - s = syndromes; - elp[0] = 1; - memset(elp + 1, 0, 3); - - switch (t) - { - case 3: - { - /* check for errors */ - all_s = s[0] | s[1] | s[2] | s[3] | s[4] | s[5]; - - if (all_s == 0) - { - break; - } - - /* assume 3 errors */ - s22 = GF16_MUL(s[1], s[1]); - s33 = GF16_MUL(s[2], s[2]); - s44 = GF16_MUL(s[3], s[3]); - s13 = GF16_MUL(s[0], s[2]); - - det = GF16_ADD(GF16_ADD(GF16_MUL(s13, s[4]), GF16_MUL(s44, s[0])), - GF16_ADD(GF16_MUL(s22, s[4]), GF16_MUL(s33, s[2]))); - - if (det) - { - det_inv = gf16_inv_table[det] << 4; - - s14 = GF16_MUL(s[0], s[3]); - s15 = GF16_MUL(s[0], s[4]); - - s23 = GF16_MUL(s[1], s[2]); - s24 = GF16_MUL(s[1], s[3]); - s25 = GF16_MUL(s[1], s[4]); - - s34 = GF16_MUL(s[2], s[3]); - s35 = GF16_MUL(s[2], s[4]); - - a = GF16_ADD(s35, s44) << 4; - b = GF16_ADD(s15, s33) << 4; - c = GF16_ADD(s13, s22) << 4; - d = GF16_ADD(s34, s25) << 4; - e = GF16_ADD(s23, s14) << 4; - f = GF16_ADD(s24, s33) << 4; - - aux = GF16_ADD(GF16_ADD(GF16_MUL0(a, s[3]), GF16_MUL0(d, s[4])), GF16_MUL0(f, s[5])); - elp[3] = GF16_MUL0(aux, det_inv); - - aux = GF16_ADD(GF16_ADD(GF16_MUL0(d, s[3]), GF16_MUL0(b, s[4])), GF16_MUL0(e, s[5])); - elp[2] = GF16_MUL0(aux, det_inv); - - aux = GF16_ADD(GF16_ADD(GF16_MUL0(f, s[3]), GF16_MUL0(e, s[4])), GF16_MUL0(c, s[5])); - elp[1] = GF16_MUL0(aux, det_inv); - - if (elp[3] == 0) - { - ret = t+1; - } - else - { - ret = 3; - } - break; - } - - /* assume two errors */ - det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1])); - - if (det) - { - det_inv = gf16_inv_table[det] << 4; - - aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3])); - elp[1] = GF16_MUL0(aux, det_inv); - - aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3])); - elp[2] = GF16_MUL0(aux, det_inv); - - /* check remaining LSF relations */ - aux = GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[2]), GF16_MUL(elp[1], s[3])), s[4]) - | GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[3]), GF16_MUL(elp[1], s[4])), s[5]); - - aux |= elp[2] == 0; - - if (aux != 0) - { - ret = t + 1; - } - else - { - ret = 2; - } - break; - } - - /* assume one error */ - if (syndromes[0] != 0) - { - elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); - - /* check remaining LSF relations */ - aux = GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]) - | GF16_ADD(GF16_MUL(elp[1], s[2]), s[3]) - | GF16_ADD(GF16_MUL(elp[1], s[3]), s[4]) - | GF16_ADD(GF16_MUL(elp[1], s[4]), s[5]); - - aux |= elp[1] == 0; - - if (aux != 0) - { - ret = t + 1; - } - else - { - ret = 1; - } - break; - } - - ret = t + 1; - break; - } - case 2: - { - all_s = s[0] | s[1] | s[2] | s[3]; - - if (all_s == 0) - { - break; - } - - /* assume two errors */ - det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1])); - - if (det) - { - det_inv = gf16_inv_table[det] << 4; - - aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3])); - elp[1] = GF16_MUL0(aux, det_inv); - - aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3])); - elp[2] = GF16_MUL0(aux, det_inv); - - if (elp[2] == 0) - { - ret = t + 1; - } - else - { - ret = 2; - } - break; - } - - /* assume one error */ - if (syndromes[0] != 0) - { - elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); - - /* check remaining LSF relation */ - aux = GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]) | GF16_ADD(GF16_MUL(elp[1], s[2]), s[3]); - aux |= elp[1] == 0; - - if (aux != 0) - { - ret = t + 1; - } - else - { - ret = 1; - } - break; - } - - ret = t + 1; - break; - } - case 1: - { - all_s = s[0] | s[1]; - - if (all_s == 0) - { - break; - } - - if (syndromes[0] != 0) - { - elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); - if (elp[1] == 0) - { - ret = t + 1; - } - else - { - ret = 1; - } - break; - } - - ret = t + 1; - break; - } - default: assert(0 && "calculating elp of this degree not implemented"); - } - - - return ret; -} - -FEC_STATIC LC3_INT16 rs16_factorize_elp(LC3_UINT8 *err_pos, LC3_UINT8 *elp, LC3_INT16 deg_elp, LC3_INT16 max_pos) -{ - LC3_UINT8 beta, gamma; - LC3_INT16 zeros, err_pos0, err_pos1, err_pos2, ret; - - beta = 0; - gamma = 0; - zeros = 0; - ret = 0; - - switch (deg_elp) - { - case 0: break; - - case 1: - err_pos0 = gf16_log_g[elp[1]]; - if (err_pos0 > max_pos) - { - ret = 1; - break; - } - - err_pos[0] = (LC3_UINT8)err_pos0; - break; - - case 2: - zeros = rs16_elp_deg2_table[elp[1] | (elp[2] << 4)]; - if (zeros == 0) - { - - return 1; - } - - err_pos0 = zeros & 15; - err_pos1 = (zeros >> 4) & 15; - - if (err_pos0 > max_pos || err_pos1 > max_pos) - { - ret = 1; - break; - } - - err_pos[0] = (LC3_UINT8)err_pos0; - err_pos[1] = (LC3_UINT8)err_pos1; - break; - - case 3: - /* beta = a*a + b, gamma = a*b + c */ - beta = GF16_ADD(GF16_MUL(elp[1], elp[1]), elp[2]); - gamma = GF16_ADD(GF16_MUL(elp[1], elp[2]), elp[3]); - zeros = rs16_elp_deg3_table[beta | gamma << 4]; - - if (zeros == 0) - /* elp does not split over GF(16) or has multiple zeros */ - { - ret = 1; - break; - } - - /* remove shift from zeros */ - err_pos0 = GF16_ADD(zeros & 15, elp[1]); - err_pos1 = GF16_ADD((zeros >> 4) & 15, elp[1]); - err_pos2 = GF16_ADD((zeros >> 8) & 15, elp[1]); - - if (err_pos0 == 0 || err_pos1 == 0 || err_pos2 == 0) - { - - return 1; - } - - err_pos0 = gf16_log_g[err_pos0]; - err_pos1 = gf16_log_g[err_pos1]; - err_pos2 = gf16_log_g[err_pos2]; - - if (err_pos0 > max_pos || err_pos1 > max_pos || err_pos2 > max_pos) - { - ret = 1; - break; - } - - err_pos[0] = (LC3_UINT8)err_pos0; - err_pos[1] = (LC3_UINT8)err_pos1; - err_pos[2] = (LC3_UINT8)err_pos2; - - break; - - default: assert(0 && "invalid degree in rs16_error_locator"); - } - - - return ret; -} - -FEC_STATIC void rs16_calculate_errors(LC3_UINT8 *err_symb, LC3_UINT8 *err_pos, LC3_UINT8 *syndromes, LC3_INT8 deg_elp, LC3_INT8 t) -{ - LC3_UINT8 det_inv; - LC3_UINT8 x0, x1, x2; - LC3_UINT8 x0sq, x1sq, x2sq; - LC3_UINT8 c0, c1, c2; - LC3_UINT8 s0, s1, s2; - LC3_UINT8 tmp; - - UNUSED(t); - - assert(deg_elp <= t); - - switch (deg_elp) - { - case 0: break; - - case 1: - err_symb[0] = GF16_MUL(gf16_g_pow[15 - err_pos[0]], syndromes[0]); - - break; - - case 2: - s0 = (LC3_UINT8) (syndromes[0] << 4); - s1 = (LC3_UINT8) (syndromes[1] << 4); - - x0 = gf16_g_pow[err_pos[0]]; - x1 = gf16_g_pow[err_pos[1]]; - - x0sq = GF16_MUL(x0, x0); - x1sq = GF16_MUL(x1, x1); - - tmp = GF16_ADD(GF16_MUL(x0sq, x1), GF16_MUL(x1sq, x0)); - det_inv = gf16_inv_table[tmp] << 4; - - tmp = GF16_ADD(GF16_MUL0(x1sq, s0), GF16_MUL0(x1, s1)); - err_symb[0] = GF16_MUL0(tmp, det_inv); - - tmp = GF16_ADD(GF16_MUL0(x0sq, s0), GF16_MUL0(x0, s1)); - err_symb[1] = GF16_MUL0(tmp, det_inv); - - break; - - case 3: - s0 = syndromes[0] << 4; - s1 = syndromes[1] << 4; - s2 = syndromes[2] << 4; - - x0 = gf16_g_pow[err_pos[0]]; - x1 = gf16_g_pow[err_pos[1]]; - x2 = gf16_g_pow[err_pos[2]]; - - x0sq = GF16_MUL(x0, x0); - x1sq = GF16_MUL(x1, x1); - x2sq = GF16_MUL(x2, x2); - - tmp = GF16_MUL(GF16_ADD(x1, x0), GF16_ADD(x2, x0)); - tmp = GF16_MUL(GF16_ADD(x2, x1), tmp); - det_inv = gf16_inv_table[tmp] << 4; - - c0 = GF16_ADD(GF16_MUL(x1, x2sq), GF16_MUL(x2, x1sq)); - c1 = GF16_ADD(x2sq, x1sq); - c2 = GF16_ADD(x2, x1); - - err_symb[0] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); - - c0 = GF16_ADD(GF16_MUL(x0, x2sq), GF16_MUL(x2, x0sq)); - c1 = GF16_ADD(x2sq, x0sq); - c2 = GF16_ADD(x2, x0); - - err_symb[1] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); - - c0 = GF16_ADD(GF16_MUL(x0, x1sq), GF16_MUL(x1, x0sq)); - c1 = GF16_ADD(x1sq, x0sq); - c2 = GF16_ADD(x1, x0); - - err_symb[2] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); - - tmp = GF16_MUL0(err_symb[0], det_inv); - err_symb[0] = GF16_MUL(tmp, gf16_inv_table[x0]); - - tmp = GF16_MUL0(err_symb[1], det_inv); - err_symb[1] = GF16_MUL(tmp, gf16_inv_table[x1]); - - tmp = GF16_MUL0(err_symb[2], det_inv); - err_symb[2] = GF16_MUL(tmp, gf16_inv_table[x2]); - - break; - - default: assert(0 && "method not implemented\n"); break; - } - - -} - -/* hash functions for data validation */ - -/* hamming distance 4 */ -static const LC3_UINT32 crc14_mask[16] = {0, 17989, 35978, 51919, 71956, 89937, 103838, 119771, - 143912, 160877, 179874, 194791, 207676, 224633, 239542, 254451}; - -/* hamming distance 4 */ -static const LC3_UINT32 crc22_mask[16] = {0, 4788009, 9576018, 14356859, 19152036, 23933837, 28713718, 33500639, - 33650273, 38304072, 43214899, 47867674, 52775621, 57427436, 62346391, 67001278}; - -FEC_STATIC LC3_INT16 crc1(LC3_UINT8 *data, LC3_INT16 data_size, LC3_INT16 epmr, LC3_UINT8 *hash_val, LC3_INT16 hash_size, LC3_INT16 check) -{ - LC3_UINT32 const *mask; - LC3_INT32 shift, i, fail; - LC3_UINT32 rem; - - fail = 0; - rem = 0; - - assert(hash_size > 0); - - switch (hash_size) - { - case 2: - shift = 14; - mask = crc14_mask; - break; - case 3: - shift = 22; - mask = crc22_mask; - break; - default: - shift = 0; - mask = 0; - assert(0 && "crc hash size not implemented"); - } - - /* data array contains 4-bit words */ - for (i = data_size - 1; i >= 0; i--) - { - rem = (rem << 4) ^ data[i]; - rem ^= mask[(rem >> shift) & 15]; - } - - rem = (rem << 4) ^ (epmr << 2); - rem ^= mask[(rem >> shift) & 15]; - - for (i = 0; i < 2 * hash_size - 1; i++) - { - rem <<= 4; - rem ^= mask[(rem >> shift) & 15]; - } - - rem ^= ((LC3_UINT32) epmr) << shift; - - if (check) - { - /* test hash value */ - for (i = 0; i < 2 * hash_size; i++) - { - fail |= hash_val[i] ^ ((rem >> (4*i)) & 15); - } - } - else - { - /* write hash value */ - for (i = 0; i < 2 * hash_size; i++) - { - hash_val[i] = (LC3_UINT8) ((rem >> (4*i)) & 15); - } - } - - - return fail; -} - -/* hamming distance = 4 */ -static const LC3_UINT32 crc16_mask[16] = {0, 107243, 190269, 214486, 289937, 380538, 428972, 469319, - 579874, 621513, 671263, 761076, 832947, 857944, 938638, 1044581}; - -FEC_STATIC LC3_INT16 crc2(LC3_UINT8 *data, LC3_INT16 data_size, LC3_UINT8 *hash_val, LC3_INT16 hash_size, LC3_INT16 check) -{ - LC3_UINT32 const *mask; - LC3_INT32 shift, i, fail; - LC3_UINT32 rem; - - fail = 0; - rem = 0; - - assert(hash_size > 0); - - switch (hash_size) - { - case 2: - shift = 16; - mask = crc16_mask; - break; - default: - shift = 0; - mask = 0; - assert(0 && "crc hash size not implemented"); - } - - /* data array contains 4-bit words */ - for (i = data_size - 1; i >= 0; i--) - { - rem = (rem << 4) ^ data[i]; - rem ^= mask[(rem >> shift) & 15]; - } - - for (i = 0; i < 2 * hash_size; i++) - { - rem <<= 4; - rem ^= mask[(rem >> shift) & 15]; - } - - if (check) - { - /* test hash value */ - for (i = 0; i < 2 * hash_size; i++) - { - fail |= hash_val[i] ^ ((rem >> (4*i)) & 15); - } - } - else - { - /* write hash value */ - for (i = 0; i < 2 * hash_size; i++) - { - hash_val[i] = (LC3_UINT8) ((rem >> (4*i)) & 15); - } - } - - - return fail; -} - -/* simple float implementation */ -FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2) -{ - simple_float rop; - LC3_INT32 aux; - - aux = (op1.mantissa * op2.mantissa) >> 14; - rop.exponent = op1.exponent + op2.exponent; - if (aux & 32768L) - { - aux >>= 1; - rop.exponent ++; - } - rop.mantissa = (LC3_INT16) aux; - - - return rop; -} - -/* Auxiliary */ - -FEC_STATIC LC3_INT16 simple_float_cmp(simple_float op1, simple_float op2) -/* returns 1 if op1 > op2, 0 if op1 = op2, and -1 if op1 < op2 */ -{ - LC3_INT16 rval; - LC3_INT16 mdiff; - LC3_INT16 ediff; - - rval = 0; - - ediff = op1.exponent - op2.exponent; - mdiff = (LC3_INT16) op1.mantissa - (LC3_INT16) op2.mantissa; - - if (ediff == 0) - { - if (mdiff > 0) - { - rval = 1; - } - if (mdiff < 0) - { - rval = -1; - } - } - else - { - if (ediff > 0) - { - rval = 1; - } - if (ediff < 0) - { - rval = -1; - } - } - - - return rval; -} - diff --git a/lib_lc3plus/apply_global_gain.c b/lib_lc3plus/apply_global_gain.c deleted file mode 100644 index 450997e20..000000000 --- a/lib_lc3plus/apply_global_gain.c +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off) -{ - LC3_FLOAT gg; - - gg = LC3_POW(10, (LC3_FLOAT)(global_gain_idx + global_gain_off) / 28); - - mult_const(x, gg, xLen); -} diff --git a/lib_lc3plus/apply_global_gain_fx.c b/lib_lc3plus/apply_global_gain_fx.c new file mode 100644 index 000000000..7c5220f10 --- /dev/null +++ b/lib_lc3plus/apply_global_gain_fx.c @@ -0,0 +1,66 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void processApplyGlobalGain_fx(Word32 x[], Word16 *x_e, Word16 xLen, Word16 global_gain_idx, Word16 global_gain_off) +{ + Counter i; +#ifdef ENABLE_HR_MODE + Word32 global_gain; +#else + Word16 global_gain; +#endif + Word16 global_gain_e; + Word32 tmp32; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processApplyGlobalGain_fx", sizeof(struct { + Counter i; + Word16 global_gain, global_gain_e; + Word32 tmp32; + })); +#endif + +#ifdef ENABLE_HR_MODE + /* 1 / (28 * log 2) is 0x797D in Q18, L_shl_pos by 7 results in Q25 tmp32 */ + /* round(2^31 / (28 * log10(2))) = 254778081 */ + //tmp32 = L_shl_pos(Mpy_32_16_lc3plus(254778081, add(global_gain_idx, global_gain_off)), 9); + Word32 mh; + UWord16 ml; + + Mpy_32_16_ss(254778081, add(global_gain_idx, global_gain_off), &mh, &ml); + tmp32 = L_shl_pos(mh, 9) | L_deposit_l((shr((Word16)ml, 7)) & 0x1ff); + move16(); + /* Uses an argument in Q25 */ + global_gain = BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000)); +#else + tmp32 = L_shl_pos(L_mult0(add(global_gain_idx, global_gain_off), 0x797D), 7); + /* Uses an argument in Q25 */ + global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000))); +#endif + global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); + + FOR (i = 0; i < xLen; i++) + { +#ifdef ENABLE_HR_MODE + x[i] = Mpy_32_32_lc3plus(x[i], global_gain); +#else + x[i] = Mpy_32_16_lc3plus(x[i], global_gain); +#endif + move32(); + } + + *x_e = add(*x_e, global_gain_e); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/ari_codec.c b/lib_lc3plus/ari_codec.c index 23a540e91..8092aa28e 100644 --- a/lib_lc3plus/ari_codec.c +++ b/lib_lc3plus/ari_codec.c @@ -1,1776 +1,2465 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" #include "functions.h" -static void ac_shift_fl(Encoder_State_fl* st); -static void ac_encode_fl(Encoder_State_fl* st, LC3_INT sym_freq, LC3_INT cum_freq); -static void ac_finalize_fl(Encoder_State_fl* st); -static void write_uint_forward_fl(Encoder_State_fl* st, LC3_INT val, LC3_INT numbits); -static void ari_enc_init(Encoder_State_fl* st, LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side); -static LC3_INT sign(LC3_INT x); -#ifdef CR9_SIMPLIFY_ARI_DECODER -static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit); -#else -static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit, LC3_INT *bp, Decoder_State_fl* st_fl, LC3_INT from_left); -#endif - -#ifdef CR9_SIMPLIFY_ARI_DECODER -static void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side); -#else -static void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side); -#endif - -#ifdef CR9_SIMPLIFY_ARI_DECODER -static LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* sym_freq, LC3_INT32 num_sym, LC3_UINT8* ptr, LC3_INT32* bp, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin); -#else -static LC3_INT ac_decode_fl(Decoder_State_fl* st, LC3_INT* sym_freq, LC3_INT* cum_freq, LC3_INT num_sym, LC3_UINT8* ptr, LC3_INT* bp, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side); -#endif - -#ifdef CR9_SIMPLIFY_ARI_DECODER -static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin); -#else -static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side); -#endif - -static void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed); -static void findNonZero(LC3_INT* in, LC3_INT len, LC3_INT* outLen); - -#ifndef CR9_SIMPLIFY_ARI_DECODER -static void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); - -static void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); - -static void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); - -void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) +typedef struct +{ + Word16 inv_bin; + Word16 numbytes; + Word16 c_bp; + Word16 c_bp_side; + Word16 bytes; + Word16 b_left; + Word16 b_right; + Word16 enc; + Word16 sim_dec; + Word16 bfi; + Word16 be_bp_left; + Word16 be_bp_right; +} Pc_State_fx; + +typedef struct +{ + UWord32 ac_low_fx; + UWord32 ac_range_fx; + Word16 ac_cache_fx; + Word16 ac_carry_fx; + Word16 ac_carry_count_fx; +} Encoder_State_fx; + +typedef struct { - LC3_INT i = 0, j = 0; + UWord32 ac_low_fx; + UWord32 ac_range_fx; + UWord32 ac_help_fx; + Word16 BER_detect; + Pc_State_fx pc; +} Decoder_State_fx; + +static void ac_dec_init_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, + Decoder_State_fx *st_fx /* i/o: Decoder State */ +); + +static __forceinline void pc_init_fx(Word16 n_pc, Word16 numbytes, Word16 be_bp_left, Word16 be_bp_right, Word16 L_spec, + Word16 enc, Word16 sim_dec, Word16 bfi, Pc_State_fx *pc /* i/o: Pc State */ +); +static __forceinline Word16 check_pc_bytes(Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin, + Word16 from_left, Pc_State_fx *pc /* i/o: Pc State */ +); + +static void ac_enc_init_fx(Encoder_State_fx *st_fx /* i/o: Encoder state */ +); + +static void ac_enc_shift_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx /* i/o: Encoder state */ +); + +static void write_indice_forward(UWord8 *ptr, Word16 bp, Word16 indice, Word16 numbits); + +static void ac_encode_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx, /* i/o: Encoder state */ + UWord32 cum_freq, /* i : Cumulative frequency up to symbol */ + UWord32 sym_freq /* i : Symbol probability */ +); + +static Word16 ac_enc_finish_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx /* i/o: Encoder state */ +); + +static Word16 ac_decode_fx( /* o : Decoded cumulative frequency */ + Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 pki); +static Word16 ac_decode_tns_order( /* o : Decoded cumulative frequency */ + Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 enable_lpc_weighting); +static Word16 ac_decode_tns_coef( /* o : Decoded cumulative frequency */ + Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 pki); +static Word16 ac_dec_update_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin, + Decoder_State_fx *st_fx, /* i/o: Decoder State */ + UWord32 cum_freq, /* i : Cumulative frequency */ + UWord32 sym_freq /* i : Symbol frequency */ +); + +/*************************************************************************/ + +# ifdef ENABLE_HR_MODE + +Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side_in, Word16 mask_side_in, Word16 nbbits, Word32 xq[], + Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz, + Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode, + Word16 enable_lpc_weighting, Word8 *scratchBuffer) +{ + Word16 resbit, i1, i2; - *numsym = 18 - 1; + Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits; + Word32 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp; + Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Counter i, n, k, lev;); - j = 0; - for (i = 1; i <= *numsym; i++) { - symfreq[j] = ari_spec_cumfreq_fl[pki][i]; - j++; - } + lsb = (Word16 *)scratchAlign(scratchBuffer, 0); /* size = 2 * lastnz */ - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_spec_cumfreq_fl[pki][i]; + /* Init */ + a1_i = 0; + move16(); + b1_i = 1; + move16(); + bp = 0; + move16(); + numResBitsEnc = 0; + move16(); + nlsbs = 0; + move16(); + ptr = bytes; + bp_side = bp_side_in; + move16(); + mask_side = mask_side_in; + move16(); + + /*Start Encoding*/ + ac_enc_init_fx(&st); + + /* TNS data */ + FOR (n = 0; n < tns_numfilters; n++) + { + IF (tns_order[n] > 0) + { + ac_encode_fx(ptr, &bp, &st, ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1], + ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]); + FOR (k = 0; k < tns_order[n]; k++) + { + ac_encode_fx(ptr, &bp, &st, ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]], + ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]); + } + } } - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_spec_cumfreq_fl[pki][i]; - } -} + IF (lsbMode == 0) + { -void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) -{ - LC3_INT i = 0, j = 0; + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) + { + IF (codingdata[1] < 0) + { + ac_encode_fx(ptr, &bp, &st, 0, + ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]); + } + ELSE IF (codingdata[1] == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + ELSE IF (sub(codingdata[1], 1) == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]); + write_bit_backward(ptr, &bp_side, &mask_side, L_and(xq[a1_i], 1)); + write_bit_backward(ptr, &bp_side, &mask_side, L_and(xq[b1_i], 1)); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + ELSE + { + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + FOR (lev = 0; lev < codingdata[1]; lev++) + { + lev1 = s_min(lev, 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(a1, lev), 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(b1, lev), 1)); + } + lev1 = s_min(codingdata[1], 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } - *numsym = 18 - 1; + a1_i += 2; + b1_i += 2; + codingdata += 3; - j = 0; - for (i = 1; i <= *numsym; i++) { - symfreq[j] = ari_tns_freq_cf[k][i]; - j++; + } /*end of the 2-tuples loop*/ } + ELSE + { + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) + { + IF (codingdata[1] < 0) + { + ac_encode_fx(ptr, &bp, &st, 0, + ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]); + } + ELSE IF (codingdata[1] == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + ELSE IF (sub(codingdata[1], 1) == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]); + a1_msb = s_and(codingdata[2], 0x3); + tmp = L_and(xq[a1_i], 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (a1_msb == 0 && tmp > 0) + { + if (xq[a1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[a1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + IF (a1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + b1_msb = shr_pos(codingdata[2], 2); + tmp = L_and(xq[b1_i], 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (b1_msb == 0 && tmp > 0) + { + if (xq[b1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[b1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + IF (b1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + ELSE + { + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + a1_msb = L_shr_pos(a1, 1); + tmp = L_and(a1, 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (a1_msb == 0 && tmp > 0) + { + if (xq[a1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[a1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + b1_msb = L_shr_pos(b1, 1); + tmp = s_and(b1, 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (b1_msb == 0 && tmp > 0) + { + if (xq[b1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[b1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC]); + FOR (lev = 1; lev < codingdata[1]; lev++) + { + lev1 = s_min(lev, 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(a1, lev), 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(b1, lev), 1)); + } + lev1 = s_min(codingdata[1], 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]); + IF (a1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (b1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_tns_freq_cf[k][i]; - } + a1_i += 2; + b1_i += 2; + codingdata += 3; - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_tns_freq_cf[k][i]; + } /*end of the 2-tuples loop*/ } -} - -void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) -{ - LC3_INT i = 0, j = 0; - *numsym = 8; + /* Side bits (in sync with the decoder) */ + nbits_side = sub(nbbits, add(shl_pos(bp_side, 3), sub(norm_s(mask_side), 6))); - j = 0; - for (i = 1; i < 9; i++) { - symfreq[j] = ari_tns_order_cf[enable_lpc_weighting][i]; - j++; + /* Residual bits (in sync with the decoder) */ + extra_bits = sub(norm_ul(st.ac_range_fx), 6); + if (st.ac_cache_fx >= 0) + { + extra_bits = add(extra_bits, 8); } - - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_tns_order_cf[enable_lpc_weighting][i]; + if (st.ac_carry_count_fx > 0) + { + extra_bits = add(extra_bits, shl_pos(st.ac_carry_count_fx, 3)); } + + n = s_max(sub(nbbits, add(shl_pos(bp, 3), add(extra_bits, nbits_side))), 0); + move16(); - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_tns_order_cf[enable_lpc_weighting][i]; + IF (lsbMode == 0) + { + numResBitsEnc = s_min(numResBits, n); + FOR (i = 0; i < numResBitsEnc; i++) + { + resbit = 0; move16(); + i1 = shr(i, RESBITS_PACK_SHIFT); + i2 = s_and(i, RESBITS_PACK_MASK); + if (s_and(resBits[i1], shl(1, i2))) + { + resbit = 1; + } + write_bit_backward(ptr, &bp_side, &mask_side, resbit); + } } -} - -#endif - -void findNonZero(LC3_INT* in, LC3_INT len, LC3_INT* outLen) -{ - LC3_INT i = 0, j = 0; - - for (i = 0; i < len; i++) { - if (in[i] != 0) { - j++; + ELSE + { + nlsbs = s_min(nlsbs, n); + FOR (k = 0; k < nlsbs; k++) + { + write_bit_backward(ptr, &bp_side, &mask_side, lsb[k]); } } - *outLen = j; -} + /* End arithmetic coder, overflow management */ + extra_bits = ac_enc_finish_fx(ptr, &bp, &st); -void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed) -{ - LC3_INT k; - - *nf_seed = 0; - - for (k = 0; k < L_spec; k++) { - *nf_seed = *nf_seed + (abs(x[k]) & 32767) * k; - } - *nf_seed = *nf_seed & 65535; + /* Fill bits (for debugging, the exact number of fill bits cannot be computed in the decoder)*/ + fill_bits = nbbits - (bp * 8 + extra_bits + nbits_side + nlsbs + numResBitsEnc); - if (*nf_seed >= 32768) { - *nf_seed = *nf_seed - 65536; - } + Dyn_Mem_Deluxe_Out(); + + return fill_bits; } -#ifdef CR9_SIMPLIFY_ARI_DECODER -static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin) +# else /* ENABLE_HR_MODE */ + +Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side_in, Word16 mask_side_in, Word16 nbbits, Word16 xq[], + Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz, + Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode, + Word16 enable_lpc_weighting, Word8 *scratchBuffer) { - LC3_INT32 bp_local, bp_side_local, offset; -#ifdef WMOPS - push_wmops("pc_check_bytes"); +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits; + Word16 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp; + Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Counter i, n, k, lev; + ); +#else + Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits; + Word16 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp; + Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Counter i, n, k, lev; + ); #endif - if (st_fl->pc_bytes > 0) - { - if (!from_left && mask_side != 1) - { - return 0; - } - if (st_fl->pc_c_bp_side > 0 && *bp_side < 0) - { - assert(mask_side == 1); - assert(st_fl->pc_b_right != -1); - *bp_side = st_fl->pc_b_right; - - return 0; - } + lsb = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN * 2 bytes */ - bp_local = *bp; - bp_side_local = *bp_side; - - if (from_left) + /* Init */ + a1_i = 0; + move16(); + b1_i = 1; + move16(); + bp = 0; + move16(); + numResBitsEnc = 0; + move16(); + nlsbs = 0; + move16(); + ptr = bytes; + bp_side = bp_side_in; + move16(); + mask_side = mask_side_in; + move16(); + + /*Start Encoding*/ + ac_enc_init_fx(&st); + + /* TNS data */ + FOR (n = 0; n < tns_numfilters; n++) + { + IF (tns_order[n] > 0) { - if (mask_side == 1) + ac_encode_fx(ptr, &bp, &st, ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1], + ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]); + FOR (k = 0; k < tns_order[n]; k++) { - bp_side_local = bp_side_local + 1; + ac_encode_fx(ptr, &bp, &st, ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]], + ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]); } - } else { - bp_local = bp_local - 1; } - - if (st_fl->pc_b_right == -1) + } + + IF (lsbMode == 0) + { + + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) { - offset = -1; - if (!st_fl->pc_enc) + IF (codingdata[1] < 0) { - offset = offset + st_fl->pc_bytes; + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][0], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]); } - - if ((bp_side_local + offset - bp_local) == st_fl->pc_bytes) + ELSE IF (codingdata[1] == 0) { - st_fl->pc_b_left = bp_local + 1; - st_fl->pc_b_right = bp_side_local - 1; - - if (st_fl->pc_enc) + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]); + IF (xq[a1_i] != 0) { - assert(st_fl->pc_b_right - st_fl->pc_b_left + 1 == st_fl->pc_bytes); - return 1; + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); } } - } - - if (!st_fl->pc_enc && st_fl->pc_b_right > -1) - { - if (from_left && *bp == st_fl->pc_b_left) - { - *bp = 0; - st_fl->pc_c_bp = 1; - } - - if (!from_left && bp_side_local == st_fl->pc_b_right) + ELSE IF (sub(codingdata[1], 1) == 0) { - *bp_side = st_fl->pc_bytes - 1; - st_fl->pc_c_bp_side = 1; + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(xq[a1_i], 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(xq[b1_i], 1)); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); + } } - - if (st_fl->pc_bfi == 2) + ELSE { - - if ((st_fl->pc_c_bp && (*bp + 1) >= st_fl->pc_be_bp_left) || (st_fl->pc_c_bp_side && (*bp_side + 1) <= st_fl->pc_be_bp_right)) + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + FOR (lev = 0; lev < codingdata[1]; lev++) { - st_fl->pc_inv_bin = cur_bin; - return 1; - } else if ((st_fl->pc_c_bp && *bp >= 0) || (st_fl->pc_c_bp_side && *bp_side <= (st_fl->pc_bytes - 1))) + lev1 = s_min(lev, 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(a1, lev), 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(b1, lev), 1)); + } + lev1 = s_min(codingdata[1], 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]); + IF (xq[a1_i] != 0) { - st_fl->pc_inv_bin = MIN(st_fl->pc_inv_bin, cur_bin); - return 0; + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); } } - } - } -#ifdef WMOPS - pop_wmops(); -#endif - return 0; -} + a1_i += 2; + b1_i += 2; + codingdata += 3; -#else - -static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side) -{ - LC3_INT32 bp_local, bp_side_local, offset; - - if (st_fl->pc_bytes > 0) + } /*end of the 2-tuples loop*/ + } + ELSE { - if (!from_left && mask_side != 1) - { - return; - } - - if (st_fl->pc_c_bp_side > 0 && *bp_side < 0) + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) { - assert(mask_side == 1); - assert(st_fl->pc_b_right != -1); - *bp_side = st_fl->pc_b_right; - return; - } - - bp_local = *bp; - bp_side_local = *bp_side; - - if (from_left) - { - if (mask_side == 1) - { - bp_side_local = bp_side_local + 1; - } - } else { - bp_local = bp_local - 1; - } - - if (st_fl->pc_b_right == -1) - { - offset = -1; - if (!st_fl->pc_enc) + IF (codingdata[1] < 0) { - offset = offset + st_fl->pc_bytes; + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][0], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]); } - - if ((bp_side_local + offset - bp_local) == st_fl->pc_bytes) + ELSE IF (codingdata[1] == 0) { - st_fl->pc_b_left = bp_local + 1; - st_fl->pc_b_right = bp_side_local - 1; - - if (st_fl->pc_enc) + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]); + IF (xq[a1_i] != 0) { - st_fl->pc_return = 1; - return; + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); } } - } - - if (!st_fl->pc_enc && st_fl->pc_b_right > -1) - { - if (from_left && *bp == st_fl->pc_b_left) - { - *bp = 0; - st_fl->pc_c_bp = 1; - } - - if (!from_left && bp_side_local == st_fl->pc_b_right) + ELSE IF (sub(codingdata[1], 1) == 0) { - *bp_side = st_fl->pc_bytes - 1; - st_fl->pc_c_bp_side = 1; + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]); + a1_msb = s_and(codingdata[2], 0x3); + tmp = s_and(xq[a1_i], 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (a1_msb == 0 && tmp > 0) + { + if (xq[a1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[a1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + IF (a1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + b1_msb = shr_pos(codingdata[2], 2); + tmp = s_and(xq[b1_i], 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (b1_msb == 0 && tmp > 0) + { + if (xq[b1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[b1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + IF (b1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); + } } - - if (st_fl->pc_bfi == 2) + ELSE { - - if ((st_fl->pc_c_bp && (*bp + 1) >= st_fl->pc_be_bp_left) || (st_fl->pc_c_bp_side && (*bp_side + 1) <= st_fl->pc_be_bp_right)) + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + a1_msb = shr_pos(a1, 1); + tmp = s_and(a1, 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (a1_msb == 0 && tmp > 0) { - st_fl->pc_bbi = 2; - } else if ((st_fl->pc_c_bp && *bp >= 0) || (st_fl->pc_c_bp_side && *bp_side <= (st_fl->pc_bytes - 1))) + if (xq[a1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[a1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + b1_msb = shr_pos(b1, 1); + tmp = s_and(b1, 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (b1_msb == 0 && tmp > 0) + { + if (xq[b1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[b1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC]); + FOR (lev = 1; lev < codingdata[1]; lev++) + { + lev1 = s_min(lev, 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(a1, lev), 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(b1, lev), 1)); + } + lev1 = s_min(codingdata[1], 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]); + IF (a1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (b1_msb != 0) { - st_fl->pc_bbi = 1; + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); } } - } - } - - return; -} -#endif + a1_i += 2; + b1_i += 2; + codingdata += 3; -#ifdef CR9_SIMPLIFY_ARI_DECODER -void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side) -{ - LC3_INT i; + } /*end of the 2-tuples loop*/ + } + + /* Side bits (in sync with the decoder) */ + nbits_side = sub(nbbits, add(shl_pos(bp_side, 3), sub(norm_s(mask_side), 6))); - if (!st_fl->pc_enc) + /* Residual bits (in sync with the decoder) */ + extra_bits = sub(norm_ul(st.ac_range_fx), 6); + if (st.ac_cache_fx >= 0) { - *bp = *bp + st_fl->pc_bytes; + extra_bits = add(extra_bits, 8); } + if (st.ac_carry_count_fx > 0) + { + extra_bits = add(extra_bits, shl_pos(st.ac_carry_count_fx, 3)); + } + + n = s_max(sub(nbbits, add(shl_pos(bp, 3), add(extra_bits, nbits_side))), 0); + move16(); - st_fl->ac_low_fl = 0; - - st_fl->ac_range_fl = (LC3_UINT32) 16777215; /* 2^24 -1 */ - for (i = 0; i < 3; i++) { - if(pc_check_bytes(bp, st_fl, from_left, mask_side, bp_side, 0) != 0) + IF (lsbMode == 0) + { + numResBitsEnc = s_min(numResBits, n); + FOR (i = 0; i < numResBitsEnc; i++) { - return; + FOR (i = 0; i < numResBitsEnc; i++) + { + write_bit_backward(ptr, &bp_side, &mask_side, resBits[i]); + } } - - st_fl->ac_low_fl = (st_fl->ac_low_fl << 8) + (LC3_UINT32)ptr[*bp]; - *bp = *bp + 1; } - - st_fl->BER_detect = 0; -} - -#else - -void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side) -{ - LC3_INT i = 0; - - if (!st_fl->pc_enc) + ELSE { - *bp = *bp + st_fl->pc_bytes; + nlsbs = s_min(nlsbs, n); + FOR (k = 0; k < nlsbs; k++) + { + write_bit_backward(ptr, &bp_side, &mask_side, lsb[k]); + } } - st_fl->ac_low_fl = 0; + /* End arithmetic coder, overflow management */ + extra_bits = ac_enc_finish_fx(ptr, &bp, &st); - st_fl->ac_range_fl = (LC3_UINT32)pow(2, 24) - (LC3_UINT32)1; - for (i = 0; i < 3; i++) { - pc_check_bytes(bp, st_fl, from_left, mask_side, bp_side); - - st_fl->ac_low_fl = (st_fl->ac_low_fl << 8) + (LC3_UINT32)ptr[*bp]; - *bp = *bp + 1; - } + /* Fill bits (for debugging, the exact number of fill bits cannot be computed in the decoder)*/ + fill_bits = nbbits - (bp * 8 + extra_bits + nbits_side + nlsbs + numResBitsEnc); - st_fl->BER_detect = 0; + Dyn_Mem_Deluxe_Out(); + return fill_bits; } -#endif - -/* Returns val */ -#ifdef CR9_SIMPLIFY_ARI_DECODER -LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* freq, LC3_INT32 num_sym, LC3_UINT8* ptr, LC3_INT32* bp, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin) +#endif /* ENABLE_HR_MODE */ + +void processAriDecoder_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec, + Word16 fs_idx, Word16 enable_lpc_weighting, Word16 tns_numfilters, Word16 lsbMode, + Word16 lastnz, Word16 *bfi, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, + Word16 frame_dms, + Word16 n_pc, Word16 be_bp_left, Word16 be_bp_right, Word16 mode, Word16 *spec_inv_idx, + Word16 *b_left, + Word16 *resBits, +# ifdef ENABLE_HR_MODE + Word32 *x, +# else + Word16 *x, +# endif + Word16 *nf_seed, UWord8 *resQdata, Word16 *tns_idx, Word16 *zero_frame, Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + , Word16 hrmode +# endif +) +{ + Decoder_State_fx st; +# ifdef ENABLE_HR_MODE + Word16 resbit, i1, i2; + Word32 a, b; +# else + Word16 a, b; +# endif + Word16 t, a1, b1, a1_i, b1_i, bp; + Word16 esc_nb; + Word16 rateFlag; + Word16 r; + Word16 nt_half; + Word16 c; + Word16 nbits_side, extra_bits, nbits_ari; + UWord8 * ptr; + Word32 tmp32; + Word16 lsb_ind_c; + Word16 * lsb_ind; + Word16 tmp; + Counter n, k, lev; + Counter i; + Word16 max_lev = 14; + +#ifdef DYNMEM_COUNT +struct _dynmem { - LC3_INT val, tmp, symfreq_loc; -#ifdef WMOPS - push_wmops("ac_decode_fl"); +Decoder_State_fx st; + Pc_State_fx pc; + Word16 resbit, i1, i2; +# ifdef ENABLE_HR_MODE + Word32 a, b; +# else + Word16 a, b; +# endif + Word16 t, a1, b1, a1_i, b1_i, bp; + Word16 esc_nb; + Word16 rateFlag; + Word16 r; + Word16 nt_half; + Word16 c; + Word16 nbits_side, extra_bits, nbits_ari; + UWord8 * ptr; + Word32 tmp32; + Word16 lsb_ind_c; + Word16 * lsb_ind; + Word16 tmp; + Counter i, n, k, lev; + }; + Dyn_Mem_In("processAriDecoder_fx", sizeof(struct _dynmem)); #endif - tmp = st->ac_range_fl >> 10; - - if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) { - st->BER_detect = 1; +# ifdef ENABLE_HR_MODE + if (hrmode == 1) + { + max_lev = max_lev + 8; } +# endif - val = num_sym - 1; + lsb_ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size 2 * MAX_LEN bytes */ - while (st->ac_low_fl < (LC3_UINT32)(tmp * freq[val])) { - val--; + /* Rate flag */ + rateFlag = 0; + move16(); +# ifdef ENABLE_HR_MODE + if (fs_idx != 5) /* Don't update rateFlag for 96000 Hz */ +# endif + { + if (sub(nbbits, add(160, DEPR_i_mult(fs_idx, 160))) > 0) + { + rateFlag = 2 << NBITS_CONTEXT; + move16(); + } } - - symfreq_loc = freq[val + 1] - freq[val]; - - st->ac_low_fl = st->ac_low_fl - tmp * freq[val]; - st->ac_range_fl = tmp * symfreq_loc; - while (st->ac_range_fl < 65536) { - st->ac_low_fl = ((LC3_INT32)st->ac_low_fl) & ((LC3_INT32)(16777215)); + pc_init_fx(n_pc, shr_pos(nbbits, 3), be_bp_left, be_bp_right, L_spec, mode==1, mode==2, *bfi, &st.pc); - if(pc_check_bytes(bp, st, from_left, mask_side, bp_side, cur_bin) != 0) - { - st->BER_detect = 1; - return 1; - } - - st->ac_low_fl = st->ac_low_fl << 8; - st->ac_low_fl = st->ac_low_fl + ptr[*bp]; - *bp = *bp + 1; - st->ac_range_fl = st->ac_range_fl << 8; + /* Init */ + nt_half = shr_pos(L_spec, 1); + c = 0; + move16(); + t = 0; + move16(); + a1_i = 0; + move16(); + b1_i = 1; + move16(); + bp = 0; + move16(); + if (mode != 1) + { + bp = add(bp, st.pc.bytes); + move16(); } - -#ifdef WMOPS - pop_wmops(); -#endif - return val; -} + *spec_inv_idx = L_spec; + move16(); + *b_left = -1; + move16(); + lsb_ind_c = 0; + move16(); -#else +ptr = bytes; -LC3_INT ac_decode_fl(Decoder_State_fl* st, LC3_INT* sym_freq, LC3_INT* cum_freq, LC3_INT num_sym, LC3_UINT8* ptr, LC3_INT* bp, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side) -{ - LC3_INT val = 0, tmp = 0; - +/* Start Decoding */ +ac_dec_init_fx(ptr, &bp, bp_side, mask_side, &st); - tmp = st->ac_range_fl >> 10; + /* Decode TNS data */ + tmp = MAXLAG; +IF (sub(frame_dms, 25) == 0) +{ +tmp = shr_pos(tmp, 1); +} +IF (sub(frame_dms, 50) == 0) +{ +tmp = shr_pos(tmp, 1); +} - if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) { - st->BER_detect = 1; + FOR (n = 0; n < tns_numfilters; n++) + { + IF (tns_order[n] > 0) + { + tns_order[n] = ac_decode_tns_order(&st, enable_lpc_weighting); + move16(); + tns_order[n] = add(tns_order[n], 1); + move16(); + IF (tns_order[n] > tmp) + { + GOTO ber_detect; + } + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, 0, &st, + ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1], + ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]) != 0) + { + GOTO ber_detect; + } + FOR (k = 0; k < tns_order[n]; k++) + { + IF (sub(*bp_side, bp) < 0) + { + GOTO ber_detect; + } + tns_idx[MAXLAG * n + k] = ac_decode_tns_coef(&st, k); + move16(); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, 0, &st, + ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]], + ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]) != 0) + { + GOTO ber_detect; + } + } + } + } + IF (st.BER_detect > 0) + { + GOTO ber_detect; } - val = num_sym - 1; +IF (lsbMode == 0) +{ - while (st->ac_low_fl < (LC3_UINT32)(tmp * cum_freq[val])) { - val--; - } +/*Main Loop through the 2-tuples*/ +FOR (k = 0; k < lastnz; k += 2) +{ - st->ac_low_fl = st->ac_low_fl - tmp * cum_freq[val]; - st->ac_range_fl = tmp * sym_freq[val]; +/* Get context */ +t = add(c, rateFlag); +if (sub(k, nt_half) > 0) +{ +t = add(t, 1 << NBITS_CONTEXT); +} - while (st->ac_range_fl < pow(2, 16)) { - st->ac_low_fl = st->ac_low_fl << 8; - st->ac_low_fl = ((LC3_INT)st->ac_low_fl) & ((LC3_INT)(pow(2, 24) - 1)); - - pc_check_bytes(bp, st, from_left, mask_side, bp_side); - - st->ac_low_fl = st->ac_low_fl + ptr[*bp]; - *bp = *bp + 1; - st->ac_range_fl = st->ac_range_fl << 8; - } + r = ac_decode_fx(&st, ari_spec_lookup[t]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, ari_spec_cumfreq[ari_spec_lookup[t]][r], + ari_spec_freq[ari_spec_lookup[t]][r]) != 0) + { + GOTO ber_detect; + } - return val; + IF (r == 0) + { + x[a1_i] = 0; + move16(); + x[b1_i] = 0; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(r, VAL_ESC) < 0) + { + a = s_and(r, 0x3); + b = shr_pos(r, 2); + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a, b), 1)); + IF (a > 0) + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + a = negate(a); + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { +if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + } + x[b1_i] = b; + move16(); + } + ELSE + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ +GOTO ber_detect; +} +a = read_bit(ptr, bp_side, mask_side); +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ +GOTO ber_detect; +} + b = read_bit(ptr, bp_side, mask_side); + r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[1]]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, + ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[1]]][r], + ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[1]]][r]) != 0) + { + GOTO ber_detect; + } + IF (sub(r, VAL_ESC) < 0) + { + a1 = s_and(r, 0x3); + b1 = shr_pos(r, 2); + a = add(shl_pos(a1, 1), a); + b = add(shl_pos(b1, 1), b); + IF (a > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { + a = negate(a); + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + } + x[b1_i] = b; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1, b1), 1), 1)); + } + ELSE + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; } +a = add(shl_pos(read_bit(ptr, bp_side, mask_side), 1), a); +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + b = add(shl_pos(read_bit(ptr, bp_side, mask_side), 1), b); + FOR (lev = 2; lev < max_lev; lev++) + { + esc_nb = s_min(lev, 3); + r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[esc_nb]]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, + ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r], + ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r]) != 0) + { + GOTO ber_detect; + } + IF (sub(r, VAL_ESC) < 0) + { + BREAK; + } + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + +# ifdef ENABLE_HR_MODE + a = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), a); +# else + a = add(shl(read_bit(ptr, bp_side, mask_side), lev), a); +# endif + + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } +# ifdef ENABLE_HR_MODE + b = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), b); +# else + b = add(shl(read_bit(ptr, bp_side, mask_side), lev), b); +# endif + } + /* check for bitflip */ + IF (sub(lev, max_lev) == 0) + { + GOTO ber_detect; + } + b1 = shr_pos(r, 2); + a1 = s_and(r, 0x3); + +# ifdef ENABLE_HR_MODE + a = L_add(L_shl(a1, lev), a); + b = L_add(L_shl(b1, lev), b); +# else + a = add(shl(a1, lev), a); + b = add(shl(b1, lev), b); +# endif + IF (a > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { +# ifdef ENABLE_HR_MODE + a = L_negate(a); +# else + a = negate(a); +# endif + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { +# ifdef ENABLE_HR_MODE + b = L_negate(b); +# else + b = negate(b); +# endif + } + } + x[b1_i] = b; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), add(esc_nb, 12)); + } + } -#endif + test(); + test(); + IF ((sub(sub(bp, *bp_side), 3) > 0 && sub(st.pc.c_bp, st.pc.c_bp_side) == 0) || st.BER_detect > 0) +{ +GOTO ber_detect; +} -#ifdef CR9_SIMPLIFY_ARI_DECODER -void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit) +a1_i += 2; +b1_i += 2; +} +} +ELSE +{ +/*Main Loop through the 2-tuples*/ +FOR (k = 0; k < lastnz; k += 2) { - if (ptr[*bp_side] & *mask_side) { - *bit = 1; - } else { - *bit = 0; - } - if (*mask_side == 128) { - *mask_side = 1; - *bp_side = *bp_side - 1; - } else { - *mask_side = *mask_side * 2; - } +/* Get context */ +t = add(c, rateFlag); +if (sub(k, nt_half) > 0) +{ +t = add(t, 1 << NBITS_CONTEXT); } -#else + r = ac_decode_fx(&st, ari_spec_lookup[t]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, ari_spec_cumfreq[ari_spec_lookup[t]][r], + ari_spec_freq[ari_spec_lookup[t]][r]) != 0) + { + GOTO ber_detect; + } -void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit, LC3_INT *bp, Decoder_State_fl* st_fl, LC3_INT from_left) + IF (r == 0) + { + x[a1_i] = 0; + move16(); + x[b1_i] = 0; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(r, VAL_ESC) < 0) + { + a = s_and(r, 0x3); + b = shr_pos(r, 2); + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a, b), 1)); + IF (a > 0) + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) { - *bit = 0; - - UNUSED(bp); - UNUSED(st_fl); - UNUSED(from_left); + GOTO ber_detect; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + a = negate(a); + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { +if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + } + x[b1_i] = b; + move16(); + } + ELSE + { + r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[1]]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, + ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[1]]][r], + ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[1]]][r]) != 0) + { + GOTO ber_detect; + } + IF (sub(r, VAL_ESC) < 0) + { + a1 = s_and(r, 0x3); + b1 = shr_pos(r, 2); + a = shl_pos(a1, 1); + b = shl_pos(b1, 1); + IF (a > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { + a = negate(a); + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + } + x[b1_i] = b; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1, b1), 1), 1)); + lsb_ind[lsb_ind_c++] = k; + move16(); + } + ELSE + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} +a = shl_pos(read_bit(ptr, bp_side, mask_side), 1); +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + b = shl_pos(read_bit(ptr, bp_side, mask_side), 1); + FOR (lev = 2; lev < max_lev; lev++) + { + esc_nb = s_min(lev, 3); + r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[esc_nb]]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, + ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r], + ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r]) != 0) + { + GOTO ber_detect; + } + IF (sub(r, VAL_ESC) < 0) + { + BREAK; + } + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } +# ifdef ENABLE_HR_MODE + a = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), a); +# else + a = add(shl(read_bit(ptr, bp_side, mask_side), lev), a); +# endif + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } +# ifdef ENABLE_HR_MODE + b = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), b); +# else + b = add(shl(read_bit(ptr, bp_side, mask_side), lev), b); +# endif + } + /* check for bitflip */ + IF (sub(lev, max_lev) == 0) + { + GOTO ber_detect; + } - if (ptr[*bp_side] & *mask_side) { - *bit = 1; - } else { - *bit = 0; - } + b1 = shr_pos(r, 2); + a1 = s_and(r, 0x3); +# ifdef ENABLE_HR_MODE + a = L_add(L_shl(a1, lev), a); + b = L_add(L_shl(b1, lev), b); +# else + a = add(shl(a1, lev), a); + b = add(shl(b1, lev), b); +# endif + IF (a > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { +# ifdef ENABLE_HR_MODE + a = L_negate(a); +# else + a = negate(a); +# endif + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { +# ifdef ENABLE_HR_MODE + b = L_negate(b); +# else + b = negate(b); +# endif + } + } + x[b1_i] = b; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), add(esc_nb, 12)); + lsb_ind[lsb_ind_c++] = k; + move16(); + } + } - if (*mask_side == 128) { - *mask_side = 1; - *bp_side = *bp_side - 1; - } else { - *mask_side = *mask_side * 2; - } + test(); + test(); + IF ((sub(sub(bp, *bp_side), 3) > 0 && sub(st.pc.c_bp, st.pc.c_bp_side) == 0) || st.BER_detect > 0) +{ +GOTO ber_detect; } -#endif +a1_i += 2; +b1_i += 2; +} +} -#ifdef CR9_SIMPLIFY_ARI_DECODER -void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting, - LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx, - LC3_INT gg_idx, uint8_t * resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes, - LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms, - LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx, - LC3_INT hrmode -) +IF (L_spec > k) { - Decoder_State_fl st; - LC3_INT a, b, t, bp; - LC3_INT c; - LC3_INT nbits_side, extra_bits; - LC3_UINT8* ptr; - LC3_INT n, k, lev; - LC3_INT max_lev, tmp; - LC3_INT bit, lev1, pki, sym, save_lev[MAX_LEN], idx_len, total_bits, nbits_ari, rateFlag; - -#ifdef WMOPS - push_wmops("processAriDecoder_fl"); -#endif +basop_memset(&x[k], 0, (L_spec - k) * sizeof(*x)); +} - total_bits = 8 * numbytes; - rateFlag = 0; - - memset(&st, 0, sizeof(st)); - - st.pc_bytes = (n_pc + 1) >> 1; - st.pc_b_left = numbytes + 1; - st.pc_b_right = -1; - st.pc_enc = enc; - st.pc_bfi = *bfi; - st.pc_be_bp_left = floor(be_bp_left / 8); - st.pc_be_bp_right = floor(be_bp_right / 8) - 1; - *spec_inv_idx = L_spec + 1; - assert(st.pc_be_bp_right < st.pc_bytes || st.pc_bytes == 0); + nbits_side = sub(nbbits, add(shl_pos(*bp_side, 3), sub(norm_s(*mask_side), 6))); + extra_bits = sub(norm_ul(st.ac_range_fx), 6); + nbits_ari = shl_pos(sub(bp, 3), 3); +IF (mode != 1) +{ +IF (st.pc.c_bp == 0) +{ +nbits_ari = shl_pos(sub(sub(bp, st.pc.bytes), 3), 3); +} +ELSE +{ +nbits_ari = shl_pos(add(bp, sub(sub(st.pc.b_left, st.pc.bytes), 3)), 3); +} - /* Rate flag */ - if (fs_idx != 5) - { - if (total_bits > (160 + fs_idx * 160)) { - rateFlag = 512; + IF (st.pc.c_bp_side != 0) + { + nbits_side = sub(add(sub(nbbits, shl_pos(st.pc.b_left, 3)), shl_pos(sub(st.pc.bytes, *bp_side), 3)), + sub(norm_s(*mask_side), 6)); } } - /* Init */ - c = 0; - t = 0; - bp = 0; - - *b_left = -1; + n = sub(nbbits, add(nbits_ari, add(extra_bits, nbits_side))); + move16(); - ptr = bytes; - - /* Start Decoding */ - ac_dec_init_fl(ptr, &bp, &st, 1, mask_side, &bp_side); - - /* Decode TNS data */ - tmp = MAXLAG; - +IF (n < 0) +{ +GOTO ber_detect; +} - if (frame_dms <= 50) + IF (lsbMode == 0) { - tmp /= 2; - } + *resBits = n; + move16(); + i=0; - /* Decode TNS data */ - for (n = 0; n < tns_numfilters; n++) { - - if (tns_order[n] > 0) { - tns_order[n] = ac_decode_fl(&st, &ari_tns_order_cf[enable_lpc_weighting][0], 8, ptr, &bp, 1, mask_side, &bp_side, 0); - - tns_order[n] = tns_order[n] + 1; - - if (tns_order[n] > tmp || st.BER_detect > 0) +#ifdef ENABLE_HR_MODE + FOR (k = 0; k < L_spec; k++) + { + IF (x[k] != 0) { - goto ber_detect; - } - - for (k = 0; k < tns_order[n]; k++) { - if (bp_side < bp) + IF (n == 0) { - *bfi = 1; - return; + BREAK; } - - tns_idx[n * 8 + k] = ac_decode_fl(&st, &ari_tns_freq_cf[k][0], 17, ptr, &bp, 1, mask_side, &bp_side, 0); - - if (st.BER_detect > 0) + if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) + { + GOTO ber_detect_res; + } + i1 = shr(i, RESBITS_PACK_SHIFT); + i2 = s_and(i, RESBITS_PACK_MASK); + resbit = read_bit(ptr, bp_side, mask_side); + if (resbit) { - goto ber_detect; + resQdata[i1] = (UWord8) s_or(resQdata[i1], shl(1, i2)); } + i = add(i, 1); + move16(); + n = sub(n, 1); } } - } - - /* Spectral data */ - for (k = 0; k < lastnz; k = k + 2) { - /* Context */ - t = c + rateFlag; - - if (k > (L_spec >> 1)) { - t = t + 256; - } - - /* Decode amplitude */ - x[k] = 0; - x[k + 1] = 0; - - if (hrmode == 1) { - max_lev = 13 + 8; - } else { - max_lev = 13; - } - - for (lev = 0; lev <= max_lev; lev++) { - lev1 = MIN(lev, 3); - pki = ari_spec_lookup_fl[t + lev1 * 1024]; - - sym = ac_decode_fl(&st, &ari_spec_cumfreq_fl[pki][0], 17, ptr, &bp, 1, mask_side, &bp_side, k); - - if (sym < 16) { - break; - } - - if (lsbMode == 0 || lev > 0) { - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) +#else + FOR (k = 0; k < L_spec; k++) + { + IF (x[k] != 0) + { + IF (n == 0) { - goto ber_detect; + BREAK; } - read_bit_fl(ptr, &mask_side, &bp_side, &bit); - x[k] = x[k] + (bit << lev); - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) + if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) { - goto ber_detect; + GOTO ber_detect_res; } - read_bit_fl(ptr, &mask_side, &bp_side, &bit); - - x[k + 1] = x[k + 1] + (bit << lev); + + *resQdata++ = (UWord8) read_bit(ptr, bp_side, mask_side); + move16(); + n = sub(n, 1); } } +#endif - if ((lev - 1) == 13 && sym == 16) +# ifdef ENABLE_HR_MODE + if (hrmode) { - goto ber_detect; - } - - if (hrmode == 0) { - lev = MIN(lev, 13); - } - - if (lsbMode == 1) { - save_lev[k] = lev; - } - - a = sym & 3; - b = sym >> 2; - - x[k] = x[k] + (a << lev); - x[k + 1] = x[k + 1] + (b << lev); - - /* Decode signs */ - if (x[k] > 0) { - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) - { - goto ber_detect; - } - read_bit_fl(ptr, &mask_side, &bp_side, &bit); - - if (bit == 1) { - x[k] = -x[k]; - } - } - - if (x[k + 1] > 0) { - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) - { - goto ber_detect; - } - read_bit_fl(ptr, &mask_side, &bp_side, &bit); - - if (bit == 1) { - x[k + 1] = -x[k + 1]; - } - } - - /* Context */ - lev1 = MIN(lev, 3); - if (lev1 <= 1) { - t = 1 + (a + b) * (lev1 + 1); - } else { - t = 12 + lev1; - } - - c = (c & 15) * 16 + t; + Word16 idx_len = sub(*resBits, n); /* Number of nonzero bits */ + Word16 idx_len_lim = idx_len * EXT_RES_ITER_MAX; - if (((bp - bp_side) > 3 && (st.pc_c_bp == st.pc_c_bp_side))) { + Word16 res_bits_hrmode = s_min(idx_len_lim, *resBits) - idx_len; + /* idx_len bits have been read in the previous loop */ - if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) + for (k = 0; k < res_bits_hrmode; k++) { - *bfi = 2; - calculate_nfseed(x, k, nf_seed); - return; + if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) + { + GOTO ber_detect_res; + } + i1 = shr(i, RESBITS_PACK_SHIFT); + i2 = s_and(i, RESBITS_PACK_MASK); + resbit = read_bit(ptr, bp_side, mask_side); + if (resbit) + { + resQdata[i1] = (UWord8) s_or(resQdata[i1], shl(1, i2)); + } + i = add(i, 1); + move16(); + n = sub(n, 1); } - - *bfi = 1; - return; } +# endif - if (st.BER_detect > 0) - { - goto ber_detect; - } + *resBits = sub(*resBits, n); } - - /* Residual bits */ - nbits_side = total_bits - (8 * bp_side + 8 - (31 - clz_func(mask_side))); - nbits_ari = (bp - 3) * 8; - extra_bits = 25 - (31 - clz_func(st.ac_range_fl)); - - if (enc == 0) + ELSE { - if (st.pc_c_bp == 0) - { - nbits_ari = (bp - st.pc_bytes - 3) * 8; - } else { - nbits_ari = (bp + st.pc_b_left - st.pc_bytes - 3) * 8; - } - - if (st.pc_c_bp_side != 0) - { - nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOGTWO(mask_side)); - } - } - - - *nbits_residual = total_bits - (nbits_side + nbits_ari + extra_bits); - - if (*nbits_residual < 0) { - if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) - { - *bfi = 2; - calculate_nfseed(x, k, nf_seed); - return; - } - - *bfi = 1; - return; - } - - if (lsbMode == 0) { - findNonZero(x, L_spec, &idx_len); - - if (hrmode) + *resBits = 0; + FOR (k = 0; k < lsb_ind_c; k++) { - idx_len *= EXT_RES_ITER_MAX; - } - *nbits_residual = MIN(*nbits_residual, idx_len); - *residualPresent = 1; - - memset(resBits, 0, MAX_RESBITS_LEN); - - for (k = 0; k < *nbits_residual; k++) { - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) + a = x[lsb_ind[k]]; + move16(); + IF (n == 0) { - goto ber_detect_res; + BREAK; } - read_bit_fl(ptr, &mask_side, &bp_side, &tmp); - - resBits[k >> 3] |= tmp << (k & 7); - } - } else { - for (k = 0; k < lastnz; k = k + 2) { - if (save_lev[k] > 0) { - if (*nbits_residual == 0) { - break; +if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) +{ +GOTO ber_detect_res; +} + tmp = read_bit(ptr, bp_side, mask_side); + n = sub(n, 1); + IF (tmp > 0) + { +# ifdef ENABLE_HR_MODE + if (a > 0) + { + a = L_add(a, 1); } - - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) + if (a < 0) { - goto ber_detect_res; + a = L_sub(a, 1); } - read_bit_fl(ptr, &mask_side, &bp_side, &bit); - - *nbits_residual = *nbits_residual - 1; - - if (bit == 1) { - if (x[k] > 0) { - x[k] = x[k] + 1; - } else if (x[k] < 0) { - x[k] = x[k] - 1; - } else { - if (*nbits_residual == 0) { - break; - } - - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) - { - goto ber_detect_res; - } - read_bit_fl(ptr, &mask_side, &bp_side, &bit); - - *nbits_residual = *nbits_residual - 1; - - if (bit == 0) { - x[k] = 1; - } else { - x[k] = -1; - } - } +# else + if (a > 0) + { + a = add(a, 1); } - - if (*nbits_residual == 0) { - break; + if (a < 0) + { + a = sub(a, 1); } +# endif + IF (a == 0) + { + IF (n == 0) + { + BREAK; + } + a = 1; +if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) +{ + GOTO ber_detect_res; +} +if (read_bit(ptr, bp_side, mask_side) != 0) +{ + a = negate(a); +} +n = sub(n, 1); +} +} - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) + x[lsb_ind[k]] = a; + move16(); + b = x[lsb_ind[k] + 1]; + move16(); + IF (n == 0) + { + BREAK; + } +if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) +{ +GOTO ber_detect_res; +} + tmp = read_bit(ptr, bp_side, mask_side); + n = sub(n, 1); + IF (tmp > 0) + { +# ifdef ENABLE_HR_MODE + if (b > 0) { - goto ber_detect_res; + b = L_add(b, 1); } - read_bit_fl(ptr, &mask_side, &bp_side, &bit); - - *nbits_residual = *nbits_residual - 1; - - if (bit == 1) { - if (x[k + 1] > 0) { - x[k + 1] = x[k + 1] + 1; - } else if (x[k + 1] < 0) { - x[k + 1] = x[k + 1] - 1; - } else { - if (*nbits_residual == 0) { - break; - } - - if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0) - { - goto ber_detect_res; - } - read_bit_fl(ptr, &mask_side, &bp_side, &bit); - - *nbits_residual = *nbits_residual - 1; - - if (bit == 0) { - x[k + 1] = 1; - } else { - x[k + 1] = -1; - } + if (b < 0) + { + b = L_sub(b, 1); + } +# else + if (b > 0) + { + b = add(b, 1); + } + if (b < 0) + { + b = sub(b, 1); + } +# endif + IF (b == 0) + { + IF (n == 0) + { + BREAK; + } + b = 1; +if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) +{ + GOTO ber_detect_res; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); } + n = sub(n, 1); } } + x[lsb_ind[k] + 1] = b; + move16(); } } - /* Noise-filling seed */ - calculate_nfseed(x, L_spec, nf_seed); - - /* Zero frame flag */ - if (lastnz == 2 && x[0] == 0 && x[1] == 0 && gg_idx == 0 && fac_ns_idx == 7) { +/* Noise Filling seed */ + tmp32 = L_deposit_l(0); + FOR (i = 0; i < L_spec; i++) + { +# ifdef ENABLE_HR_MODE + tmp32 = L_mac0(tmp32, L_and(L_abs(x[i]), 32767), i); +# else + tmp32 = L_mac0(tmp32, abs_s(x[i]), i); +# endif + } + *nf_seed = extract_l(tmp32); + move16(); + + /* Detect zero frame */ + test(); + test(); + test(); + test(); + IF (sub(lastnz, 2) == 0 && sub(x[0], 0) == 0 && sub(x[1], 0) == 0 && sub(gg_idx, 0) == 0 && sub(fac_ns_idx, 7) == 0) + { *zero_frame = 1; - } else { + move16(); + } + ELSE + { *zero_frame = 0; + move16(); } - - if (enc) + +IF (mode == 1) { - if (st.pc_bytes > 0) - { - if (st.pc_b_left > numbytes) - { - *b_left = bp_side - st.pc_bytes; - } - } - } else { - if (st.pc_bytes > 0) + IF (st.pc.bytes > 0) { - if (st.pc_b_left > numbytes) + IF (sub(st.pc.b_left, shr_pos(nbbits, 3)) > 0) { - *b_left = bp_side; + *b_left = sub(*bp_side, st.pc.bytes); } } } - - if ((*bfi == 2) && (*spec_inv_idx == (L_spec + 1))) - { - *bfi = 0; - } - - *spec_inv_idx = *spec_inv_idx - 1; +IF (mode == 2) +{ +IF (st.pc.bytes > 0) +{ +IF (sub(st.pc.b_left, shr_pos(nbbits,3)) > 0) +{ +*b_left = *bp_side; +} +} +} - goto bail; +IF (sub(*bfi, 2) == 0) +{ +IF (sub(*spec_inv_idx, L_spec) == 0) +{ +*bfi = 0; +} +} +GOTO bail; /* goto for bit error handling */ ber_detect: *bfi = 1; - *b_left = st.pc_b_left; - - if (st.pc_inv_bin > 0 && (st.pc_inv_bin - L_spec) <= 0) + move16(); + *b_left = st.pc.b_left; + move16(); + test(); + IF (st.pc.inv_bin > 0 && sub(st.pc.inv_bin, L_spec) <= 0) { - *spec_inv_idx = st.pc_inv_bin; + *spec_inv_idx = st.pc.inv_bin; + move16(); *bfi = 2; + move16(); *resBits = 0; + move16(); *zero_frame = 0; + move16(); /* Noise Filling seed */ - calculate_nfseed(x, *spec_inv_idx, nf_seed); + tmp32 = L_deposit_l(0); + FOR (i = 0; i < *spec_inv_idx; i++) + { + tmp32 = L_mac0(tmp32, abs_s(x[i]), i); + } + *nf_seed = extract_l(tmp32); + move16(); } - goto bail; +GOTO bail; /* goto for bit error handling in residual signal */ ber_detect_res: - *b_left = st.pc_b_left; + *b_left = st.pc.b_left; + move16(); *resBits = 0; + move16(); *bfi = 0; + move16(); *zero_frame = 0; + move16(); /* Noise Filling seed */ - calculate_nfseed(x, *spec_inv_idx, nf_seed); - goto bail; + tmp32 = L_deposit_l(0); + FOR (i = 0; i < *spec_inv_idx; i++) + { + tmp32 = L_mac0(tmp32, abs_s(x[i]), i); + } + *nf_seed = extract_l(tmp32); + move16(); + GOTO bail; /* goto, because of dynmem out */ bail: - -#ifdef WMOPS - pop_wmops(); -#endif - /* Avoid warning "label at end of compound statement" when WMOPS is inactive */ - (void)0; +Dyn_Mem_Deluxe_Out(); } -#else - -void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting, - LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx, - LC3_INT gg_idx, uint8_t * resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes, - LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms, - LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx, - LC3_INT hrmode -) +void processAriDecoderScaling_fx( +# ifdef ENABLE_HR_MODE + Word32 *datain, +# else + Word16 *data16, +# endif + Word16 dataLen, Word32 *data32, Word16 *data_e) { - Decoder_State_fl st; - LC3_INT a = 0, b = 0, t = 0, bp = 0; - LC3_INT c = 0; - LC3_INT nbits_side = 0, extra_bits = 0; - LC3_UINT8* ptr = NULL; - LC3_INT n = 0, k = 0, lev = 0; - LC3_INT max_lev = 0, tmp = 0; - LC3_INT sym_freq[MAX_LEN] = {0}, cum_freq[MAX_LEN] = {0}, numsym = 0, bit = 0, lev1 = 0, pki = 0, sym = 0, - save_lev[MAX_LEN] = {0}, idx_len = 0, total_bits = 0, nbits_ari = 0, rateFlag = 0; - - total_bits = 8 * numbytes; - - memset(&st, 0, sizeof(st)); + Counter i; - - st.pc_bytes = (n_pc + 1) >> 1; - st.pc_b_left = numbytes + 1; - st.pc_b_right = -1; - st.pc_enc = enc; - st.pc_bfi = *bfi; - st.pc_be_bp_left = floor(be_bp_left / 8); - st.pc_be_bp_right = floor(be_bp_right / 8) - 1; - *spec_inv_idx = L_spec + 1; - assert(st.pc_be_bp_right < st.pc_bytes || st.pc_bytes == 0); +# ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In(Word16 shift; Word32 tmp, x_min, x_max;); +# else + Dyn_Mem_Deluxe_In(Word16 shift; Word16 tmp, x_min, x_max;); +# endif + + +#ifdef ENABLE_HR_MODE + x_max = 0; + move32(); + x_min = 0; + move32(); +#else + x_max = 0; + move16(); + x_min = 0; + move16(); +#endif - /* Rate flag */ - if (fs_idx != 5) + FOR (i = 0; i < dataLen; i++) { - if (total_bits > (160 + fs_idx * 160)) { - rateFlag = 512; - } +#ifdef ENABLE_HR_MODE + if (datain[i] > 0) + x_max = L_max(x_max, datain[i]); + if (datain[i] < 0) + x_min = L_min(x_min, datain[i]); +#else + if (data16[i] > 0) + x_max = s_max(x_max, data16[i]); + if (data16[i] < 0) + x_min = s_min(x_min, data16[i]); +#endif } - /* Init */ - c = 0; - t = 0; - bp = 0; - - *b_left = -1; - - ptr = bytes; - - /* Start Decoding */ - ac_dec_init_fl(ptr, &bp, &st, 1, mask_side, &bp_side); - - /* Decode TNS data */ - tmp = MAXLAG; - if (frame_dms == 25) +#ifdef ENABLE_HR_MODE + tmp = L_max(x_max, L_negate(x_min)); + shift = norm_l(tmp); + if (tmp == 0) { - tmp /= 2; + shift = 31; + move32(); } - if (frame_dms == 50) +#else + tmp = s_max(x_max, negate(x_min)); + shift = norm_s(tmp); + if (tmp == 0) { - tmp /= 2; - } - - /* Decode TNS data */ - for (n = 0; n < tns_numfilters; n++) { - - if (tns_order[n] > 0) { - tns_order_freq(enable_lpc_weighting, sym_freq, cum_freq, &numsym); - - tns_order[n] = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - tns_order[n] = tns_order[n] + 1; - - if (tns_order[n] > tmp) - { - st.BER_detect = 1; - } - - if (st.pc_bbi == 1) - { - spec_inv_idx = 0; - } else if (st.pc_bbi == 2) - { - st.BER_detect = 1; - } - - for (k = 0; k < tns_order[n]; k++) { - if (bp_side < bp) - { - *bfi = 1; - return; - } - - tns_coef_freq(k, sym_freq, cum_freq, &numsym); - tns_idx[n * 8 + k] = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 1) - { - spec_inv_idx = 0; - } else if (st.pc_bbi == 2) - { - st.BER_detect = 1; - } - } - } - } - - if (st.BER_detect > 0) { - *bfi = 1; - return; + shift = 15; + move16(); } +#endif - /* Spectral data */ - for (k = 0; k < lastnz; k = k + 2) { - /* Context */ - t = c + rateFlag; - - if (k > L_spec / 2) { - t = t + 256; - } - - /* Decode amplitude */ - x[k] = 0; - x[k + 1] = 0; - - if (hrmode == 1) { - max_lev = 13 + 8; - } else { - max_lev = 13; - } - - for (lev = 0; lev <= max_lev; lev++) { - lev1 = MIN(lev, 3); - pki = ari_spec_lookup_fl[t + lev1 * 1024]; - ac_freq(pki, sym_freq, cum_freq, &numsym); - sym = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 1) - { - *spec_inv_idx = MIN(*spec_inv_idx, k); - } else if (st.pc_bbi == 2) - { - *spec_inv_idx = k; - x[k] = 0; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - if (sym < 16) { - break; - } - - if (lsbMode == 0 || lev > 0) { - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *spec_inv_idx = k; - x[k] = 0; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - x[k] = x[k] + (bit << lev); - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *spec_inv_idx = k; - x[k] = 0; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - x[k + 1] = x[k + 1] + (bit << lev); - } - } - - if ((lev - 1) == 13 && sym == 16) - { - st.BER_detect = 1; - } - - if (hrmode == 0) { - lev = MIN(lev, 13); - } + FOR (i = 0; i < dataLen; i++) + { +#ifdef ENABLE_HR_MODE + data32[i] = L_shl_pos(datain[i], shift); +#else + data32[i] = L_shl_pos(L_deposit_h(data16[i]), shift); +#endif + } - if (lsbMode == 1) { - save_lev[k] = lev; - } +#ifdef ENABLE_HR_MODE + *data_e = sub(31, shift); + move16(); +#else + *data_e = sub(15, shift); + move16(); +#endif - a = sym & 3; - b = sym >> 2; + Dyn_Mem_Deluxe_Out(); +} - x[k] = x[k] + (a << lev); - x[k + 1] = x[k + 1] + (b << lev); - /* Decode signs */ - if (x[k] > 0) { - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *spec_inv_idx = k; - x[k] = 0; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } +/*************************************************************************/ +/*************************************************************************/ +/*************************************************************************/ - if (bit == 1) { - x[k] = -x[k]; - } - } +/*************************************************************************/ - if (x[k + 1] > 0) { - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) +static __forceinline UWord32 UL_addNs24(UWord32 UL_var1, UWord32 UL_var2, UWord16 *wrap) +{ + return UL_lshr(UL_addNs(UL_lshl(UL_var1, 8), UL_lshl(UL_var2, 8), wrap), 8); +} +#ifdef ENABLE_HR_MODE +Word16 find_last_nz_pair(const Word32 x[], Word16 length) +#else +Word16 find_last_nz_pair(const Word16 x[], Word16 length) +#endif +{ + Dyn_Mem_Deluxe_In(Word16 last_nz, lobs[4]; Counter stage, i;); + + lobs[0] = 4; + move16(); + lobs[1] = shr_pos(length, 1); /* length/2 */ + move16(); + lobs[2] = add(lobs[1], shr_pos(length, 2)); + move16(); + lobs[3] = add(lobs[2], shr_pos(length, 3)); + move16(); + + last_nz = 0; + move16(); + i = length; + move16(); + FOR (stage = 3; stage >= 0; --stage) + { + /* unmapped kernel */ + FOR (; i >= lobs[stage]; i -= 2) + { + if (x[i - 2] != 0) { - *b_left = st.pc_b_left; - return; + last_nz = s_max(last_nz, i); } - - if (st.pc_bbi == 2) + if (x[i - 1] != 0) { - *spec_inv_idx = k + 1; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - if (bit == 1) { - x[k + 1] = -x[k + 1]; + last_nz = s_max(last_nz, i); } } - - /* Context */ - lev1 = MIN(lev, 3); - if (lev1 <= 1) { - t = 1 + (a + b) * (lev1 + 1); - } else { - t = 12 + lev1; + IF (last_nz > 0) + { + BREAK; } + } - c = (c & 15) * 16 + t; + Dyn_Mem_Deluxe_Out(); + return s_max(last_nz, 2); +} - if (((bp - bp_side) > 3 && (st.pc_c_bp == st.pc_c_bp_side))) { - if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) - { - *bfi = 2; - calculate_nfseed(x, k, nf_seed); - return; - } +void write_bit_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 bit) +{ + if (bit > 0) + { + ptr[*bp] = (UWord8)s_or((Word16)ptr[*bp], *mask); + move16(); + } + *mask = lshl_pos(*mask, 1); + move16(); + if (sub(*mask, 0x100) == 0) + { + *mask = 1; + move16(); + } + if (sub(*mask, 1) == 0) + { + *bp = sub(*bp, 1); + move16(); + } +} - *bfi = 1; - return; - } - - if (st.BER_detect > 0) - { - if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) - { - *bfi = 2; - calculate_nfseed(x, k, nf_seed); - return; - } - *bfi = 1; - return; - } +void write_indice_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 indice, Word16 numbits) +{ + Dyn_Mem_Deluxe_In(Counter k; Word16 bit;); + + FOR (k = 0; k < numbits; k++) + { + bit = s_and(indice, 1); + write_bit_backward(ptr, bp, mask, bit); + indice = lshr(indice, 1); } - /* Residual bits */ - nbits_side = total_bits - (8 * bp_side + 8 - (31 - clz_func(mask_side))); - nbits_ari = (bp - 3) * 8; - extra_bits = 25 - (31 - clz_func(st.ac_range_fl)); + Dyn_Mem_Deluxe_Out(); +} + + +static __forceinline void write_indice_forward(UWord8 *ptr, Word16 bp, Word16 indice, Word16 numbits) +{ + Dyn_Mem_Deluxe_In(Counter k; Word16 bit, mask, tmp;); - if (enc == 0) + tmp = (Word16)ptr[bp]; + move16(); + mask = 0x80; + move16(); + FOR (k = 0; k < numbits; k++) { - if (st.pc_c_bp == 0) + bit = s_and(indice, mask); + tmp = s_or(tmp, mask); + if (bit == 0) { - nbits_ari = (bp - st.pc_bytes - 3) * 8; - } else { - nbits_ari = (bp + st.pc_b_left - st.pc_bytes - 3) * 8; - } - - if (st.pc_c_bp_side != 0) - { - nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOGTWO(mask_side)); + tmp = sub(tmp, mask); } + mask = lshr(mask, 1); } + ptr[bp] = (UWord8)tmp; + move16(); - - *nbits_residual = total_bits - (nbits_side + nbits_ari + extra_bits); + Dyn_Mem_Deluxe_Out(); +} + +static __forceinline void ac_enc_init_fx(Encoder_State_fx *st_fx) /* i/o: Encoder state */ +{ + st_fx->ac_low_fx = L_deposit_l(0); + move32(); + st_fx->ac_range_fx = 0x00ffffff; + move32(); + st_fx->ac_cache_fx = -1; + move16(); + st_fx->ac_carry_fx = 0; + move16(); + st_fx->ac_carry_count_fx = 0; + move16(); +} - if (*nbits_residual < 0) { - if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) +static __forceinline void ac_enc_shift_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx) /* i/o: Encoder state */ +{ + test(); + L_sub(0, 0); /* For comparision in if */ + IF (st_fx->ac_low_fx < (0x00ff0000UL) || sub(st_fx->ac_carry_fx, 1) == 0) + { + IF (st_fx->ac_cache_fx >= 0) { - *bfi = 2; - calculate_nfseed(x, k, nf_seed); - return; + ptr[(*bp)++] = (UWord8)add(st_fx->ac_cache_fx, st_fx->ac_carry_fx); + move16(); } - - *bfi = 1; - return; - } - if (lsbMode == 0) { - findNonZero(x, L_spec, &idx_len); - if (hrmode) + WHILE (st_fx->ac_carry_count_fx > 0) { - idx_len *= EXT_RES_ITER_MAX; + ptr[(*bp)++] = (UWord8)s_and(add(st_fx->ac_carry_fx, 0xff), 255); + move16(); + st_fx->ac_carry_count_fx = sub(st_fx->ac_carry_count_fx, 1); + move16(); } - *nbits_residual = MIN(*nbits_residual, idx_len); - *residualPresent = 1; - memset(resBits, 0, MAX_RESBITS_LEN); + st_fx->ac_cache_fx = u_extract_l(UL_lshr_pos(st_fx->ac_low_fx, 16)); + move16(); + st_fx->ac_carry_fx = 0; + move16(); + } + ELSE + { + st_fx->ac_carry_count_fx = add(st_fx->ac_carry_count_fx, 1); + move16(); + } + st_fx->ac_low_fx = UL_and(UL_lshl_pos(st_fx->ac_low_fx, 8), 0x00ffffff); + move32(); +} + +static __forceinline void ac_encode_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx, /* i/o: Encoder state */ + UWord32 cum_freq, /* i : Cumulative frequency up to symbol */ + UWord32 sym_freq) /* i : Symbol probability */ +{ + Dyn_Mem_Deluxe_In(UWord32 r, tmp; UWord16 carry;); - for (k = 0; k < *nbits_residual; k++) { - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &tmp, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(uint8_t) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - resBits[k >> 3] |= tmp << (k & 7); - } - } else { - for (k = 0; k < lastnz; k = k + 2) { - if (save_lev[k] > 0) { - if (*nbits_residual == 0) { - break; - } + r = UL_lshr_pos(st_fx->ac_range_fx, 10); + tmp = UL_Mpy_32_32(r, cum_freq); - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } + assert(r < (1U << 24)); + assert(cum_freq < (1U << 24)); + assert(tmp < (1U << 24)); + assert(st_fx->ac_low_fx < (1U << 24)); + st_fx->ac_low_fx = UL_addNs24(st_fx->ac_low_fx, tmp, &carry); + move32(); - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - *nbits_residual = *nbits_residual - 1; - - if (bit == 1) { - if (x[k] > 0) { - x[k] = x[k] + 1; - } else if (x[k] < 0) { - x[k] = x[k] - 1; - } else { - if (*nbits_residual == 0) { - break; - } + if (carry != 0) + { + st_fx->ac_carry_fx = carry; + move16(); + } - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } + st_fx->ac_range_fx = UL_Mpy_32_32(r, sym_freq); + move32(); - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - *nbits_residual = *nbits_residual - 1; + assert(cum_freq < (1U << 24)); + assert(st_fx->ac_range_fx < (1U << 24)); + WHILE (st_fx->ac_range_fx < (1U << 16)) + { + L_sub(0, 0); /* Comparison in while */ + st_fx->ac_range_fx = UL_lshl_pos(st_fx->ac_range_fx, 8); + move32(); - if (bit == 0) { - x[k] = 1; - } else { - x[k] = -1; - } - } - } + assert(st_fx->ac_range_fx < (1U << 24)); - if (*nbits_residual == 0) { - break; - } + ac_enc_shift_fx(ptr, bp, st_fx); + } - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } + Dyn_Mem_Deluxe_Out(); +} - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - *nbits_residual = *nbits_residual - 1; - - if (bit == 1) { - if (x[k + 1] > 0) { - x[k + 1] = x[k + 1] + 1; - } else if (x[k + 1] < 0) { - x[k + 1] = x[k + 1] - 1; - } else { - if (*nbits_residual == 0) { - break; - } +static __forceinline Word16 ac_enc_finish_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx) /* i/o: Encoder state */ +{ + Dyn_Mem_Deluxe_In(UWord32 val, mask, high; Word16 bits; UWord16 over1, over2;); - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } + /*bits = 24 - log2_i(st->ac_range); */ + bits = sub(norm_ul(st_fx->ac_range_fx), 7); - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - *nbits_residual = *nbits_residual - 1; + mask = UL_lshr(0x00ffffff, bits); - if (bit == 0) { - x[k + 1] = 1; - } else { - x[k + 1] = -1; - } - } - } - } + val = UL_addNs24(st_fx->ac_low_fx, mask, &over1); + high = UL_addNs24(st_fx->ac_low_fx, st_fx->ac_range_fx, &over2); + + L_xor(0, 0); /* For bit not */ + UL_and(1U, 1U); /* added counters */ + val = L_and(val, (~mask) & 0x00ffffff); + + L_xor(0, 0); /* For bit not */ + IF ((L_xor(over1, over2)) == 0) + { + L_sub(0, 0); /* For comparision in if */ + IF (UL_addNsD(val, mask) >= high) + { + bits = add(bits, 1); + mask = UL_lshr_pos(mask, 1); + val = UL_and(UL_addNsD(st_fx->ac_low_fx, mask), (~mask) & 0x00ffffff); + L_xor(0, 0); + UL_and(1, 1); /* For bit not , mask */ + } + + if (val < st_fx->ac_low_fx) + { + st_fx->ac_carry_fx = 1; + move16(); } } - /* Noise-filling seed */ - calculate_nfseed(x, L_spec, nf_seed); + st_fx->ac_low_fx = val; + move32(); - /* Zero frame flag */ - if (lastnz == 2 && x[0] == 0 && x[1] == 0 && gg_idx == 0 && fac_ns_idx == 7) { - *zero_frame = 1; - } else { - *zero_frame = 0; + FOR (; bits > 0; bits -= 8) + { + ac_enc_shift_fx(ptr, bp, st_fx); } - - if (enc) + bits = add(bits, 8); + + assert(st_fx->ac_carry_fx == 0); + + IF (st_fx->ac_carry_count_fx > 0) { - if (st.pc_bytes > 0) + ptr[(*bp)++] = (UWord8)st_fx->ac_cache_fx; + move16(); + + FOR (; st_fx->ac_carry_count_fx > 1; st_fx->ac_carry_count_fx--) { - if (st.pc_b_left > numbytes) - { - *b_left = bp_side - st.pc_bytes; - } + ptr[(*bp)++] = 0xff; + move16(); } + write_indice_forward(ptr, *bp, lshr(0xff, sub(8, bits)), bits); } - - if ((*bfi == 2) && (*spec_inv_idx == (L_spec + 1))) + ELSE { - *bfi = 0; + write_indice_forward(ptr, *bp, st_fx->ac_cache_fx, bits); } - - *spec_inv_idx = *spec_inv_idx - 1; + + Dyn_Mem_Deluxe_Out(); + return bits; } -#endif -void ac_encode_fl(Encoder_State_fl* st, LC3_INT sym_freq, LC3_INT cum_freq) +__forceinline Word16 read_bit(UWord8 *ptr, Word16 *bp, Word16 *mask) { - LC3_INT r; + Dyn_Mem_Deluxe_In(Word16 bit;); - r = st->range >> 10; - st->low += r * cum_freq; - - if ((st->low >> 24) == 1) { - st->carry = 1; + bit = 0; + move16(); + if (s_and((Word16)ptr[*bp], *mask) > 0) + { + bit = 1; + move16(); } - - st->low &= (16777215); /* 2^24 -1 */ - st->range = r * sym_freq; - - while (st->range < 65536) { /* 2^16 */ - st->range <<= 8; - ac_shift_fl(st); + *mask = lshl_pos(*mask, 1); + move16(); + if (sub(*mask, 0x100) == 0) + { + *mask = 1; + move16(); } -} - -void ac_shift_fl(Encoder_State_fl* st) -{ - if (st->low < 16711680 || st->carry == 1) { - if (st->cache >= 0) { - st->ptr[st->bp] = st->cache + st->carry; - st->bp = st->bp + 1; - } - - while (st->carry_count > 0) { - st->ptr[st->bp] = (st->carry + 255) & 255; - st->bp = st->bp + 1; - st->carry_count = st->carry_count - 1; - } - - st->cache = st->low >> 16; - st->carry = 0; - } else { - st->carry_count = st->carry_count + 1; + if (sub(*mask, 1) == 0) + { + *bp = sub(*bp, 1); + move16(); } - st->low = st->low << 8; - st->low = (st->low) & (16777215); /* 2^24 - 1 */ + Dyn_Mem_Deluxe_Out(); + return bit; } -void ac_finalize_fl(Encoder_State_fl* st) +static __forceinline void ac_dec_init_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, + Decoder_State_fx *st_fx) /* i/o: Decoder State */ { - LC3_INT bits = 0, mask = 0, val = 0, over1 = 0, high = 0, over2 = 0, c = 0, b = 0; - - bits = 24 - (31 - clz_func(st->range)); - mask = 16777215 >> bits; - val = st->low + mask; - over1 = val >> 24; - - val = (val) & 16777215; - high = st->low + st->range; - over2 = high >> 24; - high = high & 16777215; - val = val & (16777215 - mask); - - if (over1 == over2) { - if (val + mask >= high) { - bits = bits + 1; - mask = mask >> 1; - val = ((st->low + mask) & (16777215)) & (16777215 - mask); - } + Dyn_Mem_Deluxe_In(Counter i;); - if (val < st->low) { - st->carry = 1; + + st_fx->ac_low_fx = L_deposit_l(0); + move32(); + + st_fx->ac_range_fx = 0x00ffffff; + move32(); + FOR (i = 0; i < 3; i++) + { + if (check_pc_bytes(bp, bp_side, mask_side, 0, 1, &st_fx->pc) != 0) + { + Dyn_Mem_Deluxe_Out(); + return; } + st_fx->ac_low_fx = UL_addNsD(UL_lshl_pos(st_fx->ac_low_fx, 8), UL_deposit_l((Word16)ptr[(*bp)++])); + move32(); + assert(st_fx->ac_low_fx < (1U << 24)); } - st->low = val; + st_fx->BER_detect = 0; + move16(); - b = bits; + Dyn_Mem_Deluxe_Out(); +} - if (bits > 8) { - for (; b >= 1; b = b - 8) { - ac_shift_fl(st); - } - } else { - ac_shift_fl(st); +/* o : Decoded cumulative frequency */ +static __forceinline Word16 ac_decode_fx(Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 pki) +{ + Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;); + + st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10); + move32(); + val = 0; + move16(); + + r = add(val, 8); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); } - bits = b; - if (bits < 0) { - bits += 8; + r = add(val, 4); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); } - if (st->carry_count > 0) { - st->ptr[st->bp] = st->cache; - st->bp = st->bp + 1; + r = add(val, 2); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } - for (c = st->carry_count; c >= 2; c--) { - st->ptr[st->bp] = 255; - st->bp = st->bp + 1; + r = add(val, 1); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn); + IF (sgn == 0) + { + val = r; + move16(); + IF (sub(val, 15) == 0) + { + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][16]), &sgn); + if (sgn == 0) + { + val = 16; + move16(); + } + UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn); + if (sgn == 0) + { + st_fx->BER_detect = 1; + move16(); + } } - - write_uint_forward_fl(st, 255 << (bits - 8), bits); - } else { - write_uint_forward_fl(st, st->cache, bits); } + + Dyn_Mem_Deluxe_Out(); + return val; } -void write_uint_forward_fl(Encoder_State_fl* st, LC3_INT val, LC3_INT numbits) +/* o : Decoded cumulative frequency */ +static __forceinline Word16 ac_decode_tns_order(Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 enable_lpc_weighting) { - LC3_INT k, bit, mask = 128; - - for (k = 0; k < numbits; k++) { - bit = val & mask; + Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;); - if (bit == 0) { - st->ptr[st->bp] = st->ptr[st->bp] & (255 - mask); - } else { - st->ptr[st->bp] = st->ptr[st->bp] | mask; - } + st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10); + move32(); + val = 0; + move16(); - mask = mask >> 1; + r = add(val, 4); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); } -} -void ari_enc_init(Encoder_State_fl* st, LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side) -{ - st->ptr = bytes; - st->bp_side = bp_side; - st->mask_side = mask_side; - st->bp = 0; - st->low = 0; - st->range = 16777215; - st->cache = -1; - st->carry = 0; - st->carry_count = 0; -} + r = add(val, 2); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } -LC3_INT sign(LC3_INT x) -{ - if (x > 0) - return 1; + r = add(val, 1); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } - if (x < 0) - return -1; + UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn); + if (sgn == 0) + { + st_fx->BER_detect = 1; + move16(); + } - return 0; + Dyn_Mem_Deluxe_Out(); + return val; } -void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT* x, LC3_INT* tns_order, LC3_INT tns_numfilters, - LC3_INT* tns_idx, LC3_INT lastnz, LC3_INT* codingdata, uint8_t* res_bits, LC3_INT resBitsLen, LC3_INT lsbMode, - LC3_INT nbbits, LC3_INT enable_lpc_weighting) +/* o : Decoded cumulative frequency */ +static __forceinline Word16 ac_decode_tns_coef(Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 pki) { - LC3_INT total_bits, cumfreq, symfreq, k, i, j, lev, lev1; - LC3_INT bit1, bit2, lsb1, lsb2, a, b, bit, pki, nbits_side; - LC3_INT nbits_residual_enc, nbits_ari, lsbs[MAX_LEN], lsbsLen = 0; - LC3_INT abs_x_k, abs_x_kp1; - Encoder_State_fl st; - -#ifdef WMOPS - push_wmops("processAriEncoder_fl"); -#endif + Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;); + + st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10); + move32(); + val = 0; + move16(); - ari_enc_init(&st, bytes, &bp_side, &mask_side); + r = add(val, 8); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } - total_bits = nbbits; + r = add(val, 4); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } - /* TNS data */ - for (i = 0; i < tns_numfilters; i++) { - if (tns_order[i] > 0) { - symfreq = tns_freq_cf[enable_lpc_weighting][tns_order[i]] - tns_freq_cf[enable_lpc_weighting][tns_order[i] - 1]; - cumfreq = tns_freq_cf[enable_lpc_weighting][tns_order[i] - 1]; - ac_encode_fl(&st, symfreq, cumfreq); + r = add(val, 2); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } - for (j = 0; j < tns_order[i]; j++) { - symfreq = tns_cf[j][tns_idx[i * 8 + j] + 1] - tns_cf[j][tns_idx[i * 8 + j]]; - cumfreq = tns_cf[j][tns_idx[i * 8 + j]]; - ac_encode_fl(&st, symfreq, cumfreq); + r = add(val, 1); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + IF (sub(val, 15) == 0) + { + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][16]), &sgn); + if (sgn == 0) + { + val = 16; + move16(); + } + UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn); + if (sgn == 0) + { + st_fx->BER_detect = 1; + move16(); } } } - /* Spectral data */ - for (k = 0; k < lastnz; k = k + 2) { - abs_x_k = abs(x[k]); - abs_x_kp1 = abs(x[k + 1]); - for (lev = 0; lev < codingdata[1]; lev++) { - lev1 = MIN(lev, 3); - pki = ari_spec_lookup_fl[codingdata[0] + lev1 * 1024]; - symfreq = ari_spec_cumfreq_fl[pki][17] - ari_spec_cumfreq_fl[pki][16]; - cumfreq = ari_spec_cumfreq_fl[pki][16]; - - ac_encode_fl(&st, symfreq, cumfreq); - bit1 = (abs_x_k >> lev) & 1; - bit2 = (abs_x_kp1 >> lev) & 1; - + Dyn_Mem_Deluxe_Out(); + return val; +} - if (lsbMode == 1 && lev == 0) { - lsb1 = bit1; - lsb2 = bit2; - } else { - write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit1); - write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit2); - } - } +static __forceinline Word16 ac_dec_update_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, + Word16 cur_bin, Decoder_State_fx *st_fx, /* i/o: Decoder State */ + UWord32 cum_freq, /* i : Cumulative frequency */ + UWord32 sym_freq /* i : Symbol frequency */ +) +{ + UWord32 UL_tmp; - lev1 = MIN(MAX(codingdata[1], 0), 3); - pki = ari_spec_lookup_fl[codingdata[0] + lev1 * 1024]; - symfreq = ari_spec_cumfreq_fl[pki][codingdata[2] + 1] - ari_spec_cumfreq_fl[pki][codingdata[2]]; - cumfreq = ari_spec_cumfreq_fl[pki][codingdata[2]]; - ac_encode_fl(&st, symfreq, cumfreq); + assert(st_fx->ac_help_fx < (1U << 24)); + assert(cum_freq < (1U << 24)); - a = abs_x_k; - b = abs_x_kp1; + UL_tmp = UL_Mpy_32_32(cum_freq, st_fx->ac_help_fx); + assert(UL_tmp < (1U << 24)); - if (lsbMode == 1 && codingdata[1] > 0) { - a = a >> 1; - lsbs[lsbsLen] = lsb1; - lsbsLen++; + st_fx->ac_low_fx = UL_subNsD(st_fx->ac_low_fx, UL_tmp); + move32(); /*0+0*/ + assert(st_fx->ac_low_fx < (1U << 24)); - if (a == 0 && x[k] != 0) { - bit = MAX(0, -sign(x[k])); - lsbs[lsbsLen] = bit; - lsbsLen++; - } + st_fx->ac_range_fx = UL_Mpy_32_32(st_fx->ac_help_fx, sym_freq); + move32(); - b = b >> 1; - lsbs[lsbsLen] = lsb2; - lsbsLen++; + assert(st_fx->ac_range_fx < (1U << 24)); + /* updated to 16 from 24 */ + WHILE (st_fx->ac_range_fx < (1U << 16)) + { + L_sub(0, 0); /* For comparision in while*/ - if (b == 0 && x[k + 1] != 0) { - bit = MAX(0, -sign(x[k + 1])); - lsbs[lsbsLen] = bit; - lsbsLen++; - } - } + st_fx->ac_low_fx = + UL_and(st_fx->ac_low_fx, 0x0000ffFF); /* make sure upshift doe not lead to more than 24 bits */ + assert(st_fx->ac_low_fx < 1U << 16); - if (a != 0) { - bit = MAX(0, -sign(x[k])); - write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit); - } + if (check_pc_bytes(bp, bp_side, mask_side, cur_bin, 1, &st_fx->pc) != 0) + return 1; - if (b != 0) { - bit = MAX(0, -sign(x[k + 1])); - write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit); - } + /*shift in 8 bits */ + st_fx->ac_low_fx = UL_addNsD(UL_lshl_pos(st_fx->ac_low_fx, 8), UL_deposit_l((Word16)ptr[(*bp)++])); + move32(); - codingdata += 3; + assert(st_fx->ac_low_fx < (1U << 24)); + st_fx->ac_range_fx = UL_lshl_pos(st_fx->ac_range_fx, 8); + move32(); + assert(st_fx->ac_range_fx < (1U << 24)); } + return 0; +} - /* Residual bits */ - nbits_side = total_bits - (8 * (*(st.bp_side) + 1) + 8 - (31 - clz_func(*(st.mask_side)))); - nbits_ari = 8 * (st.bp + 1) + 25 - (31 - clz_func(st.range )) ; +static __forceinline void pc_init_fx(Word16 n_pc, Word16 numbytes, Word16 be_bp_left, Word16 be_bp_right, Word16 L_spec, + Word16 enc, Word16 sim_dec, Word16 bfi, Pc_State_fx *pc /* i/o: Pc State */ +) +{ +pc->inv_bin = add(L_spec, 1); move16(); +pc->numbytes = numbytes; move16(); +pc->c_bp = 0; move16(); +pc->c_bp_side = 0; move16(); +pc->bytes = shr(add(n_pc, 1),1); move16(); +pc->b_left = add(numbytes,1); move16(); +pc->b_right = -1; move16(); +pc->enc = enc; move16(); +pc->sim_dec = sim_dec; move16(); +pc->bfi = bfi; move16(); +pc->be_bp_left = shr(be_bp_left, 3); move16(); +pc->be_bp_right = shr(be_bp_right, 3); move16(); + assert(pc->be_bp_right < pc->bytes || pc->bytes == 0); +} - if (st.cache >= 0) { - nbits_ari = nbits_ari + 8; - } +static __forceinline Word16 check_pc_bytes(Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin, + Word16 from_left, Pc_State_fx *pc /* i/o: Pc State */) +{ + Dyn_Mem_Deluxe_In(Word16 bp_local, bp_side_local, offset;); - if (st.carry_count > 0) { - nbits_ari = nbits_ari + st.carry_count * 8; - } + IF (pc->bytes > 0) + { + test(); + IF (from_left == 0 && sub(*mask_side, 1) != 0) + { + Dyn_Mem_Deluxe_Out(); + return 0; + } + test(); + IF (pc->c_bp_side > 0 && *bp_side < 0) + { + assert(*mask_side == 1); + assert(pc->b_right != -1); + *bp_side = pc->b_right; + Dyn_Mem_Deluxe_Out(); + return 0; + } + bp_local = *bp; + bp_side_local = *bp_side; - nbits_residual_enc = MAX(total_bits - (nbits_side + nbits_ari), 0); - /* the max operation avoids in very rare cases, that - * nbits_residual_enc becomes negative; having overwritten - * the last bit(s) of the side information is in this case - * assumed to be not critical, since no spectral data bits - * were written */ + IF (from_left != 0) + { + if (sub(*mask_side, 1) == 0) + { + bp_side_local = add(bp_side_local, 1); + } + } + ELSE + { + bp_local = sub(bp_local, 1); + } - if (lsbMode == 0) { - nbits_residual_enc = MIN(nbits_residual_enc, resBitsLen); - for (k = 0; k < nbits_residual_enc; k++) { - if (res_bits[k >> 3] & (1 << (k & 7))) + IF (pc->b_right < 0) + { + offset = -1; + move16(); + if (pc->enc == 0) { - write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, 1); + offset = add(offset, pc->bytes); } - else + + IF (add(bp_side_local, sub(offset, bp_local)) == pc->bytes) { - write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, 0); + pc->b_left = add(bp_local, 1); + pc->b_right = sub(bp_side_local, 1); + IF (pc->enc != 0) + { + assert(pc->b_right - pc->b_left + 1 == pc->bytes); + Dyn_Mem_Deluxe_Out(); + return 1; + } } } - } else { - nbits_residual_enc = MIN(nbits_residual_enc, lsbsLen); - for (k = 0; k < nbits_residual_enc; k++) { - write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, lsbs[k]); + test(); + IF (pc->enc == 0 && pc->b_right >= 0) + { + test(); + IF (from_left != 0 && sub(*bp, pc->b_left) == 0) + { + IF (pc->sim_dec == 1) + { + pc->b_left = *bp; + Dyn_Mem_Deluxe_Out(); + return 1; + } + *bp = 0; move16(); + pc->c_bp = 1; move16(); + } + test(); + IF (from_left == 0 && sub(bp_side_local, pc->b_right) == 0) + { + *bp_side = sub(pc->bytes, 1); + move16(); + pc->c_bp_side = 1; + move16(); + } + IF (sub(pc->bfi, 2) == 0) + { + test(); + test(); + IF ((pc->c_bp != 0 && sub(*bp, pc->be_bp_left) >= 0) || + (pc->c_bp_side != 0 && sub(*bp_side, pc->be_bp_right) <= 0)) + { + pc->inv_bin = cur_bin; + move16(); + Dyn_Mem_Deluxe_Out(); + return 1; + } + ELSE IF ((pc->c_bp != 0 && *bp >= 0) || (pc->c_bp_side != 0 && sub(*bp_side, sub(pc->bytes, 1)) <= 0)) + { + pc->inv_bin = s_min(pc->inv_bin, cur_bin); + Dyn_Mem_Deluxe_Out(); + return 0; + } + } } } - ac_finalize_fl(&st); -#ifdef WMOPS - pop_wmops(); -#endif + Dyn_Mem_Deluxe_Out(); + return 0; } diff --git a/lib_lc3plus/attack_detector.c b/lib_lc3plus/attack_detector.c deleted file mode 100644 index 59af3abfd..000000000 --- a/lib_lc3plus/attack_detector.c +++ /dev/null @@ -1,92 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* lastAttackPosition, LC3_FLOAT* accNrg, LC3_INT* attackFlag, - LC3_FLOAT* attdec_filter_mem, LC3_INT attackHandlingOn, LC3_INT attdec_nblocks, LC3_INT attdec_hangover_threshold) -{ - LC3_FLOAT f_sig[160], block_nrg[4], sum, tmpEne, *ptr, tmp[162]; - LC3_INT i, j, attackPosition; - LC3_FLOAT mval; - LC3_INT frame_size_16k; - - if (attackHandlingOn) { - - mval = 0; j = 0; - frame_size_16k = attdec_nblocks * 40; - ptr = &tmp[2]; - - /* Decimate 48 and 32 kHz signals to 16 kHz */ - if (fs == 48000) { - j = 0; - for (i = 0; i < frame_size;) { - ptr[j] = (in[i] + in[i + 1] + in[i + 2]); - i = i + 3; - j++; - } - } else if (fs == 32000) { - j = 0; - for (i = 0; i < frame_size;) { - ptr[j] = (in[i] + in[i + 1]); - i = i + 2; - j++; - } - } - - /* Filter */ - ptr[-2] = (LC3_FLOAT)attdec_filter_mem[0]; - ptr[-1] = (LC3_FLOAT)attdec_filter_mem[1]; - - attdec_filter_mem[0] = ptr[frame_size_16k - 2]; - attdec_filter_mem[1] = ptr[frame_size_16k - 1]; - - for (i = 159; i >= 0; i--) { - tmpEne = 0; - - tmpEne += ptr[i] * 0.375; - tmpEne += ptr[i - 1] * (-0.5); - tmpEne += ptr[i - 2] * (0.125); - - f_sig[i] = tmpEne; - } - - for (i = 0; i < attdec_nblocks; i++) { - sum = 0; - for (j = 0; j < 40; j++) { - sum += f_sig[j + i * 40] * f_sig[j + i * 40]; - } - - block_nrg[i] = sum; - } - - *attackFlag = 0; - attackPosition = -1; - - for (i = 0; i < attdec_nblocks; i++) { - tmpEne = block_nrg[i] / 8.5; - - if (tmpEne > MAX(*accNrg, mval)) { - *attackFlag = 1; - attackPosition = i + 1; - } - - *accNrg = MAX(block_nrg[i], 0.25 * (*accNrg)); - } - - if (*lastAttackPosition > attdec_hangover_threshold) { - *attackFlag = 1; - } - - *lastAttackPosition = attackPosition; - } -} diff --git a/lib_lc3plus/attack_detector_fx.c b/lib_lc3plus/attack_detector_fx.c new file mode 100644 index 000000000..3c62f8494 --- /dev/null +++ b/lib_lc3plus/attack_detector_fx.c @@ -0,0 +1,119 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void attack_detector_fx(LC3PLUS_Enc *enc, EncSetup *setup, Word16 *input, Word16 input_scaling, void *scratch) +{ + Dyn_Mem_Deluxe_In( + int i, j, position; + Word32 tmp, *block_energy; + Word16 h16, l16, new_scaling, rescale, input_delta_scaling; + Word16 scales[3], *input_16k; + Word16 frame_length_16k; + ); + + block_energy = scratchAlign(scratch, 0); + input_16k = scratchAlign(block_energy, 4 * 4 + 4); + frame_length_16k = DEPR_i_mult(enc->attdec_nblocks, 40); + + IF (setup->attack_handling) + { + /* input scaling */ + scales[0] = add(getScaleFactor16(input, enc->frame_length), input_scaling); + scales[1] = add(getScaleFactor16_0(setup->attdec_filter_mem, 2), setup->attdec_scaling); + scales[2] = + shr(add(add(getScaleFactor32_0(&setup->attdec_acc_energy, 1), shl(setup->attdec_scaling, 1)), 1), 1); + new_scaling = s_min(scales[0], s_min(scales[1], scales[2])); + + new_scaling = sub(new_scaling, 2); /* add overhead for resampler*/ + + /* memory re-scaling */ + rescale = sub(new_scaling, setup->attdec_scaling); + + IF (rescale) + { + rescale = s_min(s_max(rescale, -15), 15); + setup->attdec_filter_mem[0] = shl(setup->attdec_filter_mem[0], rescale); move16(); + setup->attdec_filter_mem[1] = shl(setup->attdec_filter_mem[1], rescale); move16(); + setup->attdec_acc_energy = L_shl(setup->attdec_acc_energy, shl(rescale, 1)); move16(); + } + setup->attdec_scaling = new_scaling; move16(); + + SWITCH (enc->fs) + { + case 32000: + input_delta_scaling = sub(1, sub(new_scaling, input_scaling)); + FOR (i = 0; i < frame_length_16k; i++) + { + input_16k[i] = add(shr(input[2 * i + 0], input_delta_scaling), + shr(input[2 * i + 1], input_delta_scaling)); move16(); + } + break; + case 48000: + input_delta_scaling = sub(2, sub(new_scaling, input_scaling)); + FOR (i = 0; i < frame_length_16k; i++) + { + input_16k[i] = add(shr(input[3 * i + 0], input_delta_scaling), + add(shr(input[3 * i + 1], input_delta_scaling), + shr(input[3 * i + 2], input_delta_scaling))); move16(); + } + break; + default: ASSERT(!"sampling rate not supported in function attack_detector_fx!"); break; + } + + input_16k[-2] = setup->attdec_filter_mem[0]; move16(); + input_16k[-1] = setup->attdec_filter_mem[1]; move16(); + setup->attdec_filter_mem[0] = input_16k[frame_length_16k - 2]; move16(); + setup->attdec_filter_mem[1] = input_16k[frame_length_16k - 1]; move16(); + + FOR (i = frame_length_16k - 1; i >= 0; i--) + { + tmp = L_mult(input_16k[i], 12288); + tmp = L_msu(tmp, input_16k[i - 1], 16384); + tmp = L_mac(tmp, input_16k[i - 2], 4096); + + input_16k[i] = extract_h(tmp); move16(); + } + + basop_memset(block_energy, 0, 4 * sizeof(Word32)); + + FOR (j = 0; j < enc->attdec_nblocks; j++) + { + FOR (i = 0; i < 40; i++) + { + block_energy[j] = L_mac(block_energy[j], input_16k[i + j*40], input_16k[i + j*40]); move16(); + } + } + + setup->attdec_detected = setup->attdec_position >= enc->attdec_hangover_thresh; + test(); move16(); + position = -1; move16(); + + FOR (i = 0; i < enc->attdec_nblocks; i++) + { + /* block_energy[i] / 8.5 */ + l16 = extract_l(L_shr(block_energy[i], 1)); + l16 = s_and(l16, 0x7fff); + h16 = extract_h(block_energy[i]); + tmp = L_shr(L_mult0(l16, 30840), 15); + tmp = L_shr(L_mac0(tmp, h16, 30840), 2); + + IF (tmp > setup->attdec_acc_energy) + { + position = i; move16(); + setup->attdec_detected = 1; move16(); + } + setup->attdec_acc_energy = L_max(L_shr(setup->attdec_acc_energy, 2), block_energy[i]); move16(); + } + setup->attdec_position = position; move16(); + } + + Dyn_Mem_Deluxe_Out(); +} diff --git a/lib_lc3plus/basop_mpy_lc3plus.c b/lib_lc3plus/basop_mpy_lc3plus.c new file mode 100644 index 000000000..88a6d336b --- /dev/null +++ b/lib_lc3plus/basop_mpy_lc3plus.c @@ -0,0 +1,99 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" + +#include "functions.h" + +#ifdef ENABLE_HR_MODE +Word32 Mpy_32_32_0(Word32 x, Word32 y) +{ + Word32 z; + + z = L_shr(L_add(Mpy_32_32_lc3plus(x, y),1), 1); + + return (z); +} + +Word32 Mpy_32_16_0(Word32 x, Word16 y) +{ + Word32 z; + + z = L_shr(L_add(Mpy_32_16_lc3plus(x, y),1), 1); + + return (z); +} +#endif + +Word32 Mpy_32_16_lc3plus(Word32 x, Word16 y) +{ + Word32 mh; + UWord16 ml; + + Mpy_32_16_ss(x, y, &mh, &ml); + + return (mh); +} + + +Word32 Mpy_32_32_lc3plus(Word32 x, Word32 y) +{ + Word32 mh; + UWord32 ml; + + Mpy_32_32_ss(x, y, &mh, &ml); + + return (mh); +} + + +void cplxMpy_32_16(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word16 b_Re, + const Word16 b_Im) +{ + *c_Re = L_sub(Mpy_32_16_lc3plus(a_Re, b_Re), Mpy_32_16_lc3plus(a_Im, b_Im)); move32(); + *c_Im = L_add(Mpy_32_16_lc3plus(a_Re, b_Im), Mpy_32_16_lc3plus(a_Im, b_Re)); move32(); +} + +void cplxMpy_32_32(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word32 b_Re, + const Word32 b_Im) +{ + *c_Re = L_sub(Mpy_32_32_lc3plus(a_Re, b_Re), Mpy_32_32_lc3plus(a_Im, b_Im)); move32(); + *c_Im = L_add(Mpy_32_32_lc3plus(a_Re, b_Im), Mpy_32_32_lc3plus(a_Im, b_Re)); move32(); +} + +#ifdef ENABLE_HR_MODE +Word32 Mac_32_16_0(Word32 z, Word32 x, Word16 y) +{ + z = L_add(z, Mpy_32_16_0(x, y)); + + return (z); +} + +Word32 Mac_32_32_0(Word32 z, Word32 x, Word32 y) +{ + z = L_add(z, Mpy_32_32_0(x, y)); + + return (z); +} + +Word32 Msu_32_16_0(Word32 z, Word32 x, Word16 y) +{ + z = L_sub(z, Mpy_32_16_0(x, y)); + + return (z); +} + +Word32 Msu_32_32_0(Word32 z, Word32 x, Word32 y) +{ + z = L_sub(z, Mpy_32_32_0(x, y)); + + return (z); +} + +#endif /* #ifdef ENABLE_HR_MODE */ diff --git a/lib_lc3plus/basop_mpy_lc3plus.h b/lib_lc3plus/basop_mpy_lc3plus.h new file mode 100644 index 000000000..7c08755ee --- /dev/null +++ b/lib_lc3plus/basop_mpy_lc3plus.h @@ -0,0 +1,94 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" + +#ifndef __BASOP_MPY_H +#define __BASOP_MPY_H + +#include "functions.h" + +#ifdef ENABLE_HR_MODE +Word32 Mpy_32_16_0(Word32 x, Word16 y); +#endif + +Word32 Mac_32_16_0(Word32 z, Word32 x, Word16 y); +Word32 Mpy_32_32_0(Word32 x, Word32 y); +Word32 Mac_32_32_0(Word32 z, Word32 x, Word32 y); +Word32 Msu_32_16_0(Word32 z, Word32 x, Word16 y); +Word32 Msu_32_32_0(Word32 z, Word32 x, Word32 y); + +/** + * \brief 32*16 Bit fractional Multiplication using 40 bit OPS + * Performs a multiplication of a 32-bit variable x by + * a 16-bit variable y, returning a 32-bit value. + * + * \param[i] x + * \param[i] y + * + * \return x*y + */ +Word32 Mpy_32_16_lc3plus(Word32 x, Word16 y); + +/** + * \brief 32*32 Bit fractional Multiplication using 40 bit OPS + * + * Performs a multiplication of a 32-bit variable x by + * a 32-bit variable y, returning a 32-bit value. + * + * \param[i] x + * \param[i] y + * + * \return x*y + */ +Word32 Mpy_32_32_lc3plus(Word32 x, Word32 y); + +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + +# ifdef ENABLE_HR_MODE +# define cplxMpy32_32_32_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_32_0(a, c), Mpy_32_32_0(b, d)); \ + im = L_add(Mpy_32_32_0(a, d), Mpy_32_32_0(b, c)); \ + } while (0) +# endif +# define cplxMpy32_32_16_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(L_shr_pos(Mpy_32_16_lc3plus(a, c), 1), L_shr_pos(Mpy_32_16_lc3plus(b, d), 1)); \ + im = L_add(L_shr_pos(Mpy_32_16_lc3plus(a, d), 1), L_shr_pos(Mpy_32_16_lc3plus(b, c), 1)); \ + } while (0) + + +#else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + +# ifdef ENABLE_HR_MODE +# define cplxMpy32_32_32_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_32_0(a, c), Mpy_32_32_0(b, d)); \ + im = L_add(Mpy_32_32_0(a, d), Mpy_32_32_0(b, c)); \ + } while (0) +# endif +# define cplxMpy32_32_16_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(L_shr_pos(Mpy_32_16_lc3plus(a, c), 1), L_shr_pos(Mpy_32_16_lc3plus(b, d), 1)); \ + im = L_add(L_shr_pos(Mpy_32_16_lc3plus(a, d), 1), L_shr_pos(Mpy_32_16_lc3plus(b, c), 1)); \ + } while (0) + +#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + +void cplxMpy_32_16(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word16 b_Re, + const Word16 b_Im); +void cplxMpy_32_32(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word32 b_Re, + const Word32 b_Im); + +#endif /* __BASOP_SETTINGS_H */ diff --git a/lib_lc3plus/basop_util_lc3plus.c b/lib_lc3plus/basop_util_lc3plus.c new file mode 100644 index 000000000..55a9b9eb1 --- /dev/null +++ b/lib_lc3plus/basop_util_lc3plus.c @@ -0,0 +1,1069 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" +#include "rom_basop_util.h" +#include "basop_util_lc3plus.h" + +extern const Word32 SqrtTable_lc3plus[32]; +extern const Word16 SqrtDiffTable_lc3plus[32]; + +extern const Word32 ISqrtTable_lc3plus[32]; +extern const Word16 ISqrtDiffTable_lc3plus[32]; + +extern const Word32 InvTable_lc3plus[32]; +extern const Word16 InvDiffTable_lc3plus[32]; + +Word32 BASOP_Util_Log2_lc3plus(Word32 x) +{ + Word32 exp; + Word16 exp_e; + Word16 nIn; + Word16 accuSqr; + Word32 accuRes; + + assert(x >= 0); + + if (x == 0) + { + + return ((Word32)MIN_32); + } + + /* normalize input, calculate integer part */ + exp_e = norm_l(x); + x = L_shl(x, exp_e); + exp = L_deposit_l(exp_e); + + /* calculate (1-normalized_input) */ + nIn = extract_h(L_sub(MAX_32, x)); + + /* approximate ln() for fractional part (nIn *c0 + nIn^2*c1 + nIn^3*c2 + ... + nIn^8 *c7) */ + + /* iteration 1, no need for accumulation */ + accuRes = L_mult(nIn, ldCoeff_lc3plus[0]); /* nIn^i * coeff[0] */ + accuSqr = mult(nIn, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 2 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[1]); /* nIn^i * coeff[1] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 3 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[2]); /* nIn^i * coeff[2] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 4 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[3]); /* nIn^i * coeff[3] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 5 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[4]); /* nIn^i * coeff[4] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 6 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[5]); /* nIn^i * coeff[5] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 7, no need to calculate accuSqr any more */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[6]); /* nIn^i * coeff[6] */ + + /* ld(fractional part) = ln(fractional part)/ln(2), 1/ln(2) = (1 + 0.44269504) */ + accuRes = L_mac0(L_shr(accuRes, 1), extract_h(accuRes), 14506); + + accuRes = L_shr(accuRes, LD_DATA_SCALE - 1); /* fractional part/LD_DATA_SCALE */ + exp = L_shl(exp, (31 - LD_DATA_SCALE)); /* integer part/LD_DATA_SCALE */ + accuRes = L_sub(accuRes, exp); /* result = integer part + fractional part */ + + return (accuRes); +} + +Word32 BASOP_Util_InvLog2_lc3plus(Word32 x) +{ +#ifdef ENABLE_HR_MODE + /* Original code was used for negative x and hence the exp was always 0, which is assumed */ + Word16 exp; + return BASOP_Util_InvLog2_pos(x, &exp); +#else + Word16 frac; + Word16 exp; + Word32 retVal; + UWord32 index3; + UWord32 index2; + UWord32 index1; + UWord32 lookup3f; + UWord32 lookup12; + UWord32 lookup; + + if (x < -1040187392l /*-31.0/64.0 Q31*/) + { + + return 0; + } + test(); + if ((L_sub(x, 1040187392l /*31.0/64.0 Q31*/) >= 0) || (x == 0)) + { + + return 0x7FFFFFFF; + } + + frac = extract_l(L_and(x, 0x3FF)); + + index3 = L_and(L_shr_pos(x, 10), 0x1F); + index2 = L_and(L_shr_pos(x, 15), 0x1F); + index1 = L_and(L_shr_pos(x, 20), 0x1F); + + exp = extract_l(L_shr_pos(x, 25)); + if (x > 0) + { + exp = sub(31, exp); + } + if (x < 0) + { + exp = negate(exp); + } + + lookup3f = L_add(exp2x_tab_long_lc3plus[index3], L_shr_pos(Mpy_32_16_lc3plus(0x0016302F, frac), 1)); + lookup12 = Mpy_32_32_lc3plus(exp2_tab_long_lc3plus[index1], exp2w_tab_long_lc3plus[index2]); + lookup = Mpy_32_32_lc3plus(lookup12, lookup3f); + + retVal = L_shr(lookup, sub(exp, 3)); + + return retVal; +#endif +} + +#ifdef ENABLE_HR_MODE +/* New function which works with positive and negative exponents */ +Word32 BASOP_Util_InvLog2_pos(Word32 x, Word16 *exp) +{ + Word16 frac; + Word16 ret_exp; + Word32 retVal; + UWord32 index3; + UWord32 index2; + UWord32 index1; + UWord32 lookup3f; + UWord32 lookup12; + UWord32 lookup; + + /* The usage of exp.mantissa format in LC3plus in Word32 is : floatval = mantissa / (2^(31 - exp)) */ + ret_exp = extract_l(L_shr(x, 25)); + + IF (x < -1040187392l /*-31.0/64.0 Q31*/) + { + *exp = 0; + move16(); + return 0; + } + test(); + IF ((L_sub(x, 1040187392l /*31.0/64.0 Q31*/) >= 0)) + { + *exp = 31; + move16(); + return 0x40000000; + } + ELSE IF(x == 0) + { + *exp = -1; + move16(); + return 0x10000000; + } + + frac = extract_l(L_and(x, 0x3FF)); + + index3 = L_and(L_shr(x, 10), 0x1F); + index2 = L_and(L_shr(x, 15), 0x1F); + index1 = L_and(L_shr(x, 20), 0x1F); + + lookup3f = L_add(exp2x_tab_long_lc3plus[index3], L_shr(Mpy_32_16_lc3plus(0x0016302F, frac), 1)); + lookup12 = Mpy_32_32_lc3plus(exp2_tab_long_lc3plus[index1], exp2w_tab_long_lc3plus[index2]); + lookup = Mpy_32_32_lc3plus(lookup12, lookup3f); + + IF (x > 0) + { + /* The returned exponent is the offset from 31, so the float result is + retVal / 2^(31 - *exp) */ + *exp = add(ret_exp, 3); + retVal = lookup; + } + ELSE + { + /* For negative powers provide the result in Q31 and ignore the exponent */ + *exp = 0; + retVal = L_shr(lookup, sub(negate(ret_exp), 3)); + } + + return retVal; +} +#endif + +/* local function for Sqrt16_lc3plus and Sqrt16norm */ +static Word16 Sqrt16_common(Word16 m, Word16 e) +{ + Word16 index, frac; + + assert((m >= 0x4000) || (m == 0)); + + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), m, 1 << 6); + + /* get fractional part for interpolation (lower 9 bits) */ + frac = s_and(m, 0x1FF); /* Q9 */ + + /* interpolate */ + if (m != 0) + { + m = mac_r(SqrtTable_lc3plus[index], SqrtDiffTable_lc3plus[index], frac); + } + + /* handle odd exponents */ + if (s_and(e, 1) != 0) + m = mult_r(m, 0x5a82); + + return m; +} + +/* local function for ISqrt16 and ISqrt16norm */ +static Word16 ISqrt16_common(Word16 m, Word16 e) +{ + Word16 index, frac; + + assert(m >= 0x4000); + + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), m, 1 << 6); + + /* get fractional part for interpolation (lower 9 bits) */ + frac = s_and(m, 0x1FF); /* Q9 */ + + /* interpolate */ + m = msu_r(ISqrtTable_lc3plus[index], ISqrtDiffTable_lc3plus[index], frac); + + /* handle even exponents */ + if (s_and(e, 1) == 0) + m = mult_r(m, 0x5a82); + + return m; +} + +Word16 Sqrt16_lc3plus( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +) +{ + Word16 preShift, e; + + assert(mantissa >= 0); + + /* normalize */ + preShift = norm_s(mantissa); + + e = sub(*exponent, preShift); + mantissa = shl(mantissa, preShift); + + /* calc mantissa */ + mantissa = Sqrt16_common(mantissa, e); + + /* e = (e + 1) >> 1 */ + *exponent = mult_r(e, 1 << 14); move16(); + + return mantissa; +} + +Word16 ISqrt16( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +) +{ + Word16 preShift, e; + + assert(mantissa > 0); + + /* normalize */ + preShift = norm_s(mantissa); + + e = sub(*exponent, preShift); + mantissa = shl(mantissa, preShift); + + /* calc mantissa */ + mantissa = ISqrt16_common(mantissa, e); + + /* e = (2 - e) >> 1 */ + *exponent = msu_r(1L << 15, e, 1 << 14); move16(); + + return mantissa; +} + +Word16 Inv16_lc3plus( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +) +{ + Word16 index, frac; + Word16 preShift; + Word16 m, e; + + assert(mantissa != 0); + + /* absolute */ + m = abs_s(s_max(mantissa, MIN_16 + 1)); + + /* normalize */ + preShift = norm_s(m); + + e = sub(*exponent, preShift); + m = shl(m, preShift); + + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), m, 1 << 6); + + /* get fractional part for interpolation (lower 9 bits) */ + frac = shl(s_and(m, 0x1FF), 1); /* Q10 */ + + /* interpolate */ + m = msu_r(InvTable_lc3plus[index], InvDiffTable_lc3plus[index], frac); + + /* restore sign */ + if (mantissa < 0) + m = negate(m); + + /* e = 1 - e */ + *exponent = sub(1, e); move16(); + + return m; +} + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x +*/ + +Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */ + const Word16 *x, /* i: array containing 16-bit data */ + const Word16 len_x) /* i: length of the array to scan */ +{ + Counter i; + Word16 i_min, i_max; + Word16 x_min, x_max; + + x_max = 0; move16(); + x_min = 0; move16(); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = s_max(x_max, x[i]); + if (x[i] < 0) + x_min = s_min(x_min, x[i]); + } + + i_max = 0x10; move16(); + i_min = 0x10; move16(); + + if (x_max != 0) + i_max = norm_s(x_max); + + if (x_min != 0) + i_min = norm_s(x_min); + + i = s_and(s_min(i_max, i_min), 0xF); + + return i; +} + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 16 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x +*/ + +Word16 getScaleFactor16_0( /* o: measured headroom in range [0..15], 16 if all x[i] == 0 */ + const Word16 *x, /* i: array containing 16-bit data */ + const Word16 len_x) /* i: length of the array to scan */ +{ + Counter i; + Word16 i_min, i_max; + Word16 x_min, x_max; + + x_max = 0; move16(); + x_min = 0; move16(); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = s_max(x_max, x[i]); + if (x[i] < 0) + x_min = s_min(x_min, x[i]); + } + + i_max = 0x10; move16(); + i_min = 0x10; move16(); + + if (x_max != 0) + i_max = norm_s(x_max); + + if (x_min != 0) + i_min = norm_s(x_min); + + i = s_min(i_max, i_min); + + return i; +} + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x +*/ + +Word16 getScaleFactor32_lc3plus( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x) /* i: length of the array to scan */ +{ + Counter i; + Word16 i_min, i_max; + Word32 x_min, x_max; + + x_max = L_add(0, 0); + x_min = L_add(0, 0); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = L_max(x_max, x[i]); + if (x[i] < 0) + x_min = L_min(x_min, x[i]); + } + + i_max = 0x20; move16(); + i_min = 0x20; move16(); + + if (x_max != 0) + i_max = norm_l(x_max); + + if (x_min != 0) + i_min = norm_l(x_min); + + i = s_and(s_min(i_max, i_min), 0x1F); + + return i; +} + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 32 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x +*/ + +Word16 getScaleFactor32_0( /* o: measured headroom in range [0..31], 32 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x) /* i: length of the array to scan */ +{ + Counter i; + Word16 i_min, i_max; + Word32 x_min, x_max; + + x_max = L_add(0, 0); + x_min = L_add(0, 0); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = L_max(x_max, x[i]); + if (x[i] < 0) + x_min = L_min(x_min, x[i]); + } + + i_max = 0x20; move16(); + i_min = 0x20; move16(); + + if (x_max != 0) + i_max = norm_l(x_max); + + if (x_min != 0) + i_min = norm_l(x_min); + + i = s_min(i_max, i_min); + + return i; +} + +Word16 BASOP_Util_Divide3216_Scale_lc3plus( /* o: result of division x/y, not normalized */ + Word32 x, /* i: numerator, signed */ + Word16 y, /* i: denominator, signed */ + Word16 *s) /* o: scaling, 0, if x==0 */ +{ + Word16 z; + Word16 sx; + Word16 sy; + Word16 sign; + + /*assert (x > (Word32)0); + assert (y >= (Word16)0);*/ + + /* check, if numerator equals zero, return zero then */ + IF (x == (Word32)0) + { + *s = 0; move16(); + + return ((Word16)0); + } + + sign = s_xor(extract_h(x), y); /* just to exor the sign bits */ + x = L_abs(L_max(x, MIN_32 + 1)); + y = abs_s(s_max(y, MIN_16 + 1)); + sx = sub(norm_l(x), 1); + x = L_shl(x, sx); + sy = norm_s(y); + y = shl(y, sy); + *s = sub(sy, sx); move16(); + + z = div_s(round_fx(x), y); + + if (sign < 0) /* if sign bits differ, negate the result */ + { + z = negate(z); + } + + return z; +} + +Word16 BASOP_Util_Divide1616_Scale_lc3plus(Word16 x, Word16 y, Word16 *s) +{ + Word16 z; + Word16 sx; + Word16 sy; + Word16 sign; + + /* assert (x >= (Word16)0); */ + assert(y != (Word16)0); + + sign = 0; move16(); + + IF (x < 0) + { + x = negate(x); + sign = s_xor(sign, 1); + } + + IF (y < 0) + { + y = negate(y); + sign = s_xor(sign, 1); + } + + IF (x == (Word16)0) + { + *s = 0; move16(); + + return ((Word16)0); + } + + sx = norm_s(x); + x = shl(x, sx); + x = shr(x, 1); + *s = sub(1, sx); move16(); + + sy = norm_s(y); + y = shl(y, sy); + *s = add(*s, sy); move16(); + + z = div_s(x, y); + + if (sign != 0) + { + z = negate(z); + } + + return z; +} + +Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e) +{ + Word32 L_tmp, L_tmp2, inc; + Word16 s, shift, tmp; + Counter i; + + shift = headroom; move16(); + + L_tmp = L_deposit_l(0); + + FOR (i = 0; i < length; i++) + { + L_tmp2 = L_sub(L_tmp, 0x40000000); + if (L_tmp2 >= 0) + shift = sub(shift, 1); + if (L_tmp2 >= 0) + L_tmp = L_shr(L_tmp, 2); + + tmp = round_fx_sat(L_shl_sat(x[i], shift)); + L_tmp = L_mac0(L_tmp, tmp, tmp); /* exponent = (1-shift*2) , Q(30+shift*2) */ + } + + /* Consider an increase of 0xfffd per sample in case that the pre-shift factor + in the acf is 1 bit higher than the shift factor estimated in this function. + This prevent overflows in the acf. */ + IF (L_tmp != 0) + { + s = norm_s(length); + inc = L_shl(Mpy_32_16_lc3plus(0x0000fffd, shl(length, s)), sub(15, s)); + L_tmp = L_add_sat(L_tmp, inc); + } + + *result_e = sub(1, shl(shift, 1)); move16(); + + return L_tmp; +} + +void Scale_sig(Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Counter i; + Word16 tmp; + IF (exp0 > 0) + { + tmp = s_min(exp0, 15); move16(); + FOR (i = 0; i < lg; i++) + { + x[i] = shl(x[i], tmp); move16(); /* saturation can occur here */ + } + return; + } + IF (exp0 < 0) + { + tmp = shl(-32768, s_max(exp0, -15)); /* we use negative to correctly represent 1.0 */ + FOR (i = 0; i < lg; i++) + { + x[i] = msu_r(0, x[i], tmp); move16(); /* msu instead of mac because factor is negative */ + } + return; + } +} + +void Copy_Scale_sig(const Word16 x[], /* i : signal to scale input Qx */ + Word16 y[], /* o : scaled signal output Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Counter i; + Word16 tmp; + + IF (exp0 == 0) + { + basop_memmove(y, x, lg * sizeof(Word16)); + + return; + } + IF (exp0 < 0) + { + tmp = shl(-32768, exp0); /* we use negative to correctly represent 1.0 */ + FOR (i = 0; i < lg; i++) + { + y[i] = msu_r(0, x[i], tmp); move16(); + } + return; + } + FOR (i = 0; i < lg; i++) + { + y[i] = shl_sat(x[i], exp0); move16(); /* saturation can occur here */ + } +} + +Word32 BASOP_Util_Add_Mant32Exp_lc3plus /*!< o: normalized result mantissa */ + (Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e, /*!< i: Exponent of 2nd operand b */ + Word16 *ptr_e) /*!< o: exponent of result */ +{ + Word32 L_tmp; + Word16 shift; + + /* Compare exponents: the difference is limited to +/- 30 + The Word32 mantissa of the operand with lower exponent is shifted right by the exponent difference. + Then, the unshifted mantissa of the operand with the higher exponent is added. The addition result + is normalized and the result represents the mantissa to return. The returned exponent takes into + account all shift operations. + */ + + if (!a_m) + a_e = add(b_e, 0); + + if (!b_m) + b_e = add(a_e, 0); + + shift = sub(a_e, b_e); + shift = s_max(-31, shift); + shift = s_min(31, shift); + if (shift < 0) + { + /* exponent of b is greater than exponent of a, shr a_m */ + a_m = L_shl(a_m, shift); + } + if (shift > 0) + { + /* exponent of a is greater than exponent of b */ + b_m = L_shr(b_m, shift); + } + a_e = add(s_max(a_e, b_e), 1); + L_tmp = L_add(L_shr(a_m, 1), L_shr(b_m, 1)); + shift = norm_l(L_tmp); + if (shift) + L_tmp = L_shl(L_tmp, shift); + if (L_tmp == 0) + a_e = add(0, 0); + if (L_tmp != 0) + a_e = sub(a_e, shift); + *ptr_e = a_e; + + return (L_tmp); +} + +Word16 BASOP_Util_Cmp_Mant32Exp_lc3plus /*!< o: flag: result of comparison */ + /* 0, if a == b */ + /* 1, if a > b */ + /* -1, if a < b */ + (Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e) /*!< i: Exponent of 2nd operand b */ + +{ + Word32 diff_m; + Word16 diff_e, shift, result; + + /* + This function compares two input parameters, both represented by a 32-bit mantissa and a 16-bit exponent. + If both values are identical, 0 is returned. + If a is greater b, 1 is returned. + If a is less than b, -1 is returned. + */ + + /* Check, if both mantissa and exponents are identical, when normalized: return 0 */ + shift = norm_l(a_m); + if (shift) + a_m = L_shl(a_m, shift); + if (shift) + a_e = sub(a_e, shift); + + shift = norm_l(b_m); + if (shift) + b_m = L_shl(b_m, shift); + if (shift) + b_e = sub(b_e, shift); + + /* align exponent, if any mantissa is zero */ + if (!a_m) + a_e = add(b_e, 0); + if (!b_m) + b_e = add(a_e, 0); + + IF (a_m > 0 && b_m < 0) + { + diff_m = 1; move16(); + } + ELSE IF (a_m<0 && b_m> 0) + { + diff_m = -1; move16(); + } + ELSE + { + diff_m = L_sub(a_m, b_m); + } + + diff_e = sub(a_e, b_e); + + test(); + IF (diff_m == 0 && diff_e == 0) + { + return 0; + } + + /* Check sign, exponent and mantissa to identify, whether a is greater b or not */ + result = sub(0, 1); + + IF (a_m >= 0) + { + /* a is positive */ + if (b_m < 0) + { + result = add(1, 0); + } + + test(); test(); test(); + if ((b_m >= 0) && ((diff_e > 0) || (diff_e == 0 && diff_m > 0))) + { + result = add(1, 0); + } + } + ELSE + { + /* a is negative */ + test(); test(); test(); + if ((b_m < 0) && ((diff_e < 0) || (diff_e == 0 && diff_m > 0))) + { + result = add(1, 0); + } + } + return result; +} + +/*----------------------------------------------------------------------------------* + * Function: Isqrt + * + * Description: + * + * The function computes 1/sqrt(x). + * The mantissa of the input value must be in the range of 1.0 > x >= 0.5. + * The computation of the inverse square root is an approach with a lookup table + * and linear interpolation. + * + * result = x * 2^x_e + * + * Parameter: + * + * x [i] mantissa (Q31) + * x_e [i/o] pointer to exponent (Q0) + * + * Return value: + * + * mantissa (Q31) + * + *----------------------------------------------------------------------------------*/ +Word32 Isqrt(Word32 x, /* mantissa */ + Word16 *x_e /* pointer to exponent */ +) +{ + Word16 s; + Word32 y; + Word32 idx; + Word32 diff; + Word16 fract; + + IF (x <= 0) + { + *x_e = 0; move16(); + return 0x7FFFFFFF; + } + + /* check if exponent is odd */ + s = s_and(*x_e, 0x0001); + + /* get table index (upper 8 bits) */ + idx = L_and(L_shr(x, (31 - 8)), 0x00000007f); + + /* get fractional part for interpolation (lower 23 bits) */ + fract = extract_h(L_shl(L_and(x, 0x007FFFFF), 8)); + + /* interpolate */ + diff = L_sub(isqrt_table[idx + 1], isqrt_table[idx]); + y = L_add(isqrt_table[idx], Mpy_32_16_lc3plus(diff, fract)); + + /* if exponent is odd apply sqrt(0.5) */ + if (s != 0) + { + y = Mpy_32_16_lc3plus(y, 0x5A82 /*0x5A827999*/); + } + + /* if exponent is odd shift 1 bit left */ + if (s != 0) + { + y = L_shl(y, s); + } + + /* change sign, shift right and add 1 to exponent (implicit exponent of isqrt_table) */ + *x_e = mac_r(32768, *x_e, -16384); move16(); + + return y; +} + +Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e) +{ + Word16 shift, tmp1, tmp2; + Word16 outInt, outFrac, out; + + assert(x >= 0); + + if (x == 0) + { + return (MIN_16); + } + + /* Scale Input */ + shift = norm_l(x); + x = L_shl(x, sub(shift, 10)); + + /* Integer part */ + outInt = shl(sub(sub(x_e, shift), 1), 9); + + /* Fractional part */ + tmp1 = mac_r(x, -33, 16384); + tmp2 = lshr(extract_l(x), 6); + outFrac = mac_r(Log2_16_table1[tmp1], Log2_16_table2[tmp1], tmp2); + + /* Output */ + out = add(outInt, outFrac); + + return out; +} + +Word16 BASOP_Util_InvLog2_16(Word16 x, Word16 *y_e) +{ + Word16 tmp1, tmp2, y; + + tmp1 = shr(s_and(x, 2047), 5); + tmp2 = shl(s_and(x, 31), 4); + y = mac_r(InvLog2_16_table1[tmp1], InvLog2_16_table2[tmp1], tmp2); + *y_e = add(shr_pos(x, 11), 1); + + return y; +} + +#ifdef ENABLE_HR_MODE +#define DFRACT_BITS 32 /* double precision */ + +#define SQRT_BITS 7 +#define SQRT_BITS_MASK 0x7f +#define SQRT_FRACT_BITS_MASK 0x007FFFFF + +#ifndef Word64 +#define Word64 long long +#endif + +static __inline Word32 Mpy_32_32_noshift(Word32 x1, Word32 x2) +{ + Word64 ret = 0; + ret = ((Word64)x1 * (Word64)x2); + return ((Word32)((ret & (Word64)0xffffffff00000000) >> 32)); +} + +static __inline Word32 fixmadddiv2_DD(const Word32 x, const Word32 a, const Word32 b) +{ + return ((((Word64)x << 32) + (Word64)a * b) >> 32); +} + +/** + * \brief calculate 1.0/sqrt(op) + * \param op_m mantissa of input value. + * \param result_e pointer to return the exponent of the result + * \return mantissa of the result + */ +/***************************************************************************** + delivers 1/sqrt(op) normalized to .5...1 and the shift value of the OUTPUT, + i.e. the denormalized result is 1/sqrt(op) = invSqrtNorm(op) * 2^(shift) + uses Newton-iteration for approximation + Q(n+1) = Q(n) + Q(n) * (0.5 - 2 * V * Q(n)^2) + with Q = 0.5* V ^-0.5; 0.5 <= V < 1.0 +*****************************************************************************/ +static __inline Word32 invSqrtNorm2(Word32 op, Word32 *shift) +{ + Word32 val = op; + Word32 reg1, reg2; + + if (val == 0) + { + *shift = 16; + return ((Word32)0x7FFFFFFF); /* maximum positive value */ + } + +/* #define INVSQRTNORM2_NEWTON_ITERATE */ +#define INVSQRTNORM2_LINEAR_INTERPOLATE +#define INVSQRTNORM2_LINEAR_INTERPOLATE_HQ + + /* normalize input, calculate shift value */ + assert(val > 0); + *shift = norm_l(val); /* CountLeadingBits() is not necessary here since test value is always > 0 */ + val <<= *shift; /* normalized input V */ + *shift += 2; /* bias for exponent */ + +#if defined(INVSQRTNORM2_NEWTON_ITERATE) + /* Newton iteration of 1/sqrt(V) */ + reg1 = invSqrtTab[(Word32)(val >> (DFRACT_BITS - 1 - (SQRT_BITS + 1))) & SQRT_BITS_MASK]; + reg2 = FL2FXCONST_DBL(0.0625f); /* 0.5 >> 3 */ + + Word32 regtmp = fPow2Div2(reg1); /* a = Q^2 */ + regtmp = reg2 - fMultDiv2(regtmp, val); /* b = 0.5 - 2 * V * Q^2 */ + reg1 += (fMultDiv2(regtmp, reg1) << 4); /* Q = Q + Q*b */ +#elif defined(INVSQRTNORM2_LINEAR_INTERPOLATE) + Word32 index = (Word32)(val >> (DFRACT_BITS - 1 - (SQRT_BITS + 1))) & SQRT_BITS_MASK; + Word32 Fract = (Word32)(((Word32)val & SQRT_FRACT_BITS_MASK) << (SQRT_BITS + 1)); + Word32 diff = invSqrtTab[index + 1] - invSqrtTab[index]; + reg1 = invSqrtTab[index] + (Word32)(((UWord32)(Mpy_32_32_noshift(diff, Fract)) << 1)); +#if defined(INVSQRTNORM2_LINEAR_INTERPOLATE_HQ) + /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ... + + (1-fract)fract*(t[i+2]-t[i+1])/2 */ + if (Fract != (Word32)0) + { + /* fract = fract * (1 - fract) */ + Fract = Mpy_32_32_noshift(Fract, (Word32)((UWord32)0x80000000 - (Word32)Fract)) << 1; + diff = diff - (invSqrtTab[index + 2] - invSqrtTab[index + 1]); + reg1 = fixmadddiv2_DD(reg1, Fract, diff); + } +#endif /* INVSQRTNORM2_LINEAR_INTERPOLATE_HQ */ +#else +#error "Either define INVSQRTNORM2_NEWTON_ITERATE or INVSQRTNORM2_LINEAR_INTERPOLATE" +#endif + /* calculate the output exponent = input exp/2 */ + if (*shift & 0x00000001) + { /* odd shift values ? */ + /* Note: Do not use rounded value 0x5A82799A to avoid overflow with shift-by-2 */ + reg2 = (Word32)0x5A827999; /* FL2FXCONST_DBL(0.707106781186547524400844362104849f);*/ /* 1/sqrt(2); */ +#ifdef __ADSP21000__ + reg1 = fMult(reg1, reg2) << 1; /* compiler bug work around (CCES 2.4.0), and better precision */ +#else + reg1 = Mpy_32_32_noshift(reg1, reg2) << 2; +#endif + } + + *shift = *shift >> 1; + + return (reg1); +} + +/** + * \brief calculate 1.0/(op_m * 2^op_e) + * \param op_m mantissa of the input value. + * \param op_e pointer into were the exponent of the input value is stored, and the result will be stored into. + * \return mantissa of the result + */ +Word32 invFixp(Word32 op_m, Word16 *op_e) +{ + if ((op_m == (Word32)0x00000000) || (op_m == (Word32)0x00000001)) + { + *op_e = 31 - *op_e; + return ((Word32)0x7FFFFFFF); + } + + Word32 tmp_exp; + Word32 tmp_inv = invSqrtNorm2(op_m, &tmp_exp); + + *op_e = (tmp_exp << 1) - *op_e + 1; + return Mpy_32_32_noshift(tmp_inv, tmp_inv); +} +#endif diff --git a/lib_lc3plus/basop_util_lc3plus.h b/lib_lc3plus/basop_util_lc3plus.h new file mode 100644 index 000000000..99bc211a9 --- /dev/null +++ b/lib_lc3plus/basop_util_lc3plus.h @@ -0,0 +1,377 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef __BASOP_UTIL_LC3PLUS_H__ +#define __BASOP_UTIL_LC3PLUS_H__ + +#include "defines.h" +#include "functions.h" +#include +#include + +#define _LONG long +#define _SHORT short +#ifdef _WIN32 +#define _INT64 __int64 +#else +#define _INT64 long long +#endif + +#define WORD32_BITS 32 +#define MAXVAL_WORD32 ((signed)0x7FFFFFFF) +#define MINVAL_WORD32 ((signed)0x80000000) +#define WORD32_FIX_SCALE ((_INT64)(1) << (WORD32_BITS - 1)) + +#define WORD16_BITS 16 +#define MAXVAL_WORD16 (((signed)0x7FFFFFFF) >> 16) +#define MINVAL_WORD16 (((signed)0x80000000) >> 16) +#define WORD16_FIX_SCALE ((_INT64)(1) << (WORD16_BITS - 1)) + +/*! + \def Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation +*/ +#define WORD322WORD16(val) \ + ((((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) > (((_LONG)1 << WORD16_BITS) - 1)) && ((_LONG)(val) > 0)) \ + ? (Word16)(_SHORT)(((_LONG)1 << (WORD16_BITS - 1)) - 1) \ + : (Word16)(_SHORT)((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) >> 1)) + + +/* Word16 Packed Type */ +typedef struct +{ + struct + { + Word16 re; + Word16 im; + } v; +} PWord16; + +#ifdef ENABLE_HR_MODE +/* Word32 Packed Type */ +typedef struct +{ + struct + { + Word32 re; + Word32 im; + } v; +} PWord32; +#endif + +#define cast16 move16 + +#define LD_DATA_SCALE (6) +#define LD_DATA_SHIFT_I5 (7) + +/************************************************************************/ +/*! + \brief Calculate the squareroot of a number given by mantissa and exponent + + Mantissa is in 16/32-bit-fractional format with values between 0 and 1.
+ For *norm versions mantissa has to be between 0.5 and 1.
+ The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ The exponent is addressed via pointers and will be overwritten with the result. +*/ + +Word16 Sqrt16_lc3plus( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +); + +Word16 ISqrt16( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +); + +/*****************************************************************************/ +/*! + \brief Calculate the inverse of a number given by mantissa and exponent + + Mantissa is in 16-bit-fractional format with values between 0 and 1.
+ The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ The operand is addressed via pointers and will be overwritten with the result. + + The function uses a table lookup and a newton iteration. +*/ +Word16 Inv16_lc3plus( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +); + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x +*/ + +Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */ + const Word16 *x, /* i: array containing 16-bit data */ + const Word16 len_x); /* i: length of the array to scan */ + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 16 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x +*/ + +Word16 getScaleFactor16_0( /* o: measured headroom in range [0..15], 16 if all x[i] == 0 */ + const Word16 *x, /* i: array containing 16-bit data */ + const Word16 len_x); /* i: length of the array to scan */ + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x +*/ + +Word16 getScaleFactor32_lc3plus( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x); /* i: length of the array to scan */ + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 32 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x +*/ + +Word16 getScaleFactor32_0( /* o: measured headroom in range [0..31], 32 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x); /* i: length of the array to scan */ + +/****************************************************************************/ +/*! + \brief Does fractional integer division of Word32 arg1 by Word16 arg2 + + + \return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized +*/ +Word16 BASOP_Util_Divide3216_Scale_lc3plus(Word32 x, /*!< i : Numerator */ + Word16 y, /*!< i : Denominator*/ + Word16 *s); /*!< o : Additional scalefactor difference*/ + +/****************************************************************************/ +/*! + \brief Does fractional division of Word16 arg1 by Word16 arg2 + + + \return fractional Q15 Word16 z = arg1(Q15)/arg2(Q15) with scaling s +*/ +Word16 BASOP_Util_Divide1616_Scale_lc3plus(Word16 x, /*!< i : Numerator*/ + Word16 y, /*!< i : Denominator*/ + Word16 *s); /*!< o : Additional scalefactor difference*/ + +/************************************************************************/ +/*! + \brief Binary logarithm with 7 iterations + + \param x + + \return log2(x)/64 + */ +/************************************************************************/ +Word32 BASOP_Util_Log2_lc3plus(Word32 x); + +/************************************************************************/ +/*! + \brief Binary power + + Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen + + Version with 3 table lookup and 1 linear interpolations + + Algorithm: compute power of 2, argument x is in Q7.25 format + result = 2^(x/64) + We split exponent (x/64) into 5 components: + integer part: represented by b31..b25 (exp) + fractional part 1: represented by b24..b20 (lookup1) + fractional part 2: represented by b19..b15 (lookup2) + fractional part 3: represented by b14..b10 (lookup3) + fractional part 4: represented by b09..b00 (frac) + => result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp + + Due to the fact, that all lookup values contain a factor 0.5 + the result has to be shifted by 3 to the right also. + Table exp2_tab_long_lc3plus contains the log2 for 0 to 1.0 in steps + of 1/32, table exp2w_tab_long_lc3plus the log2 for 0 to 1/32 in steps + of 1/1024, table exp2x_tab_long_lc3plus the log2 for 0 to 1/1024 in + steps of 1/32768. Since the 2-logarithm of very very small + negative value is rather linear, we can use interpolation. + + Limitations: + + For x <= 0, the result is fractional positive + For x > 0, the result is integer in range 1...7FFF.FFFF + For x < -31/64, we have to clear the result + For x = 0, the result is ~1.0 (0x7FFF.FFFF) + For x >= 31/64, the result is 0x7FFF.FFFF + + \param x + + \return pow(2,(x/64)) + */ +/************************************************************************/ +Word32 BASOP_Util_InvLog2_lc3plus(Word32 x); + +#ifdef ENABLE_HR_MODE +/* New function which works with positive x, BASOP_Util_InvLog2_lc3plus does not give + accurate results for x > 0 */ +Word32 BASOP_Util_InvLog2_pos(Word32 x, Word16 *exp); +#endif + +/** + * \brief Compute dot product of 1 32 bit vectors with itself + * \param x input vector 1 + * \param headroom amount of headroom bits the input vector + * \param length the length of the input vector + * \param result_e pointer to where the exponent of the result will be stored into + * \return the dot product of x and x. + */ +Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e); + +/*!********************************************************************** + \brief Add two values given by mantissa and exponent. + + Mantissas are in 32-bit-fractional format with values between 0 and 1.
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ +************************************************************************/ +Word32 BASOP_Util_Add_Mant32Exp_lc3plus /*!< o: normalized result mantissa */ + (Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e, /*!< i: Exponent of 2nd operand b */ + Word16 *ptr_e); /*!< o: exponent of result */ + /*!********************************************************************** + \brief Returns the comparison result of two normalized values given by mantissa and exponent. + return value: -1: a < b, 0: a == b, 1; a > b + + Mantissas are in 32-bit-fractional format with values between 0 and 1.
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ + ************************************************************************/ +Word16 BASOP_Util_Cmp_Mant32Exp_lc3plus /*!< o: flag: result of comparison */ + (Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e); /*!< i: Exponent of 2nd operand b */ + +/* compare two positive normalized 16 bit mantissa/exponent values */ +/* return value: positive if first value greater, negative if second value greater, zero if equal */ +Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2); + +void Scale_sig(Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); +void Copy_Scale_sig(const Word16 x[], /* i : signal to scale input Qx */ + Word16 y[], /* o : scaled signal output Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); + +#ifdef ENABLE_HR_MODE +void Copy_Scale_sig_32(const Word32 x[], /* i : signal to scale input Qx */ + Word16 y[], /* o : scaled signal output Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); +#endif + +Word32 Isqrt(Word32 x, /* (i) Q31: normalized value (1.0 > x >= 0.5) */ + Word16 *x_e /* (i/o) Q0 : pointer to exponent */ +); + +Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e); + +Word16 BASOP_Util_InvLog2_16(Word16 x, Word16 *y_e); + +#ifdef ENABLE_HR_MODE +Word32 invFixp(Word32 op_m, Word16 *op_e); +#endif + +#define BASOP_CFFT_MAX_LENGTH 480 +void BASOP_cfft_lc3plus(Word32 *re, Word32 *im, Word16 sizeOfFft, Word16 s, Word16 *scale, Word32 *x); +void BASOP_rfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer); +void BASOP_irfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer); + +#if WMOPS +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif + +static __inline void basop_memcpy(void *dst, const void *src, size_t n) +{ +#if WMOPS + multiCounter[currCounter].move16 += (UWord32)n / 2; +#endif + /* check for overlapping memory */ + assert((const char *)src + n <= (char *)dst || (char *)dst + n <= (const char *)src); + memcpy(dst, src, n); +} + +static __inline void basop_memmove(void *dst, const void *src, size_t n) +{ +#if WMOPS + multiCounter[currCounter].move16 += (UWord32)n / 2; +#endif + memmove(dst, src, n); +} + +static __inline void basop_memset(void *dst, int val, size_t n) +{ +#if WMOPS + multiCounter[currCounter].move16 += (UWord32)n / 2; +#endif + memset(dst, val, n); +} + +/* Macros around Dyn_Mem that don't require duplicate declarations. */ +#ifdef DYNMEM_COUNT +/* older visual studio doesn't have __func__ */ +#if defined _MSC_VER && _MSC_VER < 1900 +#define __func__ __FUNCTION__ +#endif +#define Dyn_Mem_Deluxe_In(...) __VA_ARGS__ Dyn_Mem_In(__func__, sizeof(struct {__VA_ARGS__})) +#define Dyn_Mem_Deluxe_Out() Dyn_Mem_Out() +#else +#define Dyn_Mem_Deluxe_In(...) __VA_ARGS__ +#define Dyn_Mem_Deluxe_Out() +#endif + +/* Macros missing from IVAS BASOP, used only in LC3plus */ +#define L_shl_pos(x, y) (L_shl((x), (y))) +#define L_shr_pos(x, y) (L_shr((x), (y))) +#define L_shr_pos_pos(x, y) (L_shr((x), (y))) + +#define L_shr_r_pos(x, shift) (L_shr_r(x, shift)) + +#define shl_pos(x, y) (shl((x), (y))) +#define shr_pos(x, y) (shr((x), (y))) +#define shr_pos_pos(x, y) (shr((x), (y))) + +#define lshl_pos(x, y) (lshl(x, y)) +#define UL_lshr_pos(x, y) (UL_lshr(x, y)) +#define UL_lshl_pos(x, y) (UL_lshl(x, y)) +#endif /* __BASOP_UTIL_LC3PLUS_H__ */ diff --git a/lib_lc3plus/clib.h b/lib_lc3plus/clib.h deleted file mode 100644 index 44e70de78..000000000 --- a/lib_lc3plus/clib.h +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#ifndef CLIB_H -#define CLIB_H - -#include "options.h" -#include "wmc_auto.h" -#include -#include -#include -#include -#include -#include -#include -#ifndef _MSC_VER -#include "strings.h" -#else -#include -#endif - -#endif diff --git a/lib_lc3plus/constants.c b/lib_lc3plus/constants.c index 3709a3f5a..c13c4e49e 100644 --- a/lib_lc3plus/constants.c +++ b/lib_lc3plus/constants.c @@ -1,68 +1,3018 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -/* DCT */ -#define ENTRY_DCT2_1 {0.353553, 0.000000} -#define ENTRY_DCT2_2 {0.351851, -0.034654} -#define ENTRY_DCT2_3 {0.346760, -0.068975} -#define ENTRY_DCT2_4 {0.338329, -0.102631} -#define ENTRY_DCT2_5 {0.326641, -0.135299} -#define ENTRY_DCT2_6 {0.311806, -0.166664} -#define ENTRY_DCT2_7 {0.293969, -0.196424} -#define ENTRY_DCT2_8 {0.273300, -0.224292} -#define ENTRY_DCT2_9 {0.250000, -0.250000} -#define ENTRY_DCT2_10 {0.224292, -0.273300} -#define ENTRY_DCT2_11 {0.196424, -0.293969} -#define ENTRY_DCT2_12 {0.166664, -0.311806} -#define ENTRY_DCT2_13 {0.135299, -0.326641} -#define ENTRY_DCT2_14 {0.102631, -0.338329} -#define ENTRY_DCT2_15 {0.068975, -0.346760} -#define ENTRY_DCT2_16 {0.034654, -0.351851} - -const Complex dct2_16[16] = { -ENTRY_DCT2_1, -ENTRY_DCT2_2, -ENTRY_DCT2_3, -ENTRY_DCT2_4, -ENTRY_DCT2_5, -ENTRY_DCT2_6, -ENTRY_DCT2_7, -ENTRY_DCT2_8, -ENTRY_DCT2_9, -ENTRY_DCT2_10, -ENTRY_DCT2_11, -ENTRY_DCT2_12, -ENTRY_DCT2_13, -ENTRY_DCT2_14, -ENTRY_DCT2_15, -ENTRY_DCT2_16 + +#include "basop_util_lc3plus.h" +#include "constants.h" +#include "defines.h" + +#ifdef ENABLE_HR_MODE + +#ifdef CR8_G_ADD_75MS +const Word32 LowDelayShapes_n960_N480_HRA_7_5ms_IP[720] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 87, 348, 823, 1614, 2855, 4711, + 7394, 11166, 16346, 23325, 32567, 44630, 60168, 79951, 104871, + 135960, 174404, 221554, 278944, 348306, 431580, 530938, 648792, 787807, + 950923, 1141360, 1362631, 1618557, 1913273, 2251235, 2637225, 3076358, 3574079, + 4136163, 4768712, 5478142, 6271180, 7154844, 8136428, 9223482, 10423785, 11745317, + 13196231, 14784811, 16519438, 18408546, 20460576, 22683925, 25086898, 27677652, 30464139, + 33454048, 36654744, 40073208, 43715977, 47589078, 51697972, 56047490, 60641775, 65484225, + 70577443, 75923181, 81522294, 87374702, 93479345, 99834159, 106436041, 113280836, 120363317, + 127677184, 135215062, 142968508, 150928157, 159083617, 167423428, 175935264, 184605929, 193421420, + 202366999, 211427267, 220586253, 229827503, 239134176, 248489151, 257875132, 267274759, 276670727, + 286045896, 295383416, 304666842, 313880253, 323008369, 332036665, 340951481, 349740127, 358390986, + 366893607, 375238791, 383418672, 391426786, 399258131, 406909219, 414378115, 421664463, 428769507, + 435696092, 442448656, 449033209, 455457302, 461729975, 467861704, 473864325, 479750954, 485535888, + 491234502, 496863130, 502438943, 507979811, 513504165, 519030849, 524578969, 530167737, 535816319, + 541543674, 547368406, 553308608, 559381722, 565604392, 571992342, 578560249, 585321630, 592288748, + 599472521, 606882448, 614526549, 622411321, 630541701, 638921050, 647551149, 656432204, 665562870, + 674940281, 684560092, 694416534, 704502476, 714809492, 725327938, 736047035, 746954953, 758038900, + 769285219, 780679474, 792206554, 803850758, 815595897, 827425384, 839322323, 851269604, 863249984, + 875246176, 887240926, 899217093, 911157723, 923046119, 934865908, 946601106, 958236175, 969756079, + 981146337, 992393068, 1003483035, 1014403685, 1025143183, 1035690443, 1046035156, 1056167806, 1066079698, + 1075762962, 1085210568, 1094416328, 1103374896, 1112081767, 1120533266, 1128726537, 1136659525, 1144330955, + 1151740310, 1158887799, 1165774327, 1172401460, 1178771388, 1184886881, 1190751250, 1196368299, 1201742283, + 1206877859, 1211780040, 1216454151, 1220905777, 1225140726, 1229164983, 1232984668, 1236606003, 1240035271, + 1243278790, 1246342881, 1249233843, 1251957932, 1254521342, 1256930191, 1259190506, 1261308214, 1263289136, + 1265138979, 1266863333, 1268467669, 1269957337, 1271337562, 1272613448, 1273789972, 1274871989, 1275864224, + 1276771276, 1277597614, 1278347576, 1279025364, 1279635046, 1280180548, 1280665658, 1281094017, 1281469123, + 1281794327, 1282072831, 1282307692, 1282501820, 1282657982, 1282778803, 1282866770, 1282924240, 1282953439, + 1282956475, 1282935340, 1282891922, 1282828007, 1282745290, 1282645385, 1282529830, 1282400095, 1282257591, + 1282103675, 1281939658, 1281766811, 1281586369, 1281399536, 1281207489, 1281011380, 1280812338, 1280611471, + 1280409867, 1280208592, 1280008692, 1279811190, 1279617083, 1279427343, 1279242908, 1279064691, 1278893575, + 1278730391, 1278575934, 1278430953, 1278296152, 1278172183, 1278059646, 1277959085, 1277870984, 1277795766, + 1277733793, 1277685360, 1277650698, 1277629970, 1277623272, 1277630630, 1277652006, 1277687290, 1277736307, + 1277798815, 1277874509, 1277963018, 1278063911, 1278176696, 1278300826, 1278435697, 1278580655, 1278734998, + 1278897977, 1279068803, 1279246650, 1279430656, 1279619930, 1279813555, 1280010596, 1280210097, 1280411091, + 1280612606, 1280813664, 1281013290, 1281210515, 1281404382, 1281593947, 1281778291, 1281956514, 1282127749, + 1282291161, 1282445951, 1282591364, 1282726688, 1282851259, 1282964467, 1283065755, 1283154623, 1283230634, + 1283293412, 1283342644, 1283378085, 1283399556, 1283406948, 1283400219, 1283379398, 1283344582, 1283295937, + 1283233697, 1283158163, 1283069704, 1282968748, 1282855789, 1282731378, 1282596123, 1282450686, 1282295780, + 1282132162, 1281960636, 1281782040, 1281597253, 1281407178, 1281212748, 1281014916, 1280814653, 1280612938, + -1280410760, -1280209108, -1280008970, -1279811325, -1279617137, -1279427356, -1279242908, -1279064691, -1278893575, + -1278730391, -1278575934, -1278430953, -1278296152, -1278172183, -1278059646, -1277959085, -1277870984, -1277795766, + -1277733793, -1277685360, -1277650698, -1277629970, -1277623272, -1277630630, -1277652006, -1277687290, -1277736307, + -1277798815, -1277874509, -1277963018, -1278063911, -1278176696, -1278300826, -1278435697, -1278580655, -1278734998, + -1278897977, -1279068803, -1279246650, -1279430656, -1279619930, -1279813555, -1280010596, -1280210097, -1280411091, + -1280612606, -1280813664, -1281013290, -1281210515, -1281404382, -1281593947, -1281778291, -1281956514, -1282127749, + -1282291161, -1282445951, -1282591364, -1282726688, -1282851259, -1282964467, -1283065755, -1283154623, -1283230634, + -1283293412, -1283342644, -1283378085, -1283399556, -1283406948, -1283400219, -1283379398, -1283344582, -1283295937, + -1283233697, -1283158163, -1283069704, -1282968748, -1282855789, -1282731378, -1282596123, -1282450686, -1282295780, + -1282132162, -1281960636, -1281782040, -1281597240, -1281407124, -1281212613, -1281014638, -1280814136, -1280612044, + -1280409293, -1280206794, -1280005436, -1279806071, -1279609505, -1279416489, -1279227704, -1279043754, -1278865148, + -1278692290, -1278525466, -1278364827, -1278210380, -1278061967, -1277919259, -1277781732, -1277648661, -1277519103, + -1277391882, -1277265579, -1277138516, -1277008749, -1276874050, -1276731906, -1276579498, -1276413701, -1276231074, + -1276027848, -1275799922, -1275542858, -1275251868, -1274921816, -1274547202, -1274122161, -1273640454, -1273095459, + -1272480163, -1271787153, -1271008605, -1270136275, -1269161491, -1268075138, -1266867650, -1265529002, -1264048705, + -1262415795, -1260618834, -1258645914, -1256484654, -1254122219, -1251545330, -1248740288, -1245693001, -1242389021, + -1238813588, -1234951678, -1230788064, -1226307382, -1221494200, -1216333106, -1210808785, -1204906119, -1198610276, + -1191906816, -1184781789, -1177221841, -1169214319, -1160747375, -1151810067, -1142392460, -1132485722, -1122082216, + -1111175584, -1099760832, -1087834398, -1075394224, -1062439811, -1048972272, -1034994376, -1020510578, -1005527053, + -990051705, -974094182, -957665874, -940779904, -923451116, -905696046, -887532891, -868981469, -850063169, + -830800896, -811219007, -791343239, -771200631, -750819438, -730229039, -709459838, -688543157, -667511126, + -646396563, -625232849, -604053802, -582893543, -561786350, -540766526, -519868245, -499125406, -478571481, + -458239366, -438161227, -418368350, -398890991, -379758233, -360997846, -342636148, -324697881, -307206093, + -290182024, -273645013, -257612410, -242099504, -227119464, -212683299, -198799827, -185475666, -172715241, + -160520802, -148892465, -137828265, -127324223, -117374432, -107971150, -99104909, -90764635, -82937772, + -75610419, -68767471, -62392760, -56469205, -50978959, -45903556, -41224052, -36921169, -32975429, + -29367284, -26077235, -23085950, -20374365, -17923784, -15715959, -13733175, -11958308, -10374886, + -8967135, -7720017, -6619257, -5651362, -4803637, -4064184, -3421902, -2866477, -2388368, + -1978789, -1629681, -1333688, -1084125, -874947, -700710, -556540, -438092, -341515, + -263414, -200812, -151118, -112086, -81786, -58572, -41046, -28035, -18564, + -11827, -7166, -4052, -2065, -873, -219, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const Word32 LowDelayShapes_n960_N960_HRA_7_5ms_IP[1440] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 44, 108, 200, + 327, 496, 716, 997, 1352, 1793, 2334, 2993, 3788, + 4740, 5873, 7210, 8782, 10618, 12754, 15228, 18079, 21354, + 25102, 29375, 34232, 39736, 45954, 52960, 60833, 69657, 79523, + 90531, 102783, 116393, 131479, 148170, 166600, 186913, 209263, 233812, + 260731, 290202, 322417, 357578, 395898, 437601, 482924, 532113, 585429, + 643144, 705541, 772919, 845587, 923872, 1008108, 1098650, 1195861, 1300121, + 1411824, 1531379, 1659208, 1795748, 1941453, 2096787, 2262233, 2438287, 2625458, + 2824273, 3035270, 3259002, 3496037, 3746956, 4012353, 4292837, 4589026, 4901555, + 5231067, 5578220, 5943680, 6328125, 6732242, 7156730, 7602292, 8069643, 8559503, + 9072598, 9609661, 10171429, 10758643, 11372046, 12012385, 12680404, 13376850, 14102468, + 14858000, 15644185, 16461757, 17311444, 18193967, 19110038, 20060361, 21045626, 22066514, + 23123691, 24217808, 25349499, 26519382, 27728053, 28976092, 30264055, 31592472, 32961855, + 34372684, 35825415, 37320475, 38858262, 40439142, 42063449, 43731482, 45443509, 47199758, + 49000423, 50845659, 52735581, 54670266, 56649748, 58674020, 60743031, 62856690, 65014857, + 67217351, 69463943, 71754359, 74088280, 76465337, 78885116, 81347157, 83850949, 86395935, + 88981513, 91607029, 94271785, 96975035, 99715986, 102493800, 105307656, 108156591, 111039641, + 113955799, 116904014, 119883198, 122892222, 125929920, 128995090, 132086493, 135202860, 138342888, + 141505243, 144688567, 147891470, 151112543, 154350350, 157603439, 160870336, 164149553, 167439589, + 170738931, 174046055, 177359434, 180677535, 183998823, 187321766, 190644834, 193966503, 197285258, + 200599596, 203908028, 207209080, 210501300, 213783255, 217053539, 220310770, 223553598, 226780705, + 229990806, 233182654, 236355043, 239506805, 242636819, 245744010, 248827351, 251885864, 254918626, + 257924767, 260903473, 263853991, 266775622, 269667734, 272529755, 275361176, 278161556, 280930518, + 283667753, 286373022, 289046153, 291687043, 294295661, 296872047, 299416309, 301928628, 304409254, + 306858511, 309276789, 311664551, 314022327, 316350717, 318650389, 320922075, 323166575, 325384751, + 327577531, 329745900, 331890905, 334013649, 336115291, 338197045, 340260173, 342305990, 344335852, + 346351165, 348353370, 350343952, 352324427, 354296346, 356261288, 358220860, 360176691, 362130431, + 364083745, 366038312, 367995821, 369957968, 371926451, 373902968, 375889214, 377886876, 379897629, + 381923135, 383965040, 386024966, 388104513, 390205254, 392328729, 394476448, 396649881, 398850460, + 401079575, 403338572, 405628746, 407951345, 410307564, 412698544, 415125367, 417589059, 420090585, + 422630847, 425210685, 427830873, 430492120, 433195067, 435940288, 438728287, 441559502, 444434298, + 447352971, 450315749, 453322788, 456374176, 459469929, 462609996, 465794259, 469022529, 472294553, + 475610011, 478968518, 482369626, 485812825, 489297542, 492823148, 496388953, 499994212, 503638125, + 507319839, 511038449, 514793004, 518582502, 522405897, 526262100, 530149980, 534068367, 538016053, + 541991796, 545994319, 550022317, 554074452, 558149362, 562245659, 566361935, 570496756, 574648675, + 578816224, 582997925, 587192283, 591397795, 595612950, 599836228, 604066106, 608301058, 612539556, + 616780072, 621021084, 625261070, 629498515, 633731914, 637959769, 642180591, 646392905, 650595252, + 654786183, 658964269, 663128098, 667276277, 671407434, 675520217, 679613298, 683685373, 687735163, + 691761414, 695762900, 699738424, 703686816, 707606936, 711497676, 715357958, 719186737, 722983000, + 726745768, 730474096, 734167073, 737823824, 741443507, 745025319, 748568492, 752072293, 755536028, + 758959039, 762340704, 765680440, 768977700, 772231975, 775442794, 778609720, 781732356, 784810341, + 787843351, 790831096, 793773326, 796669823, 799520406, 802324927, 805083276, 807795372, 810461171, + 813080658, 815653853, 818180806, 820661596, 823096332, 825485155, 827828229, 830125749, 832377934, + 834585028, 836747302, 838865047, 840938578, 842968232, 844954366, 846897354, 848797592, 850655491, + 852471478, 854245997, 855979505, 857672472, 859325380, 860938723, 862513004, 864048738, 865546444, + 867006653, 868429898, 869816720, 871167666, 872483283, 873764126, 875010749, 876223709, 877403563, + 878550870, 879666189, 880750077, 881803089, 882825781, 883818705, 884782410, 885717445, 886624352, + 887503671, 888355939, 889181688, 889981445, 890755734, 891505074, 892229977, 892930955, 893608509, + 894263138, 894895337, 895505593, 896094389, 896662203, 897209507, 897736768, 898244447, 898733000, + 899202877, 899654523, 900088379, 900504877, 900904447, 901287510, 901654485, 902005783, 902341811, + 902662967, 902969647, 903262240, 903541129, 903806691, 904059297, 904299312, 904527095, 904742999, + 904947372, 905140554, 905322879, 905494676, 905656265, 905807964, 905950080, 906082916, 906206768, + 906321926, 906428673, 906527284, 906618032, 906701178, 906776980, 906845690, 906907551, 906962802, + 907011675, 907054396, 907091185, 907122257, 907147818, 907168073, 907183217, 907193443, 907198938, + 907199882, 907196451, 907188818, 907177150, 907161608, 907142351, 907119533, 907093305, 907063813, + 907031199, 906995603, 906957162, 906916008, 906872273, 906826083, 906777563, 906726837, 906674025, + 906619245, 906562613, 906504244, 906444251, 906382745, 906319835, 906255629, 906190236, 906123759, + 906056304, 905987975, 905918873, 905849099, 905778755, 905707939, 905636751, 905565287, 905493644, + 905421918, 905350204, 905278596, 905207187, 905136068, 905065331, 904995065, 904925359, 904856301, + 904787977, 904720472, 904653870, 904588254, 904523701, 904460295, 904398114, 904337234, 904277728, + 904219670, 904163129, 904108175, 904054874, 904003290, 903953487, 903905525, 903859462, 903815353, + 903773252, 903733209, 903695274, 903659492, 903625906, 903594557, 903565482, 903538716, 903514291, + 903492237, 903472579, 903455342, 903440546, 903428208, 903418343, 903410963, 903406076, 903403687, + 903403799, 903406411, 903411521, 903419121, 903429201, 903441750, 903456751, 903474186, 903494033, + 903516269, 903540866, 903567793, 903597018, 903628506, 903662217, 903698112, 903736145, 903776272, + 903818442, 903862605, 903908708, 903956694, 904006505, 904058081, 904111359, 904166274, 904222761, + 904280750, 904340172, 904400953, 904463022, 904526303, 904590718, 904656191, 904722641, 904789988, + 904858152, 904927048, 904996594, 905066706, 905137298, 905208286, 905279583, 905351102, 905422757, + 905494462, 905566128, 905637670, 905709001, 905780033, 905850681, 905920859, 905990482, 906059464, + 906127723, 906195175, 906261739, 906327332, 906391876, 906455291, 906517501, 906578429, 906638002, + 906696146, 906752790, 906807866, 906861306, 906913045, 906963019, 907011167, 907057430, 907101752, + 907144078, 907184355, 907222535, 907258571, 907292418, 907324034, 907353381, 907380422, 907405124, + 907427456, 907447391, 907464903, 907479970, 907492575, 907502701, 907510335, 907515468, 907518092, + 907518205, 907515805, 907510896, 907503482, 907493572, 907481179, 907466317, 907449004, 907429261, + 907407111, 907382581, 907355702, 907326506, 907295028, 907261307, 907225384, 907187302, 907147109, + 907104853, 907060585, 907014361, 906966236, 906916270, 906864523, 906811060, 906755944, 906699245, + 906641031, 906581374, 906520347, 906458025, 906394483, 906329801, 906264057, 906197332, 906129707, + 906061266, 905992093, 905922271, 905851888, 905781028, 905709780, 905638230, 905566465, 905494574, + -905422645, -905350765, -905279024, -905207507, -905136304, -905065500, -904995184, -904925439, -904856352, + -904788008, -904720488, -904653877, -904588254, -904523701, -904460295, -904398114, -904337234, -904277728, + -904219670, -904163129, -904108175, -904054874, -904003290, -903953487, -903905525, -903859462, -903815353, + -903773252, -903733209, -903695274, -903659492, -903625906, -903594557, -903565482, -903538716, -903514291, + -903492237, -903472579, -903455342, -903440546, -903428208, -903418343, -903410963, -903406076, -903403687, + -903403799, -903406411, -903411521, -903419121, -903429201, -903441750, -903456751, -903474186, -903494033, + -903516269, -903540866, -903567793, -903597018, -903628506, -903662217, -903698112, -903736145, -903776272, + -903818442, -903862605, -903908708, -903956694, -904006505, -904058081, -904111359, -904166274, -904222761, + -904280750, -904340172, -904400953, -904463022, -904526303, -904590718, -904656191, -904722641, -904789988, + -904858152, -904927048, -904996594, -905066706, -905137298, -905208286, -905279583, -905351102, -905422757, + -905494462, -905566128, -905637670, -905709001, -905780033, -905850681, -905920859, -905990482, -906059464, + -906127723, -906195175, -906261739, -906327332, -906391876, -906455291, -906517501, -906578429, -906638002, + -906696146, -906752790, -906807866, -906861306, -906913045, -906963019, -907011167, -907057430, -907101752, + -907144078, -907184355, -907222535, -907258571, -907292418, -907324034, -907353381, -907380422, -907405124, + -907427456, -907447391, -907464903, -907479970, -907492575, -907502701, -907510335, -907515468, -907518092, + -907518205, -907515805, -907510896, -907503482, -907493572, -907481179, -907466317, -907449004, -907429261, + -907407111, -907382581, -907355702, -907326506, -907295028, -907261307, -907225384, -907187302, -907147109, + -907104853, -907060585, -907014361, -906966236, -906916270, -906864523, -906811060, -906755944, -906699245, + -906641031, -906581374, -906520347, -906458025, -906394483, -906329801, -906264050, -906197315, -906129676, + -906061214, -905992012, -905922152, -905851718, -905780792, -905709459, -905637802, -905565904, -905493847, + -905421715, -905349587, -905277545, -905205668, -905134032, -905062714, -904991788, -904921326, -904851397, + -904782068, -904713403, -904645463, -904578305, -904511983, -904446548, -904382044, -904318513, -904255990, + -904194508, -904134091, -904074760, -904016528, -903959404, -903903387, -903848473, -903794647, -903741889, + -903690170, -903639452, -903589690, -903540829, -903492806, -903445546, -903398968, -903352977, -903307470, + -903262332, -903217440, -903172655, -903127830, -903082805, -903037408, -902991455, -902944749, -902897082, + -902848230, -902797958, -902746017, -902692145, -902636065, -902577487, -902516107, -902451605, -902383649, + -902311891, -902235969, -902155504, -902070104, -901979361, -901882852, -901780138, -901670764, -901554261, + -901430141, -901297903, -901157028, -901006979, -900847206, -900677140, -900496195, -900303767, -900099237, + -899881968, -899651302, -899406566, -899147069, -898872099, -898580929, -898272809, -897946972, -897602633, + -897238985, -896855201, -896450436, -896023825, -895574479, -895101492, -894603937, -894080864, -893531305, + -892954268, -892348742, -891713696, -891048075, -890350805, -889620793, -888856922, -888058059, -887223048, + -886350714, -885439866, -884489291, -883497761, -882464029, -881386834, -880264898, -879096929, -877881622, + -876617661, -875303716, -873938450, -872520516, -871048562, -869521229, -867937155, -866294976, -864593328, + -862830848, -861006177, -859117961, -857164854, -855145521, -853058635, -850902887, -848676980, -846379640, + -844009611, -841565658, -839046575, -836451182, -833778329, -831026896, -828195801, -825283996, -822290474, + -819214267, -816054453, -812810153, -809480538, -806064827, -802562292, -798972258, -795294106, -791527275, + -787671264, -783725629, -779689995, -775564045, -771347531, -767040273, -762642156, -758153138, -753573244, + -748902575, -744141301, -739289667, -734347993, -729316674, -724196178, -718987051, -713689917, -708305473, + -702834496, -697277838, -691636430, -685911277, -680103464, -674214150, -668244572, -662196041, -656069944, + -649867743, -643590972, -637241240, -630820227, -624329685, -617771433, -611147363, -604459432, -597709664, + -590900148, -584033037, -577110543, -570134942, -563108566, -556033804, -548913099, -541748950, -534543903, + -527300554, -520021545, -512709564, -505367338, -497997635, -490603260, -483187052, -475751882, -468300650, + -460836282, -453361728, -445879958, -438393963, -430906743, -423421316, -415940704, -408467938, -401006049, + -393558069, -386127025, -378715938, -371327818, -363965660, -356632445, -349331130, -342064650, -334835913, + -327647796, -320503142, -313404758, -306355410, -299357818, -292414658, -285528555, -278702079, -271937746, + -265238010, -258605264, -252041836, -245549983, -239131895, -232789684, -226525389, -220340970, -214238305, + -208219189, -202285333, -196438360, -190679806, -185011113, -179433635, -173948631, -168557267, -163260612, + -158059640, -152955229, -147948160, -143039115, -138228681, -133517347, -128905505, -124393450, -119981382, + -115669406, -111457534, -107345683, -103333681, -99421264, -95608082, -91893698, -88277589, -84759152, + -81337704, -78012482, -74782650, -71647299, -68605451, -65656059, -62798015, -60030148, -57351228, + -54759972, -52255046, -49835065, -47498599, -45244179, -43070293, -40975397, -38957912, -37016231, + -35148723, -33353731, -31629581, -29974582, -28387030, -26865208, -25407397, -24011868, -22676893, + -21400745, -20181701, -19018041, -17908057, -16850050, -15842335, -14883242, -13971116, -13104325, + -12281255, -11500315, -10759938, -10058585, -9394741, -8766919, -8173665, -7613552, -7085185, + -6587202, -6118273, -5677102, -5262427, -4873021, -4507690, -4165278, -3844660, -3544752, + -3264499, -3002887, -2758933, -2531691, -2320249, -2123731, -1941292, -1772123, -1615446, + -1470519, -1336627, -1213092, -1099261, -994515, -898263, -809943, -729021, -654988, + -587365, -525695, -469547, -418515, -372215, -330284, -292383, -258192, -227410, + -199757, -174969, -152801, -133024, -115424, -99803, -85978, -73777, -63042, + -53629, -45403, -38240, -32028, -26663, -22051, -18104, -14745, -11902, + -9511, -7514, -5860, -4500, -3394, -2503, -1797, -1244, -820, + -502, -271, -109, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#endif /* #ifdef CR8_G_ADD_75MS */ + +RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_2_5ms_IP[240] = { + 214, 1407, 4144, 9592, 19434, 36052, 62711, 103783, 164992, + 253687, 379148, 552904, 789076, 1104722, 1520198, 2059494, 2750561, 3625602, + 4721314, 6079061, 7744972, 9769942, 12209518, 15123669, 18576419, 22635352, 27370973, + 32855950, 39164229, 46370051, 54546874, 63766241, 74096597, 85602085, 98341344, 112366317, + 127721101, 144440829, 162550610, 182064542, 202984778, 225300694, 248988134, 274008783, 300309659, + 327822776, 356464985, 386138051, 416728983, 448110659, 480142780, 512673177, 545539472, 578571104, + 611591694, 644421704, 676881340, 708793602, 739987407, 770300656, 799583149, 827699226, 854530045, + 879975405, 903955057, 926409465, 947300009, 966608644, 984337071, 1000505451, 1015150768, 1028324899, + 1040092491, 1050528715, 1059716983, 1067746699, 1074711082, 1080705143, 1085823820, 1090160324, 1093804700, + 1096842623, 1099354431, 1101414399, 1103090233, 1104442796, 1105526028, 1106387052, 1107066439, 1107598605, + 1108012308, 1108331223, 1108574556, 1108757676, 1108892731, 1108989242, 1109054637, 1109094735, 1109114155, + 1109116652, 1109105394, 1109083163, 1109052498, 1109015788, 1108975323, 1108933307, 1108891843, 1108852902, + 1108818280, 1108789546, 1108767992, 1108754591, 1108749953, 1108754306, 1108767481, 1108788919, 1108817694, + 1108852552, 1108891964, 1108934195, -1108977380, -1109019614, -1109059032, -1109093898, -1109122681, -1109144125, + -1109157302, -1109161650, -1109156995, -1109143556, -1109121925, -1109093037, -1109058122, -1109018637, -1108976187, + -1108932433, -1108888980, -1108847255, -1108808366, -1108772946, -1108740971, -1108711558, -1108682731, -1108651158, + -1108611855, -1108557851, -1108479820, -1108365676, -1108200143, -1107964292, -1107635083, -1107184891, -1106581062, + -1105785503, -1104754330, -1103437601, -1101779148, -1099716548, -1097181229, -1094098763, -1090389339, -1085968441, + -1080747748, -1074636248, -1067541577, -1059371579, -1050036059, -1039448713, -1027529209, -1014205354, -999415302, + -983109740, -965253961, -945829756, -924837032, -902295070, -878243367, -852741971, -825871301, -797731403, + -768440669, -738134051, -706960817, -675081952, -642667284, -609892453, -576935833, -543975515, -511186440, + -478737764, -446790521, -415495622, -384992199, -355406317, -326850029, -299420751, -273200929, -248257970, + -224644391, -202398148, -181543141, -162089834, -144035993, -127367520, -112059369, -98076525, -85375063, + -73903244, -63602666, -54409446, -46255413, -39069306, -32777951, -27307388, -22583946, -18535216, + -15090941, -12183768, -9749883, -7729511, -6067277, -4712439, -3619003, -2745721, -2055997, + -1517713, -1102987, -787888, -552109, -378629, -253358, -164789, -103664, -62644, + -36017, -19417, -9584, -4141, -1406, -214 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_5ms_IP[420] = { + 153, 1006, 2962, 6854, 13880, 25735, 44738, 73986, 117524, + 180533, 269534, 392603, 559593, 782368, 1075031, 1454143, 1938937, 2551502, + 3316947, 4263524, 5422707, 6829222, 8521011, 10539137, 12927604, 15733109, 19004698, + 22793344, 27151431, 32132152, 37788816, 44174082, 51339114, 59332667, 68200136, 77982547, + 88715548, 100428385, 113142910, 126872625, 141621804, 157384706, 174144915, 191874817, 210535261, + 230075406, 250432778, 271533559, 293293106, 315616716, 338400617, 361533198, 384896437, 408367524, + 431820627, 455128780, 478165843, 500808481, 522938120, 544442827, 565219197, 585174124, 604225689, + 622304754, 639355717, 655337129, 670221993, 683997778, 696666136, 708242355, 718754575, 728242788, + 736757688, 744359378, 751116012, 757102394, 762398585, 767088551, 771258886, 774997644, 778393288, + 781533768, 784505744, 787393944, 790280637, 793245232, 796363956, 799709608, 803351363, 807354601, + 811780739, 816687064, 822126537, 828147569, 834793773, 842103681, 850110443, 858841520, 868318369, + 878556163, 889563529, 901342346, 913887605, 927187338, 941222645, 955967800, 971390453, 987451937, + 1004107649, 1021307531, 1038996616, 1057115651, 1075601769, 1094389201, 1113410024, 1132594917, 1151873921, + 1171177186, 1190435688, 1209581916, 1228550504, 1247278803, 1265707395, 1283780533, 1301446498, 1318657893, + 1335371854, 1351550191, 1367159457, 1382170967, 1396560748, 1410309460, 1423402271, 1435828702, 1447582463, + 1458661263, 1469066617, 1478803649, 1487880888, 1496310057, 1504105864, 1511285781, 1517869810, 1523880240, + 1529341392, 1534279342, 1538721639, 1542697001, 1546235012, 1549365809, 1552119778, 1554527246, 1556618203, + 1558422028, 1559967247, 1561281317, 1562390436, 1563319395, 1564091445, 1564728213, 1565249633, 1565673917, + 1566017543, 1566295272, 1566520181, 1566703721, 1566855785, 1566984788, 1567097770, 1567200488, 1567297538, + 1567392456, 1567487845, 1567585484, 1567686442, 1567791191, 1567899701, 1568011546, 1568125984, 1568242042, + 1568358534, 1568474289, 1568587995, 1568698311, 1568803945, 1568903672, 1568996349, 1569080932, 1569156484, + 1569222192, 1569277370, 1569321465, 1569354064, 1569374893, 1569383815, 1569380829, 1569366065, 1569339781, + 1569302349, 1569254257, 1569196093, 1569128539, 1569052361, 1568968403, 1568877571, 1568780830, 1568679193, + 1568573710, 1568465461, 1568355548, 1568245083, 1568135185, 1568026967, 1567921528, 1567819946, 1567723271, + 1567632511, 1567548628, 1567472527, 1567405047, 1567346952, 1567298919, 1567261537, 1567235287, 1567220544, + 1567217562, 1567226472, 1567247272, 1567279829, 1567323868, 1567378978, 1567444612, 1567520086, 1567604589, + 1567697189, 1567796846, 1567902419, 1568012687, 1568126359, 1568242097, -1568358534, -1568474289, -1568587995, + -1568698311, -1568803945, -1568903672, -1568996349, -1569080932, -1569156484, -1569222192, -1569277370, -1569321465, + -1569354064, -1569374893, -1569383815, -1569380829, -1569366065, -1569339781, -1569302349, -1569254257, -1569196093, + -1569128539, -1569052361, -1568968403, -1568877571, -1568780830, -1568679193, -1568573710, -1568465461, -1568355548, + -1568245083, -1568135185, -1568026967, -1567921528, -1567819946, -1567723271, -1567632511, -1567548628, -1567472527, + -1567405047, -1567346952, -1567298919, -1567261537, -1567235287, -1567220544, -1567217562, -1567226472, -1567247272, + -1567279829, -1567323868, -1567378978, -1567444612, -1567520086, -1567604589, -1567697189, -1567796846, -1567902419, + -1568012687, -1568126359, -1568242097, -1568358479, -1568473914, -1568586854, -1568695591, -1568798286, -1568892916, + -1568977226, -1569048656, -1569104263, -1569140635, -1569153790, -1569139071, -1569091028, -1569003308, -1568868529, + -1568678156, -1568422382, -1568089999, -1567668277, -1567142834, -1566497514, -1565714254, -1564772952, -1563651331, + -1562324794, -1560766278, -1558946098, -1556831792, -1554387964, -1551576132, -1548354584, -1544678268, -1540498696, + -1535763912, -1530418507, -1524403718, -1517657618, -1510115411, -1501709847, -1492371764, -1482030768, -1470616033, + -1458057247, -1444285654, -1429235205, -1412843785, -1395054486, -1375816907, -1355088440, -1332835519, -1309034797, + -1283674224, -1256753995, -1228287351, -1198301206, -1166836586, -1133948872, -1099707826, -1064197417, -1027515419, + -989772809, -951092956, -911610610, -871470715, -830827045, -789840682, -748678366, -707510713, -666510349, + -625849956, -585700281, -546228117, -507594292, -469951710, -433443460, -398201053, -364342807, -331972440, + -301177891, -272030413, -244583969, -218874947, -194922208, -172727465, -152275991, -133537623, -116468025, + -101010189, -87096098, -74648510, -63582812, -53808877, -45232880, -37759037, -31291209, -25734358, + -20995832, -16986455, -13621428, -10821035, -8511162, -6623645, -5096451, -3873717, -2905668, + -2148423, -1563717, -1118555, -784819, -538834, -360926, -234965, -147925, -89451, + -51458, -27754, -13704, -5923, -2011, -306 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_IP[780] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 105, 687, 2025, 4688, 9502, 17634, + 30689, 50817, 80838, 124375, 186009, 271432, 387623, 543017, 747676, + 1013467, 1354215, 1785853, 2326545, 2996777, 3819424, 4819763, 6025441, 7466392, + 9174686, 11184326, 13530961, 16251545, 19383921, 22966334, 27036891, 31632957, 36790505, + 42543426, 48922816, 55956247, 63667042, 72073568, 81188571, 91018551, 101563225, 112815065, + 124758945, 137371906, 150623045, 164473553, 178876885, 193779093, 209119296, 224830297, 240839344, + 257069006, 273438164, 289863100, 306258645, 322539389, 338620907, 354420979, 369860792, 384866072, + 399368244, 413305531, 426623420, 439275707, 451224957, 462442920, 472910759, 482619111, 491567983, + 499766479, 507232383, 513991603, 520077504, 525530145, 530395443, 534724296, 538571682, 541995756, + 545056975, 547817267, 550339253, 552685542, 554918106, 557097730, 559283544, 561532631, 563899693, + 566436780, 569193061, 572214618, 575544274, 579221418, 583281849, 587757606, 592676805, 598063482, + 603937430, 610314061, 617204279, 624614388, 632546030, 640996174, 649957147, 659416723, 669358259, + 679760895, 690599795, 701846444, 713468981, 725432569, 737699796, 750231092, 762985159, 775919415, + 788990419, 802154306, 815367198, 828585593, 841766740, 854868978, 867852045, 880677358, 893308258, + 905710214, 917851001, 929700832, 941232469, 952421292, 963245346, 973685357, 983724726, 993349512, + 1002548385, 1011312579, 1019635831, 1027514316, 1034946573, 1041933433, 1048477942, 1054585275, 1060262649, + 1065519228, 1070366010, 1074815711, 1078882625, 1082582470, 1085932219, 1088949913, 1091654462, 1094065430, + 1096202822, 1098086863, 1099737781, 1101175600, 1102419947, 1103489872, 1104403690, 1105178850, 1105831817, + 1106377989, 1106831632, 1107205842, 1107512525, 1107762397, 1107965009, 1108128778, 1108261042, 1108368118, + 1108455375, 1108527311, 1108587638, 1108639366, 1108684891, 1108726077, 1108764338, 1108800715, 1108835945, + 1108870522, 1108904754, 1108938811, 1108972723, 1109006542, 1109040205, 1109073607, 1109106645, 1109139216, + 1109171221, 1109202563, 1109233147, 1109262880, 1109291675, 1109319447, 1109346114, 1109371602, 1109395837, + 1109418753, 1109440288, 1109460385, 1109478991, 1109496061, 1109511552, 1109525430, 1109537663, 1109548227, + 1109557101, 1109564272, 1109569731, 1109573473, 1109575498, 1109575814, 1109574431, 1109571363, 1109566630, + 1109560257, 1109552270, 1109542702, 1109531587, 1109518966, 1109504879, 1109489374, 1109472496, 1109454299, + 1109434835, 1109414161, 1109392335, 1109369417, 1109345469, 1109320555, 1109294742, 1109268095, 1109240684, + 1109212578, 1109183848, 1109154564, 1109124800, 1109094627, 1109064121, 1109033354, 1109002402, 1108971338, + 1108940237, 1108909175, 1108878226, 1108847464, 1108816965, 1108786801, 1108757046, 1108727774, 1108699056, + 1108670963, 1108643567, 1108616936, 1108591139, 1108566243, 1108542312, 1108519412, 1108497603, 1108476946, + 1108457499, 1108439319, 1108422458, 1108406967, 1108392895, 1108380286, 1108369184, 1108359626, 1108351647, + 1108345281, 1108340553, 1108337489, 1108336107, 1108336422, 1108338446, 1108342183, 1108347636, 1108354799, + 1108363664, 1108374217, 1108386437, 1108400301, 1108415777, 1108432830, 1108451419, 1108471498, 1108493014, + 1108515912, 1108540129, 1108565598, 1108592247, 1108620001, 1108648779, 1108678497, 1108709066, 1108740395, + 1108772389, 1108804951, 1108837980, 1108871376, 1108905035, 1108938852, 1108972723, 1109006542, 1109040205, + 1109073607, 1109106645, 1109139216, 1109171221, 1109202563, 1109233147, 1109262880, 1109291675, 1109319447, + 1109346114, 1109371602, 1109395837, 1109418753, 1109440288, 1109460385, 1109478991, 1109496061, 1109511552, + 1109525430, 1109537663, 1109548227, 1109557101, 1109564272, 1109569731, 1109573473, 1109575498, 1109575814, + 1109574431, 1109571363, 1109566630, 1109560257, 1109552270, 1109542702, 1109531587, 1109518966, 1109504879, + 1109489374, 1109472496, 1109454299, 1109434835, 1109414161, 1109392335, 1109369417, 1109345469, 1109320555, + 1109294742, 1109268095, 1109240684, 1109212578, 1109183848, 1109154564, 1109124800, 1109094627, 1109064121, + 1109033354, 1109002402, 1108971338, -1108940237, -1108909175, -1108878226, -1108847464, -1108816965, -1108786801, + -1108757046, -1108727774, -1108699056, -1108670963, -1108643567, -1108616936, -1108591139, -1108566243, -1108542312, + -1108519412, -1108497603, -1108476946, -1108457499, -1108439319, -1108422458, -1108406967, -1108392895, -1108380286, + -1108369184, -1108359626, -1108351647, -1108345281, -1108340553, -1108337489, -1108336107, -1108336422, -1108338446, + -1108342183, -1108347636, -1108354799, -1108363664, -1108374217, -1108386437, -1108400301, -1108415777, -1108432830, + -1108451419, -1108471498, -1108493014, -1108515912, -1108540129, -1108565598, -1108592247, -1108620001, -1108648779, + -1108678497, -1108709066, -1108740395, -1108772389, -1108804951, -1108837980, -1108871376, -1108905035, -1108938852, + -1108972723, -1109006542, -1109040205, -1109073607, -1109106645, -1109139216, -1109171221, -1109202563, -1109233147, + -1109262880, -1109291675, -1109319447, -1109346114, -1109371602, -1109395837, -1109418753, -1109440288, -1109460385, + -1109478991, -1109496061, -1109511552, -1109525430, -1109537663, -1109548227, -1109557101, -1109564272, -1109569731, + -1109573473, -1109575498, -1109575814, -1109574431, -1109571363, -1109566630, -1109560257, -1109552270, -1109542702, + -1109531587, -1109518966, -1109504879, -1109489374, -1109472496, -1109454299, -1109434835, -1109414161, -1109392335, + -1109369417, -1109345469, -1109320555, -1109294742, -1109268095, -1109240684, -1109212578, -1109183848, -1109154564, + -1109124800, -1109094627, -1109064121, -1109033354, -1109002402, -1108971338, -1108940237, -1108909175, -1108878226, + -1108847464, -1108816965, -1108786801, -1108757046, -1108727774, -1108699056, -1108670963, -1108643567, -1108616936, + -1108591139, -1108566243, -1108542312, -1108519412, -1108497603, -1108476946, -1108457499, -1108439319, -1108422458, + -1108406967, -1108392895, -1108380286, -1108369184, -1108359626, -1108351647, -1108345281, -1108340553, -1108337489, + -1108336107, -1108336422, -1108338446, -1108342183, -1108347636, -1108354799, -1108363664, -1108374217, -1108386437, + -1108400301, -1108415777, -1108432830, -1108451419, -1108471498, -1108493014, -1108515912, -1108540129, -1108565598, + -1108592247, -1108620001, -1108648779, -1108678497, -1108709066, -1108740395, -1108772389, -1108804951, -1108837980, + -1108871376, -1108905035, -1108938852, -1108972682, -1109006261, -1109039351, -1109071571, -1109102407, -1109131162, + -1109156896, -1109178374, -1109193989, -1109201688, -1109198891, -1109182406, -1109148336, -1109091993, -1109007805, + -1108889225, -1108728643, -1108517302, -1108245211, -1107901063, -1107472158, -1106944320, -1106301824, -1105527310, + -1104601707, -1103504157, -1102211925, -1100700333, -1098942681, -1096910184, -1094571927, -1091894839, -1088843693, + -1085381150, -1081467851, -1077062556, -1072122362, -1066602975, -1060459071, -1053644721, -1046113898, -1037821043, + -1028721699, -1018773190, -1007935330, -996171157, -983447669, -969736537, -955014802, -939265519, -922478340, + -904650040, -885784954, -865895333, -845001612, -823132583, -800325469, -776625909, -752087844, -726773304, + -700752110, -674101477, -646905528, -619254721, -591245188, -562977986, -534558266, -506094363, -477696807, + -449477265, -421547413, -394017760, -366996430, -340587909, -314891801, -290001587, -266003441, -242975106, + -220984887, -200090776, -180339738, -161767200, -144396752, -128240072, -113297104, -99556455, -86996029, + -75583860, -65279122, -56033278, -47791333, -40493145, -34074759, -28469709, -23610284, -19428682, + -15858075, -12833534, -10292814, -8176993, -6430970, -5003818, -3849000, -2924474, -2192679, + -1620441, -1178790, -842729, -590941, -405483, -271445, -176613, -111130, -67168, + -38622, -20823, -10279, -4442, -1508, -229 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_2_5ms_IP[480] = { + 214, 718, 1564, 2887, 4850, 7655, 11549, 16828, 23847, + 33024, 44855, 59914, 78870, 102494, 131671, 167412, 210862, 263320, + 326247, 401279, 490246, 595184, 718349, 862234, 1029583, 1223409, 1447008, + 1703973, 1998212, 2333963, 2715805, 3148674, 3637878, 4189104, 4808432, 5502344, + 6277732, 7141903, 8102584, 9167924, 10346495, 11647288, 13079711, 14653577, 16379097, + 18266869, 20327854, 22573365, 25015043, 27664828, 30534935, 33637823, 36986159, 40592781, + 44470665, 48632874, 53092523, 57862728, 62956563, 68387004, 74166887, 80308851, 86825288, + 93728290, 101029595, 108740533, 116871978, 125434289, 134437259, 143890065, 153801219, 164178510, + 175028964, 186358792, 198173341, 210477054, 223273422, 236564945, 250353087, 264638241, 279419691, + 294695574, 310462852, 326717278, 343453367, 360664374, 378342268, 396477718, 415060072, 434077349, + 453516232, 473362064, 493598851, 514209273, 535174695, 556475190, 578089564, 599995393, 622169062, + 644585817, 667219821, 690044217, 713031208, 736152130, 759377547, 782677345, 806020840, 829376886, + 852713991, 876000447, 899204452, 922294246, 945238242, 968005170, 990564209, 1012885127, 1034938418, + 1056695435, 1078128516, 1099211112, 1119917901, 1140224902, 1160109567, 1179550884, 1198529445, 1217027528, + 1235029144, 1252520091, 1269487982, 1285922269, 1301814250, 1317157066, 1331945687, 1346176884, 1359849191, + 1372962859, 1385519797, 1397523511, 1408979025, 1419892807, 1430272680, 1440127732, 1449468226, 1458305498, + 1466651859, 1474520500, 1481925383, 1488881148, 1495403011, 1501506666, 1507208191, 1512523957, 1517470536, + 1522064619, 1526322933, 1530262165, 1533898889, 1537249499, 1540330149, 1543156689, 1545744622, 1548109049, + 1550264632, 1552225553, 1554005489, 1555617576, 1557074399, 1558387963, 1559569689, 1560630404, 1561580336, + 1562429115, 1563185777, 1563858772, 1564455973, 1564984695, 1565451702, 1565863235, 1566225027, 1566542325, + 1566819919, 1567062160, 1567272989, 1567455965, 1567614286, 1567750818, 1567868122, 1567968477, 1568053906, + 1568126199, 1568186936, 1568237509, 1568279142, 1568312908, 1568339752, 1568360503, 1568375889, 1568386553, + 1568393062, 1568395921, 1568395582, 1568392450, 1568386895, 1568379252, 1568369831, 1568358921, 1568346793, + 1568333699, 1568319881, 1568305568, 1568290979, 1568276322, 1568261795, 1568247587, 1568233876, 1568220830, + 1568208605, 1568197346, 1568187184, 1568178237, 1568170607, 1568164384, 1568159638, 1568156425, 1568154783, + 1568154732, 1568156276, 1568159400, 1568164071, 1568170240, 1568177841, 1568186791, 1568196993, 1568208336, + 1568220695, 1568233934, 1568247907, 1568262461, 1568277433, 1568292659, -1568307970, -1568323196, -1568338169, + -1568352723, -1568366698, -1568379938, -1568392298, -1568403642, -1568413846, -1568422797, -1568430399, -1568436568, + -1568441238, -1568444360, -1568445899, -1568445842, -1568444189, -1568440959, -1568436189, -1568429930, -1568422249, + -1568413227, -1568402961, -1568391555, -1568379128, -1568365802, -1568351710, -1568336985, -1568321763, -1568306179, + -1568290362, -1568274432, -1568258500, -1568242658, -1568226981, -1568211514, -1568196277, -1568181247, -1568166364, + -1568151514, -1568136526, -1568121163, -1568105112, -1568087973, -1568069251, -1568048342, -1568024520, -1567996924, + -1567964542, -1567926198, -1567880531, -1567825982, -1567760771, -1567682880, -1567590033, -1567479671, -1567348935, + -1567194644, -1567013268, -1566800908, -1566553276, -1566265667, -1565932945, -1565549513, -1565109302, -1564605744, + -1564031762, -1563379748, -1562641555, -1561808482, -1560871269, -1559820088, -1558644542, -1557333666, -1555875931, + -1554259255, -1552471010, -1550498044, -1548326699, -1545942840, -1543331880, -1540478822, -1537368293, -1533984594, + -1530311749, -1526333557, -1522033659, -1517395595, -1512402882, -1507039082, -1501287884, -1495133187, -1488559185, + -1481550459, -1474092069, -1466169648, -1457769502, -1448878707, -1439485206, -1429577913, -1419146803, -1408183016, + -1396678943, -1384628319, -1372026306, -1358869573, -1345156368, -1330886582, -1316061806, -1300685380, -1284762427, + -1268299884, -1251306514, -1233792909, -1215771486, -1197256464, -1178263828, -1158811290, -1138918228, -1118605615, + -1097895946, -1076813140, -1055382446, -1033630329, -1011584359, -989273085, -966725907, -943972946, -921044904, + -897972934, -874788497, -851523227, -828208798, -804876792, -781558570, -758285150, -735087092, -711994385, + -689036342, -666241506, -643637563, -621251256, -599108313, -577233388, -555649994, -534380464, -513445903, + -492866154, -472659775, -452844015, -433434798, -414446719, -395893041, -377785693, -360135279, -342951091, + -326241124, -310012090, -294269448, -279017421, -264259031, -249996126, -236229411, -222958488, -210181887, + -197897110, -186100669, -174788126, -163954142, -153592518, -143696242, -134257536, -125267909, -116718201, + -108598638, -100898882, -93608083, -86714933, -80207718, -74074369, -68302521, -62879558, -57792672, + -53028908, -48575221, -44418518, -40545711, -36943757, -33599707, -30500746, -27634227, -24987716, + -22549018, -20306212, -18247679, -16362124, -14638601, -13066533, -11635723, -10336374, -9159092, + -8094899, -7135237, -6271969, -5497377, -4804166, -4185453, -3634765, -3146030, -2713568, + -2332079, -1996632, -1702653, -1445912, -1222503, -1028839, -861625, -717855, -594786, + -489927, -401025, -326046, -263164, -210741, -167319, -131601, -102441, -78831, + -59886, -44835, -33011, -23837, -16822, -11545, -7652, -4848, -2886, + -1564, -718, -214 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_5ms_IP[840] = { + 76, 257, 559, 1032, 1734, 2736, 4127, 6013, 8519, + 11795, 16017, 21388, 28146, 36565, 46958, 59681, 75141, 93793, + 116154, 142798, 174368, 211576, 255213, 306147, 365337, 433830, 512771, + 603404, 707083, 825270, 959545, 1111607, 1283278, 1476512, 1693391, 1936135, + 2207099, 2508779, 2843816, 3214988, 3625222, 4077586, 4575292, 5121693, 5720282, + 6374686, 7088668, 7866117, 8711044, 9627575, 10619947, 11692493, 12849640, 14095892, + 15435823, 16874063, 18415286, 20064193, 21825499, 23703917, 25704138, 27830817, 30088554, + 32481870, 35015193, 37692833, 40518962, 43497594, 46632560, 49927486, 53385775, 57010578, + 60804774, 64770951, 68911378, 73227988, 77722354, 82395670, 87248734, 92281923, 97495181, + 102888003, 108459414, 114207966, 120131717, 126228227, 132494547, 138927218, 145522261, 152275182, + 159180971, 166234104, 173428552, 180757788, 188214801, 195792105, 203481764, 211275403, 219164235, + 227139085, 235190416, 243308359, 251482745, 259703138, 267958873, 276239090, 284532776, 292828806, + 301115982, 309383080, 317618887, 325812253, 333952128, 342027608, 350027981, 357942764, 365761752, + 373475051, 381073123, 388546818, 395887478, 403086861, 410137202, 417031278, 423762414, 430324505, + 436712040, 442920115, 448944445, 454781381, 460427907, 465881653, 471140887, 476204517, 481072084, + 485743749, 490220286, 494503064, 498594029, 502495687, 506211078, 509743756, 513097759, 516277584, + 519288161, 522134817, 524823252, 527359505, 529749922, 532001128, 534119994, 536113606, 537989238, + 539754317, 541416403, 542983151, 544462298, 545861626, 547188947, 548452077, 549658817, 550816937, + 551934153, 553018114, 554076391, 555116460, 556145691, 557171340, 558200539, 559240287, 560297445, + 561378728, 562490702, 563639778, 564832206, 566074075, 567371305, 568729649, 570154682, 571651805, + 573226236, 574883010, 576626970, 578462769, 580394858, 582427488, 584564698, 586810313, 589167940, + 591640954, 594232500, 596945481, 599782552, 602746115, 605838312, 609061015, 612415825, 615904060, + 619526756, 623284658, 627178213, 631207574, 635372590, 639672804, 644107457, 648675483, 653375510, + 658205862, 663164563, 668249336, 673457615, 678786542, 684232980, 689793518, 695464480, 701241935, + 707121707, 713099387, 719170342, 725329733, 731572527, 737893509, 744287298, 750748363, 757271038, + 763849540, 770477982, 777150393, 783860731, 790602903, 797370781, 804158216, 810959059, 817767172, + 824576448, 831380824, 838174297, 844950938, 851704905, 858430460, 865121975, 871773953, 878381029, + 884937988, 891439772, 897881487, 904258415, 910566018, 916799945, 922956036, 929030332, 935019072, + 940918701, 946725867, 952437431, 958050459, 963562228, 968970222, 974272134, 979465863, 984549513, + 989521388, 994379992, 999124027, 1003752385, 1008264148, 1012658583, 1016935141, 1021093445, 1025133296, + 1029054661, 1032857672, 1036542620, 1040109952, 1043560268, 1046894310, 1050112965, 1053217256, 1056208338, + 1059087494, 1061856131, 1064515771, 1067068050, 1069514712, 1071857603, 1074098665, 1076239931, 1078283519, + 1080231627, 1082086525, 1083850551, 1085526101, 1087115629, 1088621631, 1090046648, 1091393252, 1092664044, + 1093861644, 1094988685, 1096047808, 1097041655, 1097972860, 1098844046, 1099657818, 1100416756, 1101123410, + 1101780297, 1102389891, 1102954625, 1103476879, 1103958984, 1104403212, 1104811774, 1105186822, 1105530438, + 1105844638, 1106131370, 1106392508, 1106629854, 1106845137, 1107040012, 1107216060, 1107374784, 1107517617, + 1107645915, 1107760961, 1107863967, 1107956073, 1108038347, 1108111792, 1108177340, 1108235860, 1108288159, + 1108334979, 1108377006, 1108414868, 1108449137, 1108480336, 1108508935, 1108535359, 1108559986, 1108583153, + 1108605158, 1108626260, 1108646685, 1108666625, 1108686243, 1108705675, 1108725031, 1108744398, 1108763843, + 1108783413, 1108803139, 1108823037, 1108843110, 1108863348, 1108883733, 1108904238, 1108924827, 1108945461, + 1108966087, 1108986655, 1109007132, 1109027458, 1109047572, 1109067415, 1109086928, 1109106055, 1109124739, + 1109142927, 1109160566, 1109177606, 1109193997, 1109209694, 1109224653, 1109238833, 1109252194, 1109264701, + 1109276321, 1109287024, 1109296781, 1109305569, 1109313366, 1109320154, 1109325918, 1109330645, 1109334328, + 1109336959, 1109338535, 1109339057, 1109338528, 1109336954, 1109334342, 1109330704, 1109326055, 1109320411, + 1109313791, 1109306216, 1109297711, 1109288301, 1109278014, 1109266881, 1109254934, 1109242206, 1109228734, + 1109214554, 1109199706, 1109184228, 1109168164, 1109151555, 1109134445, 1109116879, 1109098903, 1109080563, + 1109061906, 1109042980, 1109023833, 1109004515, 1108985073, 1108965557, 1108946017, 1108926503, 1108907062, + 1108887746, 1108868601, 1108849679, 1108831026, 1108812690, 1108794719, 1108777158, 1108760054, 1108743451, + 1108727393, 1108711923, 1108697081, 1108682908, 1108669442, 1108656721, 1108644781, 1108633654, 1108623374, + 1108613969, 1108605469, 1108597899, 1108591283, 1108585643, 1108580997, 1108577362, 1108574752, 1108573178, + 1108572650, 1108573172, 1108574747, 1108577376, 1108581056, 1108585780, 1108591541, 1108598324, 1108606116, + 1108614899, 1108624650, 1108635346, 1108646959, 1108659460, 1108672814, 1108686987, 1108701939, 1108717629, + 1108734013, 1108751046, 1108768679, 1108786861, 1108805540, 1108824662, 1108844171, 1108864011, 1108884121, + 1108904445, 1108924921, 1108945488, -1108966087, -1108986655, -1109007132, -1109027458, -1109047572, -1109067415, + -1109086928, -1109106055, -1109124739, -1109142927, -1109160566, -1109177606, -1109193997, -1109209694, -1109224653, + -1109238833, -1109252194, -1109264701, -1109276321, -1109287024, -1109296781, -1109305569, -1109313366, -1109320154, + -1109325918, -1109330645, -1109334328, -1109336959, -1109338535, -1109339057, -1109338528, -1109336954, -1109334342, + -1109330704, -1109326055, -1109320411, -1109313791, -1109306216, -1109297711, -1109288301, -1109278014, -1109266881, + -1109254934, -1109242206, -1109228734, -1109214554, -1109199706, -1109184228, -1109168164, -1109151555, -1109134445, + -1109116879, -1109098903, -1109080563, -1109061906, -1109042980, -1109023833, -1109004515, -1108985073, -1108965557, + -1108946017, -1108926503, -1108907062, -1108887746, -1108868601, -1108849679, -1108831026, -1108812690, -1108794719, + -1108777158, -1108760054, -1108743451, -1108727393, -1108711923, -1108697081, -1108682908, -1108669442, -1108656721, + -1108644781, -1108633654, -1108623374, -1108613969, -1108605469, -1108597899, -1108591283, -1108585643, -1108580997, + -1108577362, -1108574752, -1108573178, -1108572650, -1108573172, -1108574747, -1108577376, -1108581056, -1108585780, + -1108591541, -1108598324, -1108606116, -1108614899, -1108624650, -1108635346, -1108646959, -1108659460, -1108672814, + -1108686987, -1108701939, -1108717629, -1108734013, -1108751046, -1108768679, -1108786861, -1108805540, -1108824662, + -1108844171, -1108864011, -1108884121, -1108904445, -1108924921, -1108945488, -1108966059, -1108986562, -1109006925, + -1109027070, -1109046909, -1109066353, -1109085302, -1109103653, -1109121290, -1109138090, -1109153916, -1109168619, + -1109182038, -1109193990, -1109204280, -1109212687, -1109218972, -1109222869, -1109224086, -1109222302, -1109217164, + -1109208286, -1109195243, -1109177572, -1109154771, -1109126288, -1109091528, -1109049845, -1109000541, -1108942861, + -1108875994, -1108799068, -1108711146, -1108611228, -1108498242, -1108371047, -1108228427, -1108069090, -1107891663, + -1107694692, -1107476636, -1107235870, -1106970675, -1106679239, -1106359654, -1106009912, -1105627904, -1105211414, + -1104758117, -1104265576, -1103731240, -1103152437, -1102526375, -1101850136, -1101120673, -1100334807, -1099489225, + -1098580473, -1097604958, -1096558943, -1095438542, -1094239723, -1092958302, -1091589944, -1090130161, -1088574313, + -1086917606, -1085155099, -1083281700, -1081292171, -1079181138, -1076943086, -1074572374, -1072063243, -1069409818, + -1066606126, -1063646105, -1060523618, -1057232468, -1053766415, -1050119192, -1046284528, -1042256165, -1038027882, + -1033593517, -1028946994, -1024082345, -1018993738, -1013675503, -1008122162, -1002328454, -996289366, -990000160, + -983456402, -976653990, -969589182, -962258626, -954659381, -946788949, -938645296, -930226877, -921532657, + -912562133, -903315354, -893792938, -883996084, -873926592, -863586870, -852979945, -842109472, -830979735, + -819595655, -807962787, -796087320, -783976072, -771636483, -759076610, -746305110, -733331233, -720164799, + -706816188, -693296313, -679616605, -665788980, -651825820, -637739943, -623544570, -609253297, -594880059, + -580439096, -565944918, -551412265, -536856066, -522291404, -507733472, -493197528, -478698857, -464252725, + -449874333, -435578778, -421381001, -407295749, -393337528, -379520558, -365858731, -352365567, -339054174, + -325937207, -313026827, -300334664, -287871784, -275648653, -263675105, -251960314, -240512770, -229340251, + -218449809, -207847746, -197539607, -187530166, -177823422, -168422593, -159330123, -150547678, -142076164, + -133915731, -126065794, -118525050, -111291498, -104362470, -97734652, -91404122, -85366377, -79616373, + -74148557, -68956911, -64034986, -59375949, -54972617, -50817502, -46902854, -43220698, -39762875, + -36521086, -33486923, -30651913, -28007548, -25545325, -23256770, -21133479, -19167136, -17349546, + -15672656, -14128580, -12709614, -11408260, -10217235, -9129491, -8138220, -7236869, -6419144, + -5679019, -5010736, -4408811, -3868031, -3383459, -2950426, -2564532, -2221640, -1917871, + -1649598, -1413439, -1206249, -1025112, -867332, -730423, -612103, -510279, -423042, + -348652, -285533, -232260, -187551, -150254, -119343, -93901, -73120, -56285, + -42770, -32029, -23588, -17037, -12025, -8254, -5472, -3467, -2064, + -1119, -513, -153 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_IP[1560] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 52, 175, 382, + 705, 1185, 1871, 2823, 4114, 5831, 8077, 10972, 14660, + 19303, 25092, 32244, 41009, 51670, 64545, 79996, 98427, 120290, + 146088, 176379, 211778, 252965, 300685, 355753, 419058, 491567, 574329, + 668476, 775231, 895906, 1031911, 1184750, 1356028, 1547453, 1760836, 1998091, + 2261242, 2552417, 2873848, 3227877, 3616948, 4043606, 4510498, 5020366, 5576047, + 6180463, 6836620, 7547602, 8316559, 9146706, 10041310, 11003683, 12037172, 13145144, + 14330983, 15598071, 16949778, 18389446, 19920381, 21545832, 23268982, 25092926, 27020662, + 29055072, 31198906, 33454766, 35825091, 38312140, 40917976, 43644450, 46493186, 49465569, + 52562726, 55785514, 59134509, 62609992, 66211939, 69940008, 73793535, 77771521, 81872629, + 86095178, 90437137, 94896125, 99469410, 104153908, 108946186, 113842469, 118838639, 123930249, + 129112527, 134380390, 139728454, 145151046, 150642225, 156195792, 161805313, 167464136, 173165413, + 178902121, 184667086, 190453005, 196252476, 202058015, 207862090, 213657145, 219435626, 225190009, + 230912827, 236596697, 242234348, 247818648, 253342624, 258799497, 264182697, 269485893, 274703012, + 279828312, 284856314, 289781856, 294600125, 299306665, 303897390, 308368599, 312716983, 316939635, + 321034059, 324998175, 328830319, 332529248, 336094136, 339524575, 342820570, 345982531, 349011267, + 351907976, 354674236, 357311989, 359823531, 362211496, 364478840, 366628822, 368664989, 370591159, + 372411396, 374129997, 375751467, 377280502, 378721970, 380080887, 381362400, 382571769, 383714343, + 384795547, 385820862, 386795806, 387725921, 388616754, 389473844, 390302710, 391108835, 391897652, + 392674541, 393444809, 394213686, 394986316, 395767747, 396562926, 397376691, 398213764, 399078748, + 399976120, 400910228, 401885285, 402905364, 403974398, 405096172, 406274322, 407512329, 408813519, + 410181054, 411617935, 413126993, 414710888, 416372104, 418112946, 419935539, 421841819, 423833534, + 425912241, 428079300, 430335872, 432682921, 435121205, 437651278, 440273491, 442987985, 445794697, + 448693355, 451683483, 454764399, 457935219, 461194860, 464542039, 467975283, 471492928, 475093126, + 478773851, 482532904, 486367920, 490276375, 494255591, 498302751, 502414896, 506588946, 510821698, + 515109841, 519449966, 523838572, 528272075, 532746823, 537259100, 541805139, 546381131, 550983233, + 555607579, 560250290, 564907481, 569575271, 574249791, 578927195, 583603665, 588275420, 592938724, + 597589893, 602225302, 606841390, 611434670, 616001729, 620539240, 625043960, 629512740, 633942527, + 638330370, 642673418, 646968929, 651214270, 655406919, 659544468, 663624624, 667645211, 671604169, + 675499557, 679329551, 683092449, 686786663, 690410727, 693963289, 697443117, 700849092, 704180212, + 707435589, 710614445, 713716116, 716740046, 719685788, 722553001, 725341451, 728051005, 730681634, + 733233409, 735706498, 738101168, 740417780, 742656787, 744818734, 746904257, 748914076, 750848997, + 752709910, 754497783, 756213660, 757858664, 759433984, 760940881, 762380680, 763754766, 765064584, + 766311629, 767497450, 768623637, 769691823, 770703677, 771660899, 772565218, 773418381, 774222155, + 774978320, 775688661, 776354967, 776979026, 777562617, 778107510, 778615459, 779088198, 779527438, + 779934863, 780312126, 780660846, 780982606, 781278948, 781551373, 781801337, 782030250, 782239474, + 782430322, 782604056, 782761888, 782904976, 783034427, 783151295, 783256582, 783351237, 783436158, + 783512191, 783580133, 783640729, 783694677, 783742630, 783785193, 783822926, 783856349, 783885939, + 783912134, 783935335, 783955909, 783974185, 783990464, 784005015, 784018080, 784029874, 784040589, + 784050394, 784059435, 784067843, 784075728, 784083188, 784090303, 784097145, 784103769, 784110225, + 784116552, 784122782, 784128939, 784135042, 784141107, 784147142, 784153152, 784159138, 784165118, + 784171086, 784177037, 784182968, 784188874, 784194749, 784200591, 784206393, 784212151, 784217862, + 784223520, 784229122, 784234663, 784240139, 784245546, 784250879, 784256136, 784261311, 784266402, + 784271403, 784276313, 784281126, 784285841, 784290452, 784294958, 784299354, 784303638, 784307807, + 784311858, 784315788, 784319595, 784323276, 784326828, 784330250, 784333539, 784336693, 784339710, + 784342589, 784345327, 784347923, 784350376, 784352685, 784354847, 784356862, 784358729, 784360447, + 784362016, 784363434, 784364702, 784365818, 784366783, 784367596, 784368257, 784368766, 784369124, + 784369331, 784369387, 784369292, 784369047, 784368653, 784368111, 784367421, 784366584, 784365602, + 784364475, 784363205, 784361793, 784360241, 784358550, 784356721, 784354756, 784352657, 784350426, + 784348065, 784345575, 784342958, 784340217, 784337354, 784334371, 784331270, 784328053, 784324723, + 784321282, 784317734, 784314079, 784310321, 784306463, 784302507, 784298456, 784294312, 784290078, + 784285758, 784281354, 784276869, 784272306, 784267667, 784262957, 784258177, 784253332, 784248423, + 784243454, 784238429, 784233349, 784228220, 784223043, 784217822, 784212560, 784207260, 784201926, + 784196560, 784191167, 784185749, 784180310, 784174852, 784169380, 784163896, 784158404, 784152907, + 784147408, 784141911, 784136419, 784130935, 784125463, 784120006, 784114567, 784109150, 784103757, + 784098392, 784093059, 784087760, 784082499, 784077278, 784072102, 784066974, 784061896, 784056872, + 784051904, 784046997, 784042152, 784037374, 784032665, 784028028, 784023466, 784018982, 784014580, + 784010261, 784006029, 784001887, 783997837, 783993883, 783990026, 783986270, 783982617, 783979069, + 783975630, 783972302, 783969087, 783965987, 783963005, 783960143, 783957404, 783954788, 783952300, + 783949939, 783947709, 783945612, 783943648, 783941820, 783940130, 783938578, 783937167, 783935898, + 783934772, 783933790, 783932954, 783932264, 783931722, 783931328, 783931084, 783930989, 783931045, + 783931251, 783931609, 783932118, 783932779, 783933592, 783934556, 783935672, 783936938, 783938356, + 783939924, 783941641, 783943507, 783945521, 783947682, 783949989, 783952441, 783955036, 783957773, + 783960650, 783963666, 783966818, 783970106, 783973526, 783977077, 783980756, 783984561, 783988490, + 783992539, 783996706, 784000989, 784005383, 784009887, 784014497, 784019210, 784024022, 784028930, + 784033930, 784039019, 784044193, 784049448, 784054780, 784060186, 784065661, 784071201, 784076801, + 784082459, 784088168, 784093926, 784099727, 784105568, 784111443, 784117348, 784123278, 784129229, + 784135197, 784141176, 784147163, 784153152, 784159138, 784165118, 784171086, 784177037, 784182968, + 784188874, 784194749, 784200591, 784206393, 784212151, 784217862, 784223520, 784229122, 784234663, + 784240139, 784245546, 784250879, 784256136, 784261311, 784266402, 784271403, 784276313, 784281126, + 784285841, 784290452, 784294958, 784299354, 784303638, 784307807, 784311858, 784315788, 784319595, + 784323276, 784326828, 784330250, 784333539, 784336693, 784339710, 784342589, 784345327, 784347923, + 784350376, 784352685, 784354847, 784356862, 784358729, 784360447, 784362016, 784363434, 784364702, + 784365818, 784366783, 784367596, 784368257, 784368766, 784369124, 784369331, 784369387, 784369292, + 784369047, 784368653, 784368111, 784367421, 784366584, 784365602, 784364475, 784363205, 784361793, + 784360241, 784358550, 784356721, 784354756, 784352657, 784350426, 784348065, 784345575, 784342958, + 784340217, 784337354, 784334371, 784331270, 784328053, 784324723, 784321282, 784317734, 784314079, + 784310321, 784306463, 784302507, 784298456, 784294312, 784290078, 784285758, 784281354, 784276869, + 784272306, 784267667, 784262957, 784258177, 784253332, 784248423, 784243454, 784238429, 784233349, + 784228220, 784223043, 784217822, 784212560, 784207260, 784201926, 784196560, 784191167, 784185749, + 784180310, 784174852, 784169380, 784163896, 784158404, 784152907, -784147408, -784141911, -784136419, + -784130935, -784125463, -784120006, -784114567, -784109150, -784103757, -784098392, -784093059, -784087760, + -784082499, -784077278, -784072102, -784066974, -784061896, -784056872, -784051904, -784046997, -784042152, + -784037374, -784032665, -784028028, -784023466, -784018982, -784014580, -784010261, -784006029, -784001887, + -783997837, -783993883, -783990026, -783986270, -783982617, -783979069, -783975630, -783972302, -783969087, + -783965987, -783963005, -783960143, -783957404, -783954788, -783952300, -783949939, -783947709, -783945612, + -783943648, -783941820, -783940130, -783938578, -783937167, -783935898, -783934772, -783933790, -783932954, + -783932264, -783931722, -783931328, -783931084, -783930989, -783931045, -783931251, -783931609, -783932118, + -783932779, -783933592, -783934556, -783935672, -783936938, -783938356, -783939924, -783941641, -783943507, + -783945521, -783947682, -783949989, -783952441, -783955036, -783957773, -783960650, -783963666, -783966818, + -783970106, -783973526, -783977077, -783980756, -783984561, -783988490, -783992539, -783996706, -784000989, + -784005383, -784009887, -784014497, -784019210, -784024022, -784028930, -784033930, -784039019, -784044193, + -784049448, -784054780, -784060186, -784065661, -784071201, -784076801, -784082459, -784088168, -784093926, + -784099727, -784105568, -784111443, -784117348, -784123278, -784129229, -784135197, -784141176, -784147163, + -784153152, -784159138, -784165118, -784171086, -784177037, -784182968, -784188874, -784194749, -784200591, + -784206393, -784212151, -784217862, -784223520, -784229122, -784234663, -784240139, -784245546, -784250879, + -784256136, -784261311, -784266402, -784271403, -784276313, -784281126, -784285841, -784290452, -784294958, + -784299354, -784303638, -784307807, -784311858, -784315788, -784319595, -784323276, -784326828, -784330250, + -784333539, -784336693, -784339710, -784342589, -784345327, -784347923, -784350376, -784352685, -784354847, + -784356862, -784358729, -784360447, -784362016, -784363434, -784364702, -784365818, -784366783, -784367596, + -784368257, -784368766, -784369124, -784369331, -784369387, -784369292, -784369047, -784368653, -784368111, + -784367421, -784366584, -784365602, -784364475, -784363205, -784361793, -784360241, -784358550, -784356721, + -784354756, -784352657, -784350426, -784348065, -784345575, -784342958, -784340217, -784337354, -784334371, + -784331270, -784328053, -784324723, -784321282, -784317734, -784314079, -784310321, -784306463, -784302507, + -784298456, -784294312, -784290078, -784285758, -784281354, -784276869, -784272306, -784267667, -784262957, + -784258177, -784253332, -784248423, -784243454, -784238429, -784233349, -784228220, -784223043, -784217822, + -784212560, -784207260, -784201926, -784196560, -784191167, -784185749, -784180310, -784174852, -784169380, + -784163896, -784158404, -784152907, -784147408, -784141911, -784136419, -784130935, -784125463, -784120006, + -784114567, -784109150, -784103757, -784098392, -784093059, -784087760, -784082499, -784077278, -784072102, + -784066974, -784061896, -784056872, -784051904, -784046997, -784042152, -784037374, -784032665, -784028028, + -784023466, -784018982, -784014580, -784010261, -784006029, -784001887, -783997837, -783993883, -783990026, + -783986270, -783982617, -783979069, -783975630, -783972302, -783969087, -783965987, -783963005, -783960143, + -783957404, -783954788, -783952300, -783949939, -783947709, -783945612, -783943648, -783941820, -783940130, + -783938578, -783937167, -783935898, -783934772, -783933790, -783932954, -783932264, -783931722, -783931328, + -783931084, -783930989, -783931045, -783931251, -783931609, -783932118, -783932779, -783933592, -783934556, + -783935672, -783936938, -783938356, -783939924, -783941641, -783943507, -783945521, -783947682, -783949989, + -783952441, -783955036, -783957773, -783960650, -783963666, -783966818, -783970106, -783973526, -783977077, + -783980756, -783984561, -783988490, -783992539, -783996706, -784000989, -784005383, -784009887, -784014497, + -784019210, -784024022, -784028930, -784033930, -784039019, -784044193, -784049448, -784054780, -784060186, + -784065661, -784071201, -784076801, -784082459, -784088168, -784093926, -784099727, -784105568, -784111443, + -784117348, -784123278, -784129229, -784135197, -784141176, -784147163, -784153131, -784159068, -784164963, + -784170795, -784176541, -784182173, -784187657, -784192951, -784198007, -784202769, -784207169, -784211130, + -784214559, -784217353, -784219391, -784220535, -784220630, -784219497, -784216937, -784212727, -784206617, + -784198327, -784187551, -784173947, -784157141, -784136723, -784112243, -784083213, -784049101, -784009333, + -783963287, -783910294, -783849634, -783780538, -783702180, -783613679, -783514100, -783402445, -783277658, + -783138617, -782984141, -782812977, -782623808, -782415247, -782185834, -781934039, -781658253, -781356794, + -781027899, -780669728, -780280356, -779857776, -779399894, -778904531, -778369419, -777792197, -777170416, + -776501532, -775782908, -775011810, -774185411, -773300787, -772354919, -771344691, -770266894, -769118226, + -767895293, -766594614, -765212620, -763745664, -762190019, -760541889, -758797411, -756952664, -755003678, + -752946440, -750776904, -748491005, -746084664, -743553805, -740894366, -738102311, -735173645, -732104432, + -728890802, -725528974, -722015270, -718346128, -714518120, -710527972, -706372573, -702048997, -697554517, + -692886621, -688043026, -683021694, -677820848, -672438982, -666874876, -661127608, -655196568, -649081463, + -642782332, -636299553, -629633851, -622786302, -615758346, -608551783, -601168786, -593611894, -585884022, + -577988458, -569928861, -561709265, -553334069, -544808041, -536136306, -527324347, -518377994, -509303418, + -500107123, -490795932, -481376983, -471857712, -462245842, -452549370, -442776550, -432935882, -423036090, + -413086109, -403095064, -393072251, -383027119, -372969246, -362908319, -352854112, -342816459, -332805234, + -322830326, -312901609, -303028921, -293222034, -283490629, -273844269, -264292369, -254844170, -245508712, + -236294804, -227211000, -218265568, -209466468, -200821323, -192337394, -184021561, -175880295, -167919639, + -160145191, -152562081, -145174961, -137987988, -131004813, -124228572, -117661879, -111306824, -105164969, + -99237348, -93524475, -88026347, -82742454, -77671790, -72812867, -68163733, -63721988, -59484805, + -55448955, -51610827, -47966456, -44511550, -41241516, -38151492, -35236370, -32490831, -29909374, + -27486341, -25215951, -23092326, -21109518, -19261540, -17542387, -15946062, -14466601, -13098096, + -11834709, -10670701, -9600439, -8618419, -7719279, -6897809, -6148962, -5467868, -4849835, + -4290361, -3785136, -3330046, -2921175, -2554807, -2227423, -1935704, -1676526, -1446955, + -1244248, -1065844, -909363, -772594, -653495, -550182, -460924, -384136, -318370, + -262309, -214759, -174641, -140984, -112917, -89663, -70531, -54908, -42257, + -32104, -24037, -17698, -12781, -9020, -6190, -4103, -2600, -1548, + -839, -385, -115 }; +#endif /* ENABLE_HR_MODE */ + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_2_5ms[2] = { LowDelayShapes_n960_N480_HRA_2_5ms_IP, + LowDelayShapes_n960_N960_HRA_2_5ms_IP }; + +RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_5ms[2] = { LowDelayShapes_n960_N480_HRA_5ms_IP, + LowDelayShapes_n960_N960_HRA_5ms_IP }; + +RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA[2] = { LowDelayShapes_n960_N480_HRA_IP, + LowDelayShapes_n960_N960_HRA_IP }; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_7_5ms[2] = { LowDelayShapes_n960_N480_HRA_7_5ms_IP, + LowDelayShapes_n960_N960_HRA_7_5ms_IP }; +# endif +#endif /* ENABLE_HR_MODE */ + +RAM_ALIGN const Word16 pitch_max[5] = {MAX_PITCH_8K, MAX_PITCH_16K, MAX_PITCH_24K, MAX_PITCH_32K, MAX_PITCH_48K}; +RAM_ALIGN const Word16 plc_preemph_fac[NUM_SAMP_FREQ] = {20316, 23592, 26869, 30146, 30146 +# ifdef ENABLE_HR_MODE + , 30146 +# endif + }; +/* high pass filter Q15 */ +RAM_ALIGN const Word16 TDC_high_16[11] = {(Word16)0x0000, (Word16)0xfd60, (Word16)0xf7ab, (Word16)0xefec, + (Word16)0xe910, (Word16)0x66c2, (Word16)0xe910, (Word16)0xefec, + (Word16)0xf7ab, (Word16)0xfd60, (Word16)0x0000}; + +RAM_ALIGN const Word16 TDC_high_32[11] = {(Word16)0xf962, (Word16)0xf87d, (Word16)0xf581, (Word16)0xf2e5, + (Word16)0xf11a, (Word16)0x7076, (Word16)0xf11a, (Word16)0xf2e5, + (Word16)0xf581, (Word16)0xf87d, (Word16)0xf962}; + +RAM_ALIGN const Word16 TDC_high_16_harm[11] = {(Word16) 174, (Word16) 0, (Word16) -1442, (Word16) 0, + (Word16) 8641, (Word16) 18022, (Word16) 8641, (Word16) 0, + (Word16) -1442, (Word16) 0, (Word16) 174}; + +RAM_ALIGN const Word16 TDC_high_32_harm[11] = {(Word16) -174, (Word16) -121, (Word16) -459, (Word16) 590, + (Word16) 8743, (Word16) 16355, (Word16) 8743, (Word16) 590, + (Word16) -459, (Word16) -121, (Word16) -174}; + + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 LowDelayShapes_n960_N80[130] = { + -15, -43, -94, -171, -277, -414, -580, -771, -981, -1201, -1423, -1638, -1836, + -2008, -2145, -2240, -2286, -2279, -2214, -2085, -1889, -1621, -1274, -842, -318, 305, + 1034, 1876, 2833, 3906, 5091, 6379, 7754, 9198, 10683, 12179, 13652, 15068, 16390, + 17588, 18634, 19509, 20201, 20712, 21051, 21237, 21297, 21263, 21168, 21044, 20918, 20797, + 20701, 20627, 20571, 20529, 20499, 20479, 20468, 20463, 20464, 20469, 20477, 20486, 20495, + 20503, 20509, 20514, 20516, 20518, 20520, 20524, 20530, 20540, 20556, 20576, 20602, 20633, + 20668, 20705, -20743, -20781, -20816, -20847, -20873, -20894, -20910, -20920, -20927, -20930, -20932, + -20934, -20937, -20942, -20948, -20956, -20966, -20975, -20982, -20988, -20989, -20984, -20972, -20952, + -20921, -20879, -20822, -20747, -20652, -20532, -20359, -20121, -19785, -19318, -18689, -17873, -16855, + -15636, -14231, -12670, -10997, -9266, -7542, -5889, -4373, -3051, -1965, -1136, -560, -207}; +#else +#define LowDelayShapes_n960_N80 NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 LowDelayShapes_n960_N160[260] = { + -14, -29, -49, -76, -112, -156, -210, -275, -350, -437, -534, -641, -759, -885, + -1020, -1163, -1311, -1464, -1620, -1777, -1935, -2090, -2242, -2390, -2530, -2661, -2783, -2893, + -2990, -3073, -3140, -3191, -3224, -3238, -3233, -3208, -3162, -3094, -3003, -2889, -2751, -2587, + -2397, -2180, -1935, -1661, -1355, -1018, -648, -244, 197, 674, 1190, 1745, 2340, 2976, + 3652, 4370, 5129, 5928, 6766, 7642, 8553, 9496, 10470, 11469, 12490, 13529, 14579, 15637, + 16696, 17750, 18792, 19817, 20819, 21791, 22727, 23621, 24469, 25264, 26004, 26685, 27304, 27858, + 28348, 28773, 29134, 29433, 29672, 29855, 29986, 30070, 30112, 30117, 30092, 30043, 29976, 29895, + 29807, 29716, 29632, 29536, 29451, 29374, 29307, 29247, 29195, 29149, 29109, 29075, 29045, 29020, + 28999, 28982, 28968, 28957, 28949, 28943, 28940, 28939, 28940, 28942, 28946, 28950, 28956, 28962, + 28968, 28975, 28981, 28987, 28993, 28998, 29002, 29006, 29009, 29012, 29014, 29015, 29017, 29018, + 29019, 29021, 29024, 29027, 29031, 29037, 29044, 29053, 29064, 29077, 29091, 29108, 29126, 29146, + 29168, 29192, 29216, 29242, 29268, 29295, -29322, -29349, -29376, -29401, -29426, -29450, -29472, -29492, + -29511, -29527, -29542, -29555, -29566, -29575, -29583, -29589, -29593, -29596, -29599, -29601, -29602, -29603, + -29605, -29606, -29608, -29611, -29614, -29618, -29623, -29628, -29634, -29640, -29646, -29653, -29660, -29666, + -29671, -29676, -29680, -29682, -29683, -29682, -29678, -29673, -29664, -29653, -29639, -29621, -29600, -29574, + -29544, -29509, -29469, -29423, -29370, -29310, -29243, -29167, -29083, -28988, -28861, -28718, -28551, -28351, + -28114, -27834, -27505, -27121, -26677, -26168, -25591, -24943, -24223, -23431, -22569, -21639, -20644, -19592, + -18487, -17338, -16154, -14944, -13719, -12491, -11270, -10068, -8898, -7771, -6698, -5689, -4753, -3898, + -3130, -2452, -1866, -1371, -964, -640, -392, -198}; +#else +#define LowDelayShapes_n960_N160 NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N240[390] = { + -9, -17, -26, -37, -50, -66, -86, -108, -134, -164, -197, -234, -275, -320, + -369, -422, -479, -539, -603, -670, -741, -814, -891, -969, -1050, -1132, -1216, -1301, + -1387, -1473, -1558, -1643, -1728, -1810, -1892, -1971, -2047, -2120, -2190, -2256, -2318, -2376, + -2429, -2477, -2519, -2556, -2586, -2611, -2629, -2640, -2645, -2642, -2632, -2614, -2589, -2556, + -2515, -2466, -2408, -2341, -2266, -2182, -2088, -1985, -1872, -1748, -1615, -1471, -1316, -1150, + -972, -783, -582, -368, -141, 99, 352, 619, 899, 1194, 1503, 1827, 2166, 2519, + 2888, 3271, 3669, 4082, 4510, 4952, 5408, 5878, 6362, 6857, 7365, 7885, 8414, 8954, + 9502, 10058, 10621, 11189, 11761, 12335, 12912, 13488, 14063, 14635, 15203, 15764, 16319, 16864, + 17399, 17922, 18431, 18926, 19405, 19866, 20309, 20732, 21135, 21517, 21876, 22213, 22526, 22817, + 23083, 23326, 23546, 23743, 23916, 24068, 24198, 24308, 24397, 24469, 24522, 24560, 24582, 24592, + 24589, 24575, 24552, 24522, 24485, 24443, 24398, 24349, 24300, 24252, 24209, 24155, 24104, 24058, + 24014, 23974, 23938, 23904, 23873, 23844, 23818, 23794, 23773, 23753, 23735, 23719, 23705, 23692, + 23681, 23670, 23662, 23654, 23647, 23642, 23638, 23634, 23632, 23630, 23629, 23629, 23629, 23630, + 23632, 23634, 23636, 23639, 23642, 23645, 23648, 23652, 23655, 23658, 23662, 23665, 23669, 23672, + 23674, 23677, 23680, 23682, 23684, 23686, 23687, 23688, 23689, 23690, 23691, 23692, 23693, 23693, + 23694, 23695, 23696, 23697, 23699, 23701, 23703, 23706, 23710, 23714, 23718, 23723, 23729, 23736, + 23743, 23751, 23760, 23769, 23779, 23790, 23801, 23813, 23825, 23838, 23851, 23865, 23879, 23894, + 23908, 23923, -23938, -23952, -23967, -23981, -23996, -24010, -24023, -24036, -24049, -24061, -24072, -24083, + -24093, -24102, -24111, -24119, -24127, -24133, -24139, -24145, -24149, -24153, -24157, -24160, -24162, -24164, + -24166, -24167, -24168, -24169, -24170, -24171, -24171, -24172, -24173, -24174, -24175, -24176, -24178, -24179, + -24181, -24184, -24186, -24189, -24192, -24195, -24198, -24202, -24205, -24209, -24213, -24216, -24219, -24223, + -24226, -24228, -24231, -24233, -24234, -24235, -24236, -24236, -24235, -24233, -24230, -24227, -24222, -24217, + -24210, -24202, -24193, -24183, -24171, -24158, -24143, -24127, -24109, -24089, -24067, -24043, -24017, -23988, + -23957, -23923, -23886, -23847, -23804, -23758, -23708, -23655, -23584, -23509, -23427, -23336, -23234, -23119, + -22990, -22846, -22685, -22506, -22307, -22087, -21845, -21580, -21291, -20977, -20638, -20272, -19880, -19462, + -19018, -18549, -18054, -17536, -16995, -16432, -15849, -15248, -14630, -13997, -13353, -12698, -12036, -11369, + -10700, -10032, -9367, -8709, -8059, -7422, -6800, -6196, -5611, -5050, -4513, -4004, -3523, -3073, + -2655, -2269, -1917, -1598, -1312, -1059, -837, -646, -484, -350, -239, -127}; +#else +#define LowDelayShapes_n960_N240 NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N320[520] = { + -6, -12, -17, -23, -30, -39, -48, -60, -72, -86, -102, -119, -138, -159, + -182, -207, -234, -262, -293, -325, -359, -396, -434, -473, -515, -558, -603, -649, + -697, -746, -797, -848, -900, -954, -1008, -1062, -1118, -1173, -1229, -1285, -1340, -1396, + -1451, -1505, -1559, -1612, -1664, -1715, -1764, -1813, -1859, -1904, -1947, -1988, -2027, -2064, + -2098, -2130, -2159, -2186, -2210, -2230, -2248, -2263, -2275, -2283, -2289, -2290, -2289, -2283, + -2274, -2262, -2245, -2225, -2201, -2173, -2141, -2105, -2065, -2020, -1971, -1918, -1860, -1797, + -1730, -1658, -1582, -1500, -1414, -1322, -1225, -1122, -1014, -901, -782, -657, -526, -389, + -246, -97, 59, 221, 390, 565, 748, 937, 1133, 1336, 1547, 1764, 1989, 2221, + 2460, 2707, 2961, 3222, 3490, 3765, 4048, 4338, 4634, 4937, 5246, 5562, 5884, 6212, + 6546, 6885, 7229, 7578, 7932, 8289, 8650, 9014, 9382, 9751, 10123, 10496, 10870, 11244, + 11619, 11992, 12365, 12736, 13105, 13471, 13833, 14192, 14546, 14895, 15239, 15576, 15907, 16231, + 16547, 16856, 17155, 17446, 17727, 17999, 18261, 18512, 18753, 18983, 19202, 19409, 19605, 19790, + 19963, 20125, 20275, 20414, 20541, 20658, 20764, 20858, 20943, 21017, 21082, 21137, 21184, 21221, + 21251, 21273, 21287, 21295, 21297, 21293, 21285, 21271, 21254, 21233, 21209, 21182, 21154, 21124, + 21092, 21060, 21028, 20999, 20972, 20935, 20902, 20870, 20839, 20811, 20784, 20758, 20734, 20712, + 20691, 20671, 20653, 20635, 20619, 20604, 20590, 20577, 20565, 20554, 20543, 20534, 20525, 20517, + 20509, 20502, 20496, 20491, 20486, 20481, 20477, 20474, 20471, 20469, 20467, 20465, 20464, 20464, + 20463, 20463, 20463, 20464, 20465, 20466, 20467, 20468, 20470, 20472, 20474, 20476, 20478, 20480, + 20482, 20485, 20487, 20489, 20491, 20494, 20496, 20498, 20500, 20502, 20504, 20505, 20507, 20508, + 20510, 20511, 20512, 20513, 20514, 20515, 20516, 20516, 20517, 20517, 20518, 20518, 20519, 20519, + 20519, 20520, 20521, 20521, 20522, 20523, 20524, 20526, 20527, 20529, 20531, 20533, 20536, 20539, + 20542, 20546, 20549, 20554, 20558, 20563, 20568, 20573, 20579, 20586, 20592, 20599, 20606, 20613, + 20621, 20629, 20637, 20646, 20655, 20663, 20672, 20682, 20691, 20700, 20710, 20720, -20729, -20739, + -20748, -20758, -20767, -20776, -20785, -20794, -20803, -20812, -20820, -20828, -20836, -20843, -20851, -20857, + -20864, -20870, -20876, -20882, -20887, -20892, -20896, -20901, -20905, -20908, -20911, -20914, -20917, -20919, + -20921, -20923, -20925, -20926, -20927, -20928, -20929, -20930, -20931, -20931, -20932, -20932, -20933, -20933, + -20934, -20934, -20935, -20935, -20936, -20937, -20938, -20939, -20940, -20941, -20943, -20944, -20946, -20947, + -20949, -20951, -20953, -20955, -20958, -20960, -20962, -20964, -20967, -20969, -20971, -20974, -20976, -20978, + -20980, -20982, -20983, -20985, -20986, -20987, -20988, -20989, -20989, -20989, -20988, -20988, -20986, -20985, + -20983, -20980, -20978, -20974, -20970, -20966, -20961, -20955, -20949, -20942, -20934, -20926, -20917, -20907, + -20896, -20885, -20873, -20859, -20845, -20830, -20814, -20796, -20778, -20758, -20737, -20714, -20690, -20665, + -20638, -20610, -20580, -20548, -20515, -20480, -20433, -20384, -20333, -20279, -20220, -20155, -20085, -20008, + -19924, -19833, -19734, -19627, -19511, -19385, -19249, -19103, -18946, -18778, -18598, -18406, -18202, -17986, + -17757, -17515, -17260, -16993, -16713, -16421, -16116, -15799, -15470, -15129, -14778, -14415, -14043, -13661, + -13271, -12872, -12466, -12053, -11634, -11210, -10782, -10351, -9918, -9484, -9049, -8616, -8184, -7755, + -7330, -6910, -6496, -6090, -5691, -5301, -4922, -4553, -4196, -3852, -3521, -3204, -2902, -2615, + -2343, -2087, -1847, -1624, -1417, -1226, -1051, -892, -748, -619, -504, -404, -316, -241, + -175, -92}; +#else +#define LowDelayShapes_n960_N320 NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 LowDelayShapes_n960_N480[780] = { + -4, -8, -11, -13, -16, -20, -24, -28, -33, -38, -44, -50, -57, -64, + -72, -81, -90, -100, -110, -121, -133, -146, -159, -173, -187, -202, -218, -235, + -252, -270, -289, -308, -328, -349, -370, -392, -415, -438, -462, -486, -511, -537, + -563, -589, -616, -643, -671, -699, -728, -757, -786, -815, -845, -875, -905, -935, + -965, -996, -1026, -1056, -1087, -1117, -1147, -1177, -1207, -1236, -1266, -1295, -1323, -1352, + -1380, -1407, -1434, -1461, -1486, -1512, -1537, -1561, -1584, -1607, -1629, -1650, -1670, -1690, + -1709, -1726, -1743, -1759, -1774, -1788, -1801, -1813, -1824, -1834, -1842, -1850, -1856, -1861, + -1865, -1868, -1870, -1870, -1869, -1867, -1863, -1858, -1852, -1845, -1836, -1826, -1814, -1801, + -1786, -1770, -1753, -1734, -1713, -1691, -1668, -1643, -1616, -1588, -1558, -1527, -1494, -1459, + -1422, -1384, -1344, -1302, -1259, -1213, -1166, -1117, -1066, -1013, -959, -902, -843, -783, + -720, -655, -588, -519, -448, -374, -299, -221, -141, -58, 27, 114, 203, 295, + 389, 486, 585, 687, 791, 898, 1007, 1119, 1234, 1351, 1471, 1593, 1718, 1846, + 1976, 2109, 2244, 2382, 2523, 2667, 2813, 2961, 3113, 3266, 3423, 3582, 3743, 3907, + 4073, 4241, 4412, 4585, 4760, 4938, 5117, 5299, 5483, 5668, 5855, 6045, 6235, 6428, + 6622, 6817, 7013, 7211, 7410, 7610, 7811, 8012, 8215, 8417, 8621, 8824, 9028, 9232, + 9436, 9639, 9843, 10045, 10248, 10449, 10650, 10850, 11048, 11246, 11442, 11636, 11829, 12020, + 12209, 12396, 12581, 12763, 12944, 13121, 13296, 13468, 13638, 13804, 13967, 14127, 14284, 14437, + 14586, 14732, 14875, 15014, 15148, 15280, 15407, 15530, 15649, 15764, 15875, 15981, 16084, 16183, + 16277, 16367, 16453, 16535, 16612, 16686, 16755, 16821, 16882, 16940, 16993, 17043, 17089, 17131, + 17170, 17205, 17237, 17265, 17291, 17313, 17331, 17348, 17361, 17371, 17379, 17385, 17388, 17389, + 17388, 17385, 17380, 17374, 17366, 17356, 17345, 17333, 17320, 17306, 17292, 17276, 17260, 17243, + 17226, 17209, 17191, 17174, 17157, 17142, 17128, 17108, 17089, 17071, 17053, 17036, 17019, 17003, + 16988, 16973, 16959, 16946, 16933, 16920, 16908, 16897, 16886, 16875, 16865, 16856, 16846, 16838, + 16829, 16821, 16814, 16806, 16799, 16793, 16786, 16780, 16775, 16769, 16764, 16759, 16755, 16751, + 16747, 16743, 16739, 16736, 16733, 16730, 16727, 16725, 16722, 16720, 16718, 16717, 16715, 16714, + 16712, 16711, 16711, 16710, 16709, 16709, 16708, 16708, 16708, 16708, 16708, 16708, 16709, 16709, + 16710, 16710, 16711, 16712, 16713, 16714, 16715, 16716, 16717, 16718, 16719, 16720, 16721, 16722, + 16724, 16725, 16726, 16727, 16728, 16730, 16731, 16732, 16733, 16734, 16736, 16737, 16738, 16739, + 16740, 16741, 16742, 16743, 16744, 16744, 16745, 16746, 16747, 16747, 16748, 16748, 16749, 16750, + 16750, 16750, 16751, 16751, 16751, 16752, 16752, 16752, 16753, 16753, 16753, 16753, 16753, 16754, + 16754, 16754, 16755, 16755, 16755, 16756, 16756, 16757, 16757, 16758, 16759, 16759, 16760, 16761, + 16762, 16763, 16765, 16766, 16767, 16769, 16770, 16772, 16774, 16776, 16778, 16780, 16782, 16785, + 16787, 16790, 16793, 16796, 16799, 16802, 16805, 16809, 16812, 16816, 16820, 16824, 16828, 16832, + 16836, 16840, 16845, 16849, 16854, 16858, 16863, 16868, 16873, 16878, 16883, 16888, 16893, 16898, + 16903, 16908, 16914, 16919, -16924, -16929, -16934, -16940, -16945, -16950, -16955, -16960, -16965, -16970, + -16975, -16980, -16984, -16989, -16994, -16998, -17003, -17007, -17011, -17015, -17020, -17023, -17027, -17031, + -17035, -17038, -17041, -17045, -17048, -17051, -17053, -17056, -17059, -17061, -17064, -17066, -17068, -17070, + -17072, -17074, -17075, -17077, -17078, -17080, -17081, -17082, -17083, -17084, -17085, -17086, -17086, -17087, + -17088, -17088, -17089, -17089, -17089, -17090, -17090, -17090, -17091, -17091, -17091, -17091, -17092, -17092, + -17092, -17092, -17093, -17093, -17093, -17094, -17094, -17094, -17095, -17095, -17096, -17097, -17097, -17098, + -17099, -17099, -17100, -17101, -17102, -17103, -17104, -17105, -17106, -17107, -17108, -17109, -17110, -17111, + -17113, -17114, -17115, -17116, -17118, -17119, -17120, -17121, -17123, -17124, -17125, -17126, -17127, -17129, + -17130, -17131, -17132, -17133, -17133, -17134, -17135, -17136, -17136, -17137, -17137, -17137, -17137, -17137, + -17137, -17137, -17137, -17136, -17136, -17135, -17134, -17133, -17132, -17130, -17129, -17127, -17125, -17123, + -17120, -17118, -17115, -17112, -17109, -17105, -17102, -17098, -17094, -17089, -17085, -17080, -17075, -17069, + -17063, -17057, -17051, -17044, -17037, -17030, -17022, -17014, -17005, -16997, -16987, -16978, -16967, -16957, + -16946, -16934, -16922, -16910, -16897, -16883, -16869, -16855, -16840, -16824, -16808, -16791, -16773, -16755, + -16736, -16717, -16690, -16663, -16637, -16609, -16581, -16550, -16518, -16484, -16448, -16409, -16369, -16326, + -16280, -16232, -16181, -16127, -16070, -16010, -15947, -15880, -15810, -15736, -15658, -15577, -15491, -15402, + -15308, -15210, -15108, -15001, -14890, -14775, -14655, -14530, -14401, -14267, -14128, -13985, -13837, -13685, + -13528, -13367, -13201, -13030, -12855, -12676, -12493, -12306, -12114, -11919, -11720, -11517, -11311, -11102, + -10889, -10674, -10455, -10234, -10010, -9784, -9556, -9327, -9095, -8862, -8628, -8393, -8157, -7921, + -7684, -7448, -7211, -6976, -6741, -6507, -6274, -6042, -5813, -5585, -5360, -5137, -4917, -4700, + -4487, -4276, -4070, -3867, -3668, -3474, -3284, -3099, -2919, -2744, -2574, -2410, -2251, -2097, + -1949, -1807, -1671, -1540, -1415, -1297, -1184, -1077, -976, -881, -791, -707, -629, -556, + -489, -427, -369, -317, -269, -226, -188, -151, -114, -59}; +#else +#define LowDelayShapes_n960_N480 NULL +#endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 LowDelayShapes_n960_N40_5ms[70] = { + 29, 112, 280, 563, 991, 1590, 2380, 3377, 4587, 6006, 7624, 9416, 11353, 13393, + 15490, 17595, 19657, 21624, 23450, 25092, 26519, 27707, 28645, 29332, 29783, 30021, 30083, 30008, + 29840, 29625, 29408, 29214, 29077, 28993, 28956, 28961, 29000, 29068, 29156, 29256, -29361, -29462, + -29551, -29620, -29661, -29666, -29628, -29542, -29403, -29209, -28923, -28521, -27962, -27210, -26234, -25014, + -23541, -21819, -19874, -17743, -15481, -13149, -10820, -8571, -6479, -4611, -3020, -1753, -842, -284}; +#else +#define LowDelayShapes_n960_N40_5ms NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 LowDelayShapes_n960_N80_5ms[140] = { + 13, 31, 60, 102, 161, 239, 339, 464, 615, 795, 1006, 1251, 1530, 1845, + 2198, 2588, 3015, 3481, 3983, 4520, 5092, 5697, 6331, 6992, 7677, 8382, 9104, 9838, + 10580, 11326, 12071, 12811, 13540, 14255, 14951, 15624, 16270, 16885, 17466, 18010, 18515, 18978, + 19399, 19775, 20106, 20393, 20636, 20836, 20995, 21115, 21199, 21250, 21271, 21266, 21239, 21194, + 21134, 21064, 20987, 20908, 20836, 20757, 20688, 20630, 20581, 20542, 20513, 20491, 20478, 20473, + 20475, 20483, 20497, 20517, 20541, 20568, 20600, 20633, 20669, 20706, -20743, -20780, -20816, -20850, + -20881, -20910, -20934, -20954, -20968, -20977, -20979, -20973, -20960, -20938, -20908, -20868, -20819, -20761, + -20692, -20613, -20508, -20389, -20248, -20080, -19883, -19653, -19387, -19083, -18738, -18351, -17920, -17444, + -16923, -16358, -15749, -15099, -14410, -13687, -12933, -12154, -11353, -10537, -9712, -8884, -8060, -7246, + -6450, -5679, -4938, -4235, -3574, -2959, -2397, -1889, -1441, -1055, -732, -474, -277, -138}; +#else +#define LowDelayShapes_n960_N80_5ms NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N120_5ms[210] = { + 9, 17, 28, 44, 65, 91, 123, 161, 208, 262, 325, 398, 480, 572, + 676, 791, 918, 1057, 1209, 1374, 1552, 1744, 1950, 2169, 2402, 2648, 2908, 3181, + 3468, 3767, 4078, 4402, 4736, 5081, 5437, 5801, 6174, 6554, 6942, 7335, 7732, 8134, + 8538, 8943, 9349, 9755, 10159, 10560, 10957, 11349, 11735, 12114, 12485, 12846, 13198, 13539, + 13868, 14184, 14487, 14776, 15051, 15311, 15555, 15784, 15997, 16194, 16374, 16538, 16686, 16818, + 16935, 17036, 17123, 17195, 17254, 17299, 17333, 17355, 17366, 17368, 17361, 17347, 17325, 17297, + 17265, 17228, 17189, 17147, 17104, 17061, 17024, 16979, 16938, 16901, 16867, 16837, 16811, 16788, + 16768, 16752, 16739, 16729, 16722, 16718, 16716, 16717, 16720, 16726, 16734, 16743, 16755, 16768, + 16782, 16798, 16815, 16833, 16852, 16871, 16891, 16911, -16931, -16952, -16972, -16991, -17010, -17028, + -17045, -17061, -17076, -17090, -17101, -17111, -17119, -17125, -17128, -17129, -17127, -17123, -17116, -17106, + -17092, -17076, -17056, -17033, -17006, -16976, -16942, -16905, -16864, -16820, -16760, -16698, -16630, -16553, + -16467, -16370, -16263, -16144, -16013, -15868, -15710, -15537, -15349, -15146, -14927, -14693, -14442, -14175, + -13891, -13591, -13276, -12944, -12597, -12236, -11862, -11474, -11074, -10664, -10244, -9816, -9380, -8938, + -8492, -8043, -7592, -7141, -6692, -6247, -5807, -5374, -4949, -4534, -4131, -3741, -3365, -3005, + -2662, -2337, -2030, -1744, -1478, -1234, -1012, -814, -638, -486, -357, -250, -164, -95}; +#else +#define LowDelayShapes_n960_N120_5ms NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N160_5ms[280] = { + 13, 23, 36, 52, 73, 98, 128, 163, 205, 253, 308, 371, 441, 520, + 608, 705, 812, 929, 1056, 1195, 1344, 1505, 1678, 1863, 2060, 2270, 2493, 2729, + 2978, 3241, 3516, 3805, 4108, 4424, 4753, 5095, 5450, 5818, 6198, 6591, 6995, 7411, + 7839, 8277, 8725, 9184, 9651, 10128, 10612, 11104, 11603, 12108, 12618, 13133, 13653, 14175, + 14700, 15226, 15754, 16281, 16808, 17334, 17857, 18376, 18892, 19403, 19909, 20408, 20901, 21385, + 21861, 22328, 22784, 23231, 23666, 24089, 24500, 24898, 25283, 25654, 26011, 26354, 26681, 26994, + 27291, 27572, 27838, 28089, 28323, 28541, 28744, 28931, 29103, 29259, 29401, 29528, 29640, 29738, + 29823, 29895, 29955, 30002, 30038, 30063, 30078, 30083, 30080, 30068, 30049, 30023, 29991, 29953, + 29911, 29865, 29815, 29763, 29708, 29653, 29597, 29541, 29496, 29437, 29381, 29329, 29280, 29235, + 29194, 29156, 29122, 29091, 29064, 29039, 29018, 29000, 28986, 28974, 28964, 28958, 28954, 28953, + 28954, 28958, 28964, 28972, 28982, 28994, 29007, 29023, 29040, 29058, 29078, 29099, 29121, 29144, + 29168, 29192, 29218, 29243, 29269, 29295, -29322, -29348, -29374, -29400, -29425, -29450, -29474, -29498, + -29520, -29541, -29561, -29580, -29597, -29613, -29627, -29639, -29649, -29657, -29663, -29667, -29668, -29667, + -29663, -29657, -29647, -29635, -29620, -29602, -29580, -29556, -29528, -29496, -29462, -29424, -29382, -29337, + -29288, -29236, -29181, -29122, -29041, -28964, -28880, -28788, -28688, -28579, -28460, -28332, -28193, -28042, + -27879, -27705, -27517, -27315, -27100, -26871, -26627, -26369, -26095, -25806, -25501, -25180, -24844, -24492, + -24123, -23739, -23339, -22924, -22493, -22048, -21588, -21114, -20627, -20128, -19616, -19094, -18561, -18018, + -17467, -16907, -16341, -15769, -15192, -14611, -14028, -13442, -12857, -12272, -11689, -11109, -10533, -9963, + -9400, -8846, -8300, -7765, -7241, -6730, -6232, -5749, -5282, -4830, -4396, -3979, -3581, -3202, + -2843, -2505, -2188, -1893, -1620, -1369, -1141, -936, -753, -593, -454, -336, -237, -155}; +#else +#define LowDelayShapes_n960_N160_5ms NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 LowDelayShapes_n960_N240_5ms[420] = { + 10, 15, 21, 27, 36, 45, 56, 69, 83, 100, 118, 138, 161, 186, + 214, 244, 276, 312, 350, 392, 436, 484, 535, 590, 648, 710, 775, 845, + 918, 995, 1076, 1162, 1252, 1346, 1444, 1547, 1655, 1767, 1883, 2005, 2131, 2261, + 2397, 2537, 2683, 2833, 2988, 3148, 3312, 3482, 3656, 3835, 4019, 4208, 4401, 4599, + 4801, 5008, 5220, 5436, 5656, 5880, 6109, 6342, 6578, 6818, 7063, 7310, 7562, 7816, + 8074, 8335, 8598, 8865, 9134, 9405, 9679, 9955, 10233, 10513, 10794, 11076, 11360, 11645, + 11931, 12217, 12504, 12791, 13078, 13366, 13652, 13939, 14224, 14509, 14792, 15075, 15356, 15635, + 15912, 16187, 16460, 16731, 16999, 17264, 17526, 17785, 18041, 18293, 18542, 18787, 19028, 19264, + 19497, 19725, 19949, 20168, 20382, 20592, 20796, 20996, 21190, 21379, 21563, 21741, 21914, 22082, + 22243, 22399, 22550, 22695, 22834, 22967, 23095, 23216, 23332, 23443, 23548, 23647, 23740, 23828, + 23910, 23987, 24059, 24125, 24186, 24243, 24294, 24340, 24381, 24418, 24450, 24478, 24502, 24522, + 24537, 24549, 24557, 24562, 24563, 24561, 24556, 24549, 24538, 24525, 24510, 24492, 24473, 24451, + 24428, 24404, 24378, 24351, 24323, 24294, 24264, 24234, 24204, 24173, 24143, 24112, 24093, 24059, + 24027, 23997, 23968, 23940, 23914, 23889, 23865, 23842, 23821, 23801, 23783, 23765, 23749, 23734, + 23720, 23708, 23696, 23686, 23677, 23668, 23661, 23655, 23650, 23647, 23644, 23641, 23640, 23640, + 23641, 23642, 23645, 23648, 23652, 23657, 23662, 23668, 23675, 23682, 23691, 23699, 23708, 23718, + 23728, 23739, 23750, 23762, 23774, 23786, 23799, 23812, 23825, 23839, 23853, 23866, 23881, 23895, + 23909, 23923, -23938, -23952, -23966, -23980, -23994, -24008, -24022, -24036, -24049, -24062, -24075, -24088, + -24100, -24112, -24123, -24134, -24144, -24154, -24164, -24173, -24181, -24189, -24195, -24202, -24207, -24212, + -24216, -24219, -24222, -24223, -24224, -24224, -24223, -24221, -24218, -24214, -24208, -24202, -24195, -24187, + -24177, -24167, -24155, -24142, -24128, -24113, -24097, -24079, -24060, -24040, -24019, -23996, -23972, -23947, + -23921, -23893, -23864, -23834, -23802, -23769, -23721, -23681, -23638, -23592, -23543, -23492, -23438, -23380, + -23319, -23255, -23186, -23115, -23039, -22959, -22875, -22786, -22693, -22596, -22494, -22387, -22275, -22157, + -22035, -21908, -21775, -21637, -21494, -21345, -21190, -21030, -20864, -20692, -20515, -20332, -20143, -19948, + -19748, -19541, -19329, -19112, -18888, -18659, -18425, -18185, -17940, -17690, -17434, -17174, -16909, -16639, + -16365, -16087, -15804, -15518, -15228, -14934, -14637, -14337, -14034, -13728, -13420, -13109, -12797, -12483, + -12167, -11851, -11533, -11215, -10896, -10577, -10258, -9940, -9623, -9307, -8992, -8678, -8367, -8058, + -7752, -7448, -7148, -6851, -6557, -6268, -5983, -5702, -5426, -5156, -4890, -4630, -4375, -4126, + -3884, -3647, -3417, -3194, -2977, -2767, -2565, -2369, -2181, -2001, -1829, -1664, -1507, -1358, + -1218, -1085, -961, -846, -738, -639, -547, -464, -388, -320, -259, -206, -159, -124}; +#else +#define LowDelayShapes_n960_N240_5ms NULL +#endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 LowDelayShapes_n960_N40_2_5ms[40] = { + 140, 566, 1277, 2319, 3704, 5404, 7357, 9466, 11616, 13686, 15563, 17163, 18436, 19375, + 20007, 20391, 20594, 20685, 20717, 20724, -20724, -20717, -20685, -20594, -20391, -20007, -19375, -18436, + -17163, -15563, -13686, -11616, -9466, -7357, -5404, -3704, -2319, -1277, -566, -140}; +#else +#define LowDelayShapes_n960_N40_2_5ms NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 LowDelayShapes_n960_N80_2_5ms[80] = { + 140, 353, 653, 1049, 1553, 2171, 2909, 3768, 4747, 5842, 7043, 8341, 9721, 11165, + 12655, 14170, 15688, 17188, 18649, 20051, 21376, 22610, 23739, 24756, 25656, 26436, 27099, 27650, + 28097, 28450, 28721, 28922, 29065, 29164, 29228, 29267, 29290, 29301, 29306, 29308, -29308, -29306, + -29301, -29290, -29267, -29228, -29164, -29065, -28922, -28721, -28450, -28097, -27650, -27099, -26436, -25656, + -24756, -23739, -22610, -21376, -20051, -18649, -17188, -15688, -14170, -12655, -11165, -9721, -8341, -7043, + -5842, -4747, -3768, -2909, -2171, -1553, -1049, -653, -353, -140}; +#else +#define LowDelayShapes_n960_N80_2_5ms NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N120_2_5ms[120] = { + 93, 196, 328, 491, 689, 924, 1199, 1514, 1873, 2274, 2720, 3209, 3742, 4318, + 4934, 5588, 6277, 7000, 7750, 8526, 9321, 10132, 10953, 11780, 12606, 13427, 14237, 15032, + 15807, 16557, 17278, 17967, 18620, 19234, 19809, 20341, 20830, 21276, 21680, 22040, 22360, 22641, + 22884, 23092, 23269, 23416, 23538, 23636, 23714, 23775, 23822, 23857, 23882, 23900, 23913, 23920, + 23925, 23928, 23930, 23930, -23930, -23930, -23928, -23925, -23920, -23913, -23900, -23882, -23857, -23822, + -23775, -23714, -23636, -23538, -23416, -23269, -23092, -22884, -22641, -22360, -22040, -21680, -21276, -20830, + -20341, -19809, -19234, -18620, -17967, -17278, -16557, -15807, -15032, -14237, -13427, -12606, -11780, -10953, + -10132, -9321, -8526, -7750, -7000, -6277, -5588, -4934, -4318, -3742, -3209, -2720, -2274, -1873, + -1514, -1199, -924, -689, -491, -328, -196, -93}; +#else +#define LowDelayShapes_n960_N120_2_5ms NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N160_2_5ms[160] = { + 70, 134, 210, 301, 407, 530, 671, 830, 1008, 1206, 1425, 1665, 1926, 2208, + 2512, 2837, 3183, 3550, 3937, 4343, 4768, 5211, 5670, 6143, 6631, 7131, 7642, 8161, + 8688, 9219, 9755, 10292, 10828, 11363, 11893, 12417, 12933, 13440, 13936, 14418, 14887, 15339, + 15775, 16193, 16593, 16972, 17332, 17670, 17988, 18285, 18561, 18816, 19050, 19264, 19459, 19635, + 19793, 19934, 20059, 20168, 20264, 20347, 20418, 20478, 20529, 20572, 20606, 20635, 20657, 20675, + 20689, 20700, 20708, 20713, 20718, 20720, 20722, 20723, 20724, 20724, -20724, -20724, -20723, -20722, + -20720, -20718, -20713, -20708, -20700, -20689, -20675, -20657, -20635, -20606, -20572, -20529, -20478, -20418, + -20347, -20264, -20168, -20059, -19934, -19793, -19635, -19459, -19264, -19050, -18816, -18561, -18285, -17988, + -17670, -17332, -16972, -16593, -16193, -15775, -15339, -14887, -14418, -13936, -13440, -12933, -12417, -11893, + -11363, -10828, -10292, -9755, -9219, -8688, -8161, -7642, -7131, -6631, -6143, -5670, -5211, -4768, + -4343, -3937, -3550, -3183, -2837, -2512, -2208, -1926, -1665, -1425, -1206, -1008, -830, -671, + -530, -407, -301, -210, -134, -70}; +#else +#define LowDelayShapes_n960_N160_2_5ms NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 LowDelayShapes_n960_N240_2_5ms[240] = { + 47, 81, 118, 160, 207, 259, 317, 381, 452, 528, 611, 701, 799, 903, + 1015, 1134, 1260, 1395, 1537, 1686, 1844, 2009, 2183, 2363, 2552, 2748, 2951, 3162, + 3380, 3604, 3836, 4073, 4317, 4567, 4822, 5083, 5348, 5618, 5892, 6170, 6451, 6735, + 7022, 7311, 7601, 7892, 8185, 8477, 8769, 9060, 9350, 9639, 9926, 10209, 10491, 10768, + 11042, 11312, 11577, 11837, 12092, 12341, 12585, 12822, 13053, 13277, 13494, 13705, 13908, 14103, + 14291, 14472, 14645, 14810, 14968, 15118, 15261, 15396, 15523, 15643, 15756, 15862, 15961, 16054, + 16140, 16220, 16293, 16361, 16424, 16481, 16533, 16580, 16623, 16662, 16697, 16728, 16755, 16780, + 16802, 16821, 16837, 16851, 16864, 16874, 16883, 16891, 16897, 16902, 16907, 16910, 16913, 16915, + 16917, 16918, 16919, 16920, 16921, 16921, 16921, 16921, -16921, -16921, -16921, -16921, -16920, -16919, + -16918, -16917, -16915, -16913, -16910, -16907, -16902, -16897, -16891, -16883, -16874, -16864, -16851, -16837, + -16821, -16802, -16780, -16755, -16728, -16697, -16662, -16623, -16580, -16533, -16481, -16424, -16361, -16293, + -16220, -16140, -16054, -15961, -15862, -15756, -15643, -15523, -15396, -15261, -15118, -14968, -14810, -14645, + -14472, -14291, -14103, -13908, -13705, -13494, -13277, -13053, -12822, -12585, -12341, -12092, -11837, -11577, + -11312, -11042, -10768, -10491, -10209, -9926, -9639, -9350, -9060, -8769, -8477, -8185, -7892, -7601, + -7311, -7022, -6735, -6451, -6170, -5892, -5618, -5348, -5083, -4822, -4567, -4317, -4073, -3836, + -3604, -3380, -3162, -2951, -2748, -2552, -2363, -2183, -2009, -1844, -1686, -1537, -1395, -1260, + -1134, -1015, -903, -799, -701, -611, -528, -452, -381, -317, -259, -207, -160, -118, + -81, -47}; +#else +#define LowDelayShapes_n960_N240_2_5ms NULL +#endif + + +#ifdef SUBSET_NB +RAM_ALIGN const Word32 lag_win_8k[16] = {0x7fdba30b, 0x7f6eca1a, 0x7eba2e4e, 0x7dbf01e8, 0x7c7eecec, 0x7afc0879, + 0x7938d8eb, 0x773846e0, 0x74fd973a, 0x728c623e, 0x6fe889ee, 0x6d162fc8, + 0x6a19aa0b, 0x66f778a7, 0x63b43a09, 0x60549fe1}; +#else +#define lag_win_8k NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word32 lag_win_16k[16] = {0x7ff6e7cb, 0x7fdba30b, 0x7fae3d5f, 0x7f6eca1a, 0x7f1d643a, 0x7eba2e4e, + 0x7e455264, 0x7dbf01e8, 0x7d277581, 0x7c7eecec, 0x7bc5aecb, 0x7afc0879, + 0x7a224dcf, 0x7938d8eb, 0x784009f7, 0x773846e0}; +#else +#define lag_win_16k NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word32 lag_win_24k[16] = {0x7ffbf529, 0x7fefd569, 0x7fdba30b, 0x7fbf61e2, 0x7f9b1748, 0x7f6eca1a, + 0x7f3a82b8, 0x7efe4b00, 0x7eba2e4e, 0x7e6e3976, 0x7e1a7ac1, 0x7dbf01e8, + 0x7d5be00f, 0x7cf127c2, 0x7c7eecec, 0x7c0544d0}; +#else +#define lag_win_24k NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word32 lag_win_32k[16] = {0x7ffdb9e3, 0x7ff6e7cb, 0x7feb8a70, 0x7fdba30b, 0x7fc7334b, 0x7fae3d5f, + 0x7f90c3ed, 0x7f6eca1a, 0x7f485382, 0x7f1d643a, 0x7eee00d1, 0x7eba2e4e, + 0x7e81f22e, 0x7e455264, 0x7e045558, 0x7dbf01e8}; +#else +#define lag_win_32k NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word32 lag_win_48k[16] = {0x7ffefd47, 0x7ffbf529, 0x7ff6e7cb, 0x7fefd569, 0x7fe6be59, 0x7fdba30b, + 0x7fce8403, 0x7fbf61e2, 0x7fae3d5f, 0x7f9b1748, 0x7f85f087, 0x7f6eca1a, + 0x7f55a51b, 0x7f3a82b8, 0x7f1d643a, 0x7efe4b00}; +#else +#define lag_win_48k NULL +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 lag_win_96k[16] = {0x7fffbf52, 0x7ffefd47, 0x7ffdb9e3, 0x7ffbf529, 0x7ff9af1f, 0x7ff6e7cb, + 0x7ff39f35, 0x7fefd569, 0x7feb8a70, 0x7fe6be59, 0x7fe17132, 0x7fdba30b, + 0x7fd553f5, 0x7fce8403, 0x7fc7334b, 0x7fbf61e2}; +# else +# define lag_win_96k NULL +# endif + +RAM_ALIGN const Word32 *const lag_win[NUM_SAMP_FREQ] = {lag_win_8k, lag_win_16k, lag_win_24k, lag_win_32k, lag_win_48k, lag_win_96k}; + +RAM_ALIGN const Word16 sqrt_table_phecu[49] = {/* used by Sqrt_l */ + 16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644, 20066, 20480, + 20886, 21283, 21674, 22058, 22435, 22806, 23170, 23530, 23884, 24232, + 24576, 24915, 25249, 25580, 25905, 26227, 26545, 26859, 27170, 27477, + 27780, 28081, 28378, 28672, 28963, 29251, 29537, 29819, 30099, 30377, + 30652, 30924, 31194, 31462, 31727, 31991, 32252, 32511, 32767}; + +/* First frequency bin in each subband now adjusted to include last bin * + * which was missed with the previous definition * + * 250 750 1250 2250 4250 8250 12250 16250 20250 ( 24250 ) * + * note that bins over 20000 are zeroed and not used */ +/* [- FB ----------------------------) (Currently limited to 20kHz) + * [- SWB -----------------------) + * [- sWB -------------------) + * [- WB ----------------) + * [- NB -----------) + */ + +RAM_ALIGN const Word16 gw_len_inv_shift_fx[MAX_LGW] = {/* Q0 */ + 1 - 1 /*/1/2*/, 1 - 1, 2 - 1 /*1/4*/, + 3 - 1 /*1/8*/, 4 - 1 /*1/16*/, 4 - 1, + 4 - 1, 4 - 1, 4 - 1}; +RAM_ALIGN const Word16 gwlpr_fx[MAX_LGW + 1] = { + 1, + 3 * QUOT_LPR_LTR, + 5 * QUOT_LPR_LTR, + 9 * QUOT_LPR_LTR, + 17 * QUOT_LPR_LTR, + 33 * QUOT_LPR_LTR, + 49 * QUOT_LPR_LTR, + 65 * QUOT_LPR_LTR, + 81 * QUOT_LPR_LTR, + 97 * QUOT_LPR_LTR}; /* frequency group start bins for transient analysis */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING + /* puretone_ana compressed ATH bandborder weights */ +RAM_ALIGN const Word16 scATHFx[MAX_LGW - 2] = { 14924 , 30499 , 31886 , 32767 , 29770 , 25417 , 16384 }; + /* 0.455444335937500 0.930755615234375 0.973083496093750 0.999969482421875 0.908508300781250 0.775665283203125 0.5*/ +#endif + +RAM_ALIGN const Word16 e_tot_headroom[5] = {3, 3, 4, 4, 4}; /* smallest head room to use for each fs */ + + + +RAM_ALIGN const Word16 xfp_wE_MDCT2FFTQ11[5] = {4077, 8283, 12489, 16698, + 25109}; /* Q11 Mantissa of scale to use for each fs */ + +RAM_ALIGN const Word16 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, 20675, 19745, 18856, 18007, 17197, 16423, + 8211, 4106, 2053, 1026, 513, 257, 128, 64, 32, 16, 8, 4, 2, 1, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE1[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, 23198, 22410, 21650, 20915, 20205, 19519, + 9759, 4880, 2440, 1220, 610, 305, 152, 76, 38, 19, 10, 5, 2, 1, 0}; + +#ifdef PLC2_FADEOUT_IN_MS +#if PLC2_FADEOUT_IN_MS == 0 +#ifndef CR8_A_PLC_FADEOUT_TUNING +/*/ default setting only requieres two tables */ +RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 2] = { + NULL, + POW_ATT_TABLE1 /*1 0.3dB steps */, + POW_ATT_TABLE0 /*2 0.4 dB steps*/, +}; +#endif + +#else /* PLC2_FADEOUT_IN_MS == 0 */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x9_14_7[OFF_FRAMES_LIMIT + 1] = { + 32767, + 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, /* 9 times .3dB steps , 14 6 dB steps, 7 muted steps */ + 12007, 6003, 3002, 1501, 750, 375, 188, 94, 47, 23, 12, 6, 3, 1, + 0, 0, 0, 0, 0, 0, 0 }; + +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x9_14_7[OFF_FRAMES_LIMIT + 1] = +{ 32767, + 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, /* 9 times .4dB steps , 14 6 dB steps, 7 muted steps */ + 10825, 5413, 2706, 1353, 677, 338, 169, 85, 42, 21, 11, 5, 3, 1, + 0, 0,0,0,0,0,0 }; +#endif + +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x8_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 12865, 6433, 3216, 1608, 804, 402, 201, 101, + 50, 25, 13, 6, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x8_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 11869, 5935, 2967, 1484, 742, 371, 185, 93, + 46, 23, 12, 6, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}; + +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x4_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 30581, 29543, 14772, 7386, 3693, 1847, 923, 462, 231, 115, 58, 29, 14, 7, + 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x4_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 29885, 28540, 14270, 7135, 3568, 1784, 892, 446, 223, 111, 56, 28, 14, 7, + 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x2_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 15828, 7914, 3957, 1979, 989, 495, 247, 124, 62, 31, 15, 8, 4, 2, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x2_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 15647, 7823, 3912, 1956, 978, 489, 244, 122, 61, 31, 15, 8, 4, 2, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x1_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +#ifdef CR8_A_PLC_FADEOUT_TUNING +/* POW_ATT_TABLES now ordered logically based on initial slow muting phase time */ +/* POW_ATT_TABLES[ind] is used after teh initial gain==1.0 no energy muting phase */ +RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 24 / 2] = +{ NULL, +/*0.3dB col , 0.4dB col */ +/* 1*/POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6, /* 0 0.3dB, 16 6dB, 14mute */ /* 0.4dB version */ /* old short mute tabs */ +/* 3*/POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6, /* 1 0.3dB, 15 6dB ,14mute */ /* 0.4dB version */ +/* 5*/POW_ATT_TABLE_p3x4_6, POW_ATT_TABLE_p4x4_6, /* 3 0.3dB, 15 6dB , 12 mute */ /* 0.4dB version */ +/* 7*/POW_ATT_TABLE_p3x8_6, POW_ATT_TABLE_p4x8_6, /* 7 0.3dB, 15 6dB , 8 mute */ /* 0.4dB version */ +/* 9*/POW_ATT_TABLE_p3x9_14_7, POW_ATT_TABLE_p4x9_14_7, /* 9 0.3dB, 14 6dB , 7 mute */ /* 0.4dB version */ /* opt 120 ms */ +/*11*/POW_ATT_TABLE1, POW_ATT_TABLE0, /* 15 0.3dB, 14 6dB , 1 mute */ /* 0.4dB version */ /* 3GPP original/default curves */ +}; + +/* PLC_FADEOUT_TUNING, extended table nominal muting phases from 30 ms to 140 ms */ +RAM_ALIGN const Word16 fade_scheme_tab_fx[24 / 2][3] = { +/* burst_att_thresh indicates when muting POW_ATT_TABLE[att_per_frame_idx] should be used first time it is 1.0 though */ +/* burst_att_thresh ==2 --> gains [ 1.0, 32767/32768.0(first table value used) , first muted, .... ]*/ +/* burst_att_thresh ==5 --> gains [ 1.0, 1.0, 1,0 1,0, 32767/32768.0(first table value used) , first muted,... ]*/ +/* beta_mute_thr ==4 --> start of final attenuation attenuate AvgMix */ + +/* tabled {att_per_frame_idx_p3dB , burst_att_thresh, beta_mute_thr } */ +{ 1, 2, 0 + 2 + 2 }, /* 30 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=0 */ +{ 1, 3, 0 + 3 + 2 }, /* 40 ms, 0.3 dB delta att in slow mutephase */ +{ 3, 3, 1 + 3 + 1 }, /* 50 ms, 0.3 dB delta att in slow mutephase */ +{ 3, 4, 1 + 4 + 1}, /* 60 ms, 0.3 dB delta att in slow mutephase */ +{ 5, 4, 3 + 4 + 1 }, /* 70 ms, 0.3 dB delta att in slow mutephase */ +{ 5, 5, 3 + 5 + 1 }, /* 80 ms, 0.3 dB delta att in slow mutephase */ +{ 7, 5, 7 + 5 }, /* 90 ms, 0.3 dB delta att in slow mutephase */ +{ 7, 5, 7 + 5 + 1}, /* 100 ms, 0.3 dB delta att in slow mutephase */ +{ 9, 5, 9 + 5 }, /* 110 ms, 0.3 dB delta att in slow mutephase */ +{ 9, 5, 9 + 5 + 1}, /* 120 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=1 */ +{ 11, 5, 15 + 5 },/* 130 ms, 0.3 dB delta att in slow mutephase */ +{ 11, 6, 15 + 6 },/* 140 ms, 0.3 dB delta att in slow mutephase nominal 3GPP */ +}; +/*fade_scheme_tab_fx[ind][0] att_per _fram_index , "points" to first column in POW_ATT TABLES */ +/*fade_scheme_tab_fx[ind][1] is burst_att_thresh, the number of non_muted 1.0 gain frames */ +/*fade_scheme_tab_fx[ind][2] is beta_mute_thr, the location of the start of final attenuation */ + +#else +RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 10] = { + NULL, + POW_ATT_TABLE1, + POW_ATT_TABLE0, + /* .3dB x16,16 6dB steps */ /* .4dB x16, 16 6dB steps */ /*original/default */ + POW_ATT_TABLE_p3x8_6, + POW_ATT_TABLE_p4x8_6, + /* .3dB x8, 24 6dB steps */ /* .4dB x8, 24 6dB steps */ + POW_ATT_TABLE_p3x4_6, + POW_ATT_TABLE_p4x4_6, + /* .3dB x4, 28 6dB steps */ /* .4dB x4, 28 6dB steps */ + POW_ATT_TABLE_p3x2_6, + POW_ATT_TABLE_p4x2_6, + /* .3dB x2, 30 6dB steps */ /* .4dB x2, 30 6dB steps */ + POW_ATT_TABLE_p3x1_6, + POW_ATT_TABLE_p4x1_6 /* .3dB x1, 30 6dB steps */ /* .4dB x1, 30 6dB steps */ +}; +#endif + +#endif /* PLC2_FADEOUT_IN_MS == 0 */ + +#else /* PLC2_FADEOUT_IN_MS */ +RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 2] = { + NULL, + POW_ATT_TABLE1 /*1 .3dB steps */, + POW_ATT_TABLE0 /*2 .4 dB steps*/, +}; +#endif /* PLC2_FADEOUT_IN_MS */ + +RAM_ALIGN const Word16 sin_quarterQ15_fx[256 + 1] = { + 0, 201, 402, 603, 804, 1005, 1206, 1407, 1608, 1809, 2009, 2210, 2411, 2611, 2811, 3012, + 3212, 3412, 3612, 3812, 4011, 4211, 4410, 4609, 4808, 5007, 5205, 5404, 5602, 5800, 5998, 6195, + 6393, 6590, 6787, 6983, 7180, 7376, 7571, 7767, 7962, 8157, 8351, 8546, 8740, 8933, 9127, 9319, + 9512, 9704, 9896, 10088, 10279, 10469, 10660, 10850, 11039, 11228, 11417, 11605, 11793, 11980, 12167, 12354, + 12540, 12725, 12910, 13095, 13279, 13463, 13646, 13828, 14010, 14192, 14373, 14553, 14733, 14912, 15091, 15269, + 15447, 15624, 15800, 15976, 16151, 16326, 16500, 16673, 16846, 17018, 17190, 17361, 17531, 17700, 17869, 18037, + 18205, 18372, 18538, 18703, 18868, 19032, 19195, 19358, 19520, 19681, 19841, 20001, 20160, 20318, 20475, 20632, + 20788, 20943, 21097, 21251, 21403, 21555, 21706, 21856, 22006, 22154, 22302, 22449, 22595, 22740, 22884, 23028, + 23170, 23312, 23453, 23593, 23732, 23870, 24008, 24144, 24279, 24414, 24548, 24680, 24812, 24943, 25073, 25202, + 25330, 25457, 25583, 25708, 25833, 25956, 26078, 26199, 26320, 26439, 26557, 26674, 26791, 26906, 27020, 27133, + 27246, 27357, 27467, 27576, 27684, 27791, 27897, 28002, 28106, 28209, 28311, 28411, 28511, 28610, 28707, 28803, + 28899, 28993, 29086, 29178, 29269, 29359, 29448, 29535, 29622, 29707, 29792, 29875, 29957, 30038, 30118, 30196, + 30274, 30350, 30425, 30499, 30572, 30644, 30715, 30784, 30853, 30920, 30986, 31050, 31114, 31177, 31238, 31298, + 31357, 31415, 31471, 31527, 31581, 31634, 31686, 31737, 31786, 31834, 31881, 31927, 31972, 32015, 32058, 32099, + 32138, 32177, 32214, 32251, 32286, 32319, 32352, 32383, 32413, 32442, 32470, 32496, 32522, 32546, 32568, 32590, + 32610, 32629, 32647, 32664, 32679, 32693, 32706, 32718, 32729, 32738, 32746, 32753, 32758, 32762, 32766, 32767, + 32767}; + +/* 16 ms tables for PHECU fft windowing and post ifft preTda MDCT windowing (window 11) */ +/* 3+3ms tapering for the hamming parts */ +/* temporary ROM solution */ +/* alternatively use values from a single 48 kHz table */ + +/* 3ms rising tapering part @48 kHZ */ +/* only quarter sine hamming part is actually used by the C-function windowing_fx */ +/* OPT: store only one table at 48 or 96 kHz */ +/* OPT2: for this to work one must switch to 'periodic' instead of used 'symetric' windows, * + * the different windows are just sub-sampled windows of a 96kHz window */ + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 PhECU_whr16ms_NB_Q15[Lprot_hamm_len2_8k] = {/* From matlab */ + 2621, 2750, 3135, 3769, 4641, 5736, + 7036, 8519, 10158, 11926, 13793, 15727, + 17695, 19662, 21596, 23463, 25231, 26871, + 28353, 29653, 30749, 31621, 32254, 32639}; +#else +#define PhECU_whr16ms_NB_Q15 NULL +#endif +#ifdef SUBSET_WB +RAM_ALIGN const Word16 PhECU_whr16ms_WB_Q15[Lprot_hamm_len2_16k] = {/* From matlab */ + 2621, 2654, 2750, 2911, 3135, 3421, 3769, + 4176, 4641, 5162, 5736, 6362, 7036, 7756, + 8519, 9320, 10158, 11028, 11926, 12850, 13793, + 14754, 15727, 16709, 17695, 18681, 19662, 20635, + 21596, 22540, 23463, 24361, 25231, 26069, 26871, + 27633, 28353, 29027, 29653, 30228, 30749, 31214, + 31621, 31968, 32254, 32478, 32639, 32736}; +#else +#define PhECU_whr16ms_WB_Q15 NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 PhECU_whr16ms_sWB_Q15[Lprot_hamm_len2_24k] = + {/* From matlab */ + 2621, 2636, 2679, 2750, 2850, 2979, 3135, 3319, 3530, 3769, 4034, 4325, 4641, 4982, 5347, + 5736, 6148, 6582, 7036, 7511, 8006, 8519, 9049, 9596, 10158, 10735, 11324, 11926, 12539, 13162, + 13793, 14432, 15077, 15727, 16381, 17037, 17695, 18352, 19008, 19662, 20312, 20957, 21596, 22227, 22850, + 23463, 24065, 24655, 25231, 25794, 26340, 26871, 27384, 27878, 28353, 28808, 29242, 29653, 30042, 30407, + 30749, 31065, 31356, 31621, 31859, 32070, 32254, 32411, 32539, 32639, 32711, 32754}; +#else +#define PhECU_whr16ms_sWB_Q15 NULL +#endif +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 PhECU_whr16ms_SWB_Q15[Lprot_hamm_len2_32k] = + {/* From matlab */ + 2621, 2630, 2654, 2694, 2750, 2823, 2911, 3015, 3135, 3270, 3421, 3588, 3769, 3965, 4176, 4401, + 4641, 4894, 5162, 5442, 5736, 6043, 6362, 6693, 7036, 7391, 7756, 8132, 8519, 8915, 9320, 9735, + 10158, 10589, 11028, 11474, 11926, 12385, 12850, 13319, 13793, 14272, 14754, 15239, 15727, 16217, 16709, 17202, + 17695, 18188, 18681, 19172, 19662, 20150, 20635, 21118, 21596, 22070, 22540, 23004, 23463, 23916, 24361, 24800, + 25231, 25654, 26069, 26475, 26871, 27257, 27633, 27999, 28353, 28696, 29027, 29347, 29653, 29947, 30228, 30495, + 30749, 30988, 31214, 31424, 31621, 31802, 31968, 32119, 32254, 32374, 32478, 32567, 32639, 32695, 32736, 32760}; +#else +#define PhECU_whr16ms_SWB_Q15 NULL +#endif +#ifdef SUBSET_FB +RAM_ALIGN const Word16 PhECU_whr16ms_FB_Q15[Lprot_hamm_len2_48k] = + {/* From matlab */ + 2621, 2625, 2636, 2654, 2679, 2711, 2750, 2797, 2850, 2911, 2979, 3053, 3135, 3224, 3319, 3421, + 3530, 3646, 3769, 3898, 4034, 4176, 4325, 4480, 4641, 4808, 4982, 5162, 5347, 5539, 5736, 5939, + 6148, 6362, 6582, 6806, 7036, 7271, 7511, 7756, 8006, 8260, 8519, 8782, 9049, 9320, 9596, 9875, + 10158, 10445, 10735, 11028, 11324, 11624, 11926, 12232, 12539, 12850, 13162, 13477, 13793, 14112, 14432, 14754, + 15077, 15402, 15727, 16054, 16381, 16709, 17037, 17366, 17695, 18024, 18352, 18681, 19008, 19336, 19662, 19988, + 20312, 20635, 20957, 21277, 21596, 21913, 22227, 22540, 22850, 23158, 23463, 23765, 24065, 24361, 24655, 24945, + 25231, 25514, 25794, 26069, 26340, 26608, 26871, 27129, 27384, 27633, 27878, 28118, 28353, 28583, 28808, 29027, + 29242, 29450, 29653, 29850, 30042, 30228, 30407, 30581, 30749, 30910, 31065, 31214, 31356, 31491, 31621, 31743, + 31859, 31968, 32070, 32166, 32254, 32336, 32411, 32478, 32539, 32593, 32639, 32678, 32711, 32736, 32754, 32764}; +#else +#define PhECU_whr16ms_FB_Q15 NULL +#endif + +/* initial 2ms for preTda is the LD-MDCT analysis window times the centered inverse whr window */ +#ifdef SUBSET_NB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_128_pre_Q14[16] = {-12, -34, -74, -135, -219, -327, -459, -610, + -776, -949, -1125, -1295, -1451, -1587, -1696, -1771}; +#else +#define PhECU_preTdaFx16ms_128_pre_Q14 NULL +#endif +#ifdef SUBSET_WB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_256_pre_Q14[32] = { + -8, -16, -27, -42, -63, -87, -117, -154, -196, -244, -299, -358, -424, -495, -570, -650, + -733, -818, -906, -993, -1082, -1168, -1253, -1336, -1414, -1488, -1556, -1617, -1671, -1718, -1755, -1784}; +#else +#define PhECU_preTdaFx16ms_256_pre_Q14 NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_384_pre_Q14[48] = { + -6, -12, -18, -25, -34, -45, -59, -74, -92, -112, -135, -160, -188, -219, -253, -289, + -328, -369, -413, -459, -507, -557, -610, -663, -719, -775, -833, -891, -950, -1008, -1067, -1125, + -1183, -1239, -1295, -1349, -1401, -1451, -1499, -1545, -1587, -1627, -1663, -1696, -1725, -1750, -1771, -1788}; +#else +#define PhECU_preTdaFx16ms_384_pre_Q14 NULL +#endif +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_512_pre_Q14[64] = { + -5, -9, -13, -18, -24, -31, -38, -47, -57, -68, -81, -94, -109, -126, -144, -164, + -185, -207, -232, -257, -284, -313, -343, -374, -407, -441, -477, -513, -551, -590, -630, -670, + -712, -754, -797, -840, -884, -927, -972, -1016, -1059, -1104, -1147, -1190, -1232, -1274, -1316, -1356, + -1395, -1433, -1470, -1505, -1539, -1572, -1602, -1632, -1659, -1684, -1707, -1728, -1747, -1763, -1777, -1789}; +#else +#define PhECU_preTdaFx16ms_512_pre_Q14 NULL +#endif +#ifdef SUBSET_FB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_768_pre_Q14[96] = { + -4, -8, -11, -13, -15, -19, -23, -27, -32, -37, -43, -48, -55, -62, -70, -78, + -87, -97, -107, -117, -129, -141, -154, -168, -181, -196, -211, -228, -244, -261, -280, -298, + -318, -338, -358, -380, -402, -424, -447, -471, -495, -520, -545, -570, -596, -623, -650, -677, + -705, -733, -761, -789, -818, -847, -876, -905, -934, -964, -993, -1022, -1052, -1082, -1111, -1140, + -1169, -1197, -1226, -1254, -1281, -1309, -1336, -1362, -1388, -1415, -1439, -1464, -1488, -1511, -1534, -1556, + -1577, -1598, -1617, -1636, -1655, -1671, -1688, -1703, -1718, -1731, -1744, -1755, -1766, -1776, -1784, -1791}; +#else +#define PhECU_preTdaFx16ms_768_pre_Q14 NULL +#endif + +/* ROM OPT compute it runtime based on MDCT win and tabled inverse hamming sections */ +/* 16 ms tables for PHECU fft windowing and post ifft preTda MDCT windowing */ +/* OPT2 can be reduced to 14.25 ms, due to 1.75 ms trailing zeroes */ +#ifdef SUBSET_NB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_NB_Q14[128] = { + -22591, -21465, -18295, -14331, -10544, -7321, -4690, -2561, -811, 662, 1942, 3090, 4148, 5146, 6107, 7043, + 7961, 8868, 9761, 10640, 11502, 12345, 13164, 13959, 14731, 15423, 15970, 16374, 16642, 16789, 16837, 16810, + 16735, 16637, 16537, 16441, 16366, 16307, 16263, 16230, 16206, 16190, 16181, 16177, 16178, 16182, 16188, 16196, + 16203, 16209, 16214, 16218, 16219, 16221, 16222, 16226, 16230, 16238, 16251, 16267, 16287, 16312, 16339, 16369, + 16399, 16429, 16456, 16481, 16502, 16518, 16531, 16539, 16544, 16547, 16548, 16550, 16552, 16556, 16561, 16567, + 16575, 16582, 16588, 16592, 16593, 16589, 16580, 16564, 16540, 16506, 16461, 16402, 16327, 16232, 16095, 15907, + 15641, 15272, 14775, 14130, 13325, 12361, 11251, 10017, 8694, 7354, 6057, 4825, 3684, 2665, 1795, 1095, + 575, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#else +#define PhECU_preTdaFx16ms_NB_Q14 NULL +#endif +#ifdef SUBSET_WB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_WB_Q14[256] = { + -22528, -22351, -21532, -20186, -18475, -16565, -14596, -12673, -10858, -9181, -7654, -6277, -5037, -3923, -2914, + -2001, -1169, -405, 303, 961, 1580, 2166, 2725, 3263, 3781, 4285, 4778, 5262, 5739, 6211, + 6677, 7140, 7601, 8059, 8514, 8968, 9419, 9868, 10314, 10756, 11195, 11630, 12060, 12486, 12907, + 13322, 13733, 14137, 14537, 14917, 15263, 15573, 15847, 16085, 16286, 16454, 16587, 16689, 16763, 16810, + 16833, 16836, 16822, 16795, 16757, 16712, 16663, 16612, 16565, 16511, 16464, 16421, 16383, 16350, 16321, + 16295, 16272, 16253, 16237, 16223, 16211, 16201, 16194, 16187, 16183, 16180, 16178, 16177, 16178, 16179, + 16181, 16184, 16187, 16190, 16194, 16198, 16201, 16204, 16208, 16210, 16213, 16215, 16217, 16218, 16219, + 16220, 16221, 16222, 16222, 16223, 16225, 16227, 16229, 16232, 16236, 16241, 16247, 16255, 16262, 16272, + 16282, 16293, 16305, 16319, 16332, 16347, 16361, 16376, 16391, 16407, 16422, 16436, 16450, 16463, 16475, + 16487, 16497, 16506, 16514, 16522, 16528, 16533, 16537, 16541, 16543, 16545, 16546, 16547, 16548, 16549, + 16550, 16550, 16551, 16553, 16555, 16557, 16560, 16563, 16566, 16569, 16573, 16577, 16580, 16584, 16587, + 16589, 16592, 16593, 16593, 16593, 16591, 16588, 16583, 16577, 16569, 16559, 16547, 16532, 16516, 16496, + 16474, 16448, 16418, 16385, 16347, 16305, 16258, 16205, 16134, 16054, 15960, 15849, 15716, 15560, 15376, + 15161, 14913, 14628, 14306, 13944, 13541, 13098, 12616, 12097, 11540, 10952, 10335, 9692, 9030, 8362, + 7699, 7045, 6400, 5769, 5155, 4560, 3990, 3448, 2936, 2460, 2022, 1625, 1272, 963, 700, + 481, 306, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0}; +#else +#define PhECU_preTdaFx16ms_WB_Q14 NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_sWB_Q14[384] = { + -22499, -22471, -22152, -21551, -20715, -19688, -18527, -17277, -15982, -14679, -13393, -12145, -10954, -9826, + -8760, -7763, -6831, -5958, -5149, -4394, -3688, -3029, -2410, -1831, -1285, -769, -279, 186, + 630, 1055, 1462, 1856, 2236, 2606, 2966, 3317, 3662, 3999, 4330, 4658, 4981, 5301, + 5618, 5933, 6246, 6556, 6866, 7175, 7481, 7788, 8093, 8398, 8702, 9004, 9306, 9606, + 9906, 10205, 10502, 10798, 11092, 11385, 11676, 11965, 12252, 12537, 12820, 13101, 13379, 13655, + 13929, 14200, 14470, 14732, 14977, 15208, 15422, 15622, 15804, 15970, 16121, 16256, 16374, 16478, + 16567, 16643, 16703, 16753, 16789, 16815, 16830, 16837, 16835, 16825, 16810, 16789, 16764, 16735, + 16704, 16671, 16637, 16604, 16575, 16538, 16503, 16471, 16441, 16414, 16389, 16366, 16345, 16325, + 16307, 16291, 16276, 16263, 16250, 16239, 16230, 16221, 16213, 16206, 16200, 16195, 16190, 16187, + 16184, 16181, 16180, 16178, 16178, 16178, 16178, 16178, 16180, 16181, 16182, 16185, 16187, 16189, + 16191, 16193, 16195, 16198, 16200, 16202, 16205, 16207, 16208, 16211, 16213, 16214, 16215, 16217, + 16217, 16218, 16219, 16219, 16220, 16221, 16221, 16221, 16222, 16223, 16224, 16224, 16226, 16227, + 16228, 16230, 16233, 16236, 16239, 16242, 16246, 16251, 16256, 16261, 16267, 16274, 16280, 16288, + 16295, 16304, 16312, 16321, 16330, 16339, 16349, 16359, 16369, 16379, 16389, 16399, 16409, 16419, + 16429, 16439, 16447, 16456, 16465, 16473, 16481, 16489, 16495, 16502, 16508, 16513, 16519, 16523, + 16527, 16531, 16534, 16536, 16539, 16541, 16543, 16544, 16545, 16546, 16547, 16547, 16548, 16549, + 16549, 16549, 16550, 16551, 16551, 16552, 16554, 16554, 16556, 16558, 16559, 16561, 16563, 16565, + 16567, 16570, 16572, 16575, 16578, 16580, 16582, 16584, 16586, 16588, 16590, 16591, 16592, 16593, + 16593, 16593, 16593, 16591, 16589, 16587, 16584, 16580, 16575, 16570, 16564, 16557, 16549, 16540, + 16530, 16519, 16506, 16493, 16478, 16461, 16443, 16423, 16402, 16379, 16354, 16327, 16297, 16266, + 16232, 16195, 16147, 16096, 16039, 15977, 15907, 15828, 15740, 15642, 15531, 15409, 15273, 15122, + 14956, 14775, 14577, 14362, 14130, 13879, 13611, 13325, 13021, 12700, 12361, 12006, 11636, 11250, + 10851, 10440, 10016, 9583, 9142, 8698, 8255, 7815, 7377, 6944, 6515, 6092, 5675, 5266, + 4865, 4475, 4094, 3726, 3370, 3029, 2703, 2393, 2101, 1826, 1571, 1334, 1117, 921, + 744, 588, 451, 335, 235, 128, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0}; +#else +#define PhECU_preTdaFx16ms_sWB_Q14 NULL +#endif +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_SWB_Q14[512] = { + -22482, -22492, -22345, -22020, -21560, -20952, -20236, -19434, -18551, -17624, -16665, -15691, -14716, -13753, + -12810, -11889, -11002, -10152, -9335, -8553, -7813, -7108, -6442, -5806, -5206, -4634, -4091, -3574, + -3084, -2618, -2173, -1748, -1341, -952, -578, -219, 128, 462, 786, 1099, 1405, 1701, + 1989, 2271, 2548, 2818, 3084, 3345, 3601, 3856, 4106, 4354, 4598, 4840, 5082, 5322, + 5559, 5795, 6029, 6263, 6496, 6729, 6961, 7192, 7422, 7652, 7882, 8111, 8339, 8567, + 8795, 9022, 9249, 9475, 9701, 9926, 10151, 10374, 10597, 10819, 11041, 11261, 11481, 11699, + 11917, 12133, 12349, 12563, 12776, 12988, 13198, 13408, 13616, 13823, 14028, 14233, 14437, 14635, + 14826, 15007, 15181, 15344, 15499, 15645, 15782, 15910, 16029, 16139, 16239, 16332, 16415, 16490, + 16557, 16615, 16667, 16710, 16747, 16777, 16800, 16818, 16829, 16835, 16837, 16834, 16827, 16816, + 16803, 16786, 16767, 16746, 16724, 16700, 16675, 16649, 16624, 16601, 16580, 16551, 16524, 16499, + 16475, 16453, 16431, 16411, 16392, 16374, 16358, 16342, 16328, 16313, 16301, 16289, 16278, 16268, + 16258, 16249, 16241, 16234, 16226, 16220, 16214, 16208, 16204, 16200, 16196, 16192, 16188, 16186, + 16184, 16182, 16181, 16179, 16178, 16178, 16177, 16177, 16177, 16178, 16179, 16180, 16181, 16181, + 16183, 16185, 16186, 16188, 16189, 16191, 16192, 16195, 16196, 16198, 16200, 16202, 16204, 16205, + 16207, 16208, 16210, 16211, 16212, 16213, 16215, 16215, 16216, 16217, 16218, 16219, 16219, 16219, + 16220, 16220, 16221, 16221, 16222, 16222, 16222, 16222, 16223, 16223, 16224, 16225, 16226, 16227, + 16228, 16230, 16231, 16233, 16235, 16238, 16240, 16243, 16245, 16249, 16253, 16256, 16260, 16264, + 16269, 16275, 16279, 16285, 16290, 16296, 16302, 16309, 16315, 16322, 16329, 16336, 16343, 16351, + 16358, 16365, 16373, 16381, 16388, 16396, 16403, 16411, 16418, 16425, 16432, 16439, 16446, 16453, + 16460, 16466, 16472, 16478, 16484, 16489, 16494, 16499, 16504, 16509, 16513, 16517, 16520, 16524, + 16527, 16529, 16532, 16534, 16536, 16538, 16540, 16541, 16543, 16543, 16544, 16545, 16546, 16547, + 16547, 16547, 16548, 16548, 16549, 16549, 16550, 16550, 16551, 16551, 16551, 16552, 16553, 16554, + 16555, 16555, 16557, 16558, 16559, 16560, 16562, 16563, 16565, 16566, 16569, 16570, 16572, 16573, + 16576, 16577, 16579, 16581, 16583, 16585, 16586, 16588, 16589, 16590, 16591, 16592, 16592, 16593, + 16593, 16593, 16592, 16592, 16591, 16590, 16589, 16586, 16585, 16581, 16578, 16575, 16571, 16566, + 16562, 16556, 16550, 16543, 16536, 16528, 16520, 16511, 16502, 16490, 16479, 16468, 16455, 16441, + 16426, 16411, 16394, 16376, 16357, 16337, 16316, 16294, 16270, 16245, 16219, 16191, 16154, 16115, + 16075, 16032, 15985, 15934, 15879, 15818, 15751, 15679, 15601, 15517, 15425, 15325, 15218, 15102, + 14978, 14845, 14703, 14551, 14390, 14219, 14038, 13847, 13645, 13434, 13213, 12982, 12741, 12490, + 12230, 11961, 11683, 11396, 11102, 10800, 10492, 10176, 9855, 9529, 9197, 8864, 8532, 8201, + 7872, 7544, 7218, 6894, 6573, 6255, 5940, 5629, 5322, 5020, 4723, 4432, 4147, 3868, + 3596, 3332, 3076, 2828, 2590, 2361, 2141, 1931, 1732, 1543, 1366, 1200, 1044, 901, + 768, 647, 536, 438, 349, 271, 201, 108, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; +#else +#define PhECU_preTdaFx16ms_SWB_Q14 NULL +#endif +#ifdef SUBSET_FB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_FB_Q14[768] = { + -22463, -22493, -22449, -22334, -22148, -21885, -21560, -21179, -20737, -20250, -19726, -19171, -18581, -17972, + -17340, -16701, -16050, -15401, -14757, -14114, -13474, -12848, -12237, -11637, -11048, -10478, -9922, -9386, + -8864, -8357, -7865, -7393, -6936, -6493, -6069, -5654, -5258, -4874, -4503, -4144, -3801, -3465, + -3140, -2829, -2524, -2230, -1944, -1667, -1399, -1136, -884, -636, -395, -158, 72, 296, + 514, 728, 938, 1144, 1346, 1545, 1739, 1931, 2119, 2305, 2489, 2670, 2849, 3025, + 3199, 3373, 3543, 3713, 3879, 4046, 4211, 4376, 4539, 4700, 4862, 5022, 5182, 5341, + 5499, 5657, 5814, 5970, 6126, 6282, 6437, 6592, 6746, 6901, 7056, 7209, 7362, 7517, + 7669, 7823, 7976, 8129, 8281, 8433, 8585, 8738, 8890, 9040, 9193, 9343, 9495, 9645, + 9796, 9946, 10096, 10245, 10395, 10543, 10693, 10841, 10989, 11137, 11284, 11431, 11578, 11723, + 11869, 12014, 12159, 12303, 12446, 12589, 12733, 12874, 13016, 13157, 13298, 13438, 13577, 13716, + 13855, 13992, 14129, 14266, 14403, 14537, 14667, 14795, 14918, 15037, 15152, 15263, 15371, 15474, + 15573, 15669, 15760, 15847, 15931, 16010, 16084, 16156, 16223, 16287, 16346, 16402, 16453, 16502, + 16546, 16587, 16625, 16659, 16690, 16717, 16742, 16763, 16781, 16797, 16810, 16819, 16827, 16833, + 16836, 16837, 16836, 16833, 16828, 16822, 16815, 16805, 16794, 16783, 16770, 16756, 16743, 16727, + 16712, 16695, 16679, 16663, 16645, 16629, 16612, 16598, 16584, 16565, 16546, 16529, 16511, 16495, + 16479, 16463, 16449, 16434, 16420, 16408, 16395, 16383, 16371, 16360, 16350, 16339, 16329, 16321, + 16311, 16303, 16295, 16287, 16280, 16272, 16266, 16260, 16253, 16247, 16242, 16237, 16232, 16227, + 16223, 16219, 16215, 16211, 16207, 16205, 16202, 16199, 16196, 16194, 16191, 16189, 16187, 16186, + 16184, 16183, 16181, 16180, 16180, 16179, 16178, 16178, 16177, 16177, 16177, 16177, 16177, 16177, + 16178, 16178, 16179, 16179, 16180, 16181, 16182, 16183, 16184, 16185, 16186, 16187, 16188, 16189, + 16190, 16191, 16193, 16194, 16195, 16196, 16197, 16199, 16200, 16201, 16202, 16203, 16205, 16206, + 16206, 16207, 16208, 16209, 16210, 16211, 16212, 16212, 16213, 16214, 16215, 16215, 16216, 16216, + 16217, 16218, 16218, 16218, 16219, 16219, 16219, 16220, 16220, 16220, 16221, 16221, 16221, 16221, + 16221, 16222, 16222, 16222, 16223, 16223, 16223, 16224, 16224, 16225, 16225, 16226, 16227, 16227, + 16228, 16229, 16230, 16231, 16233, 16234, 16235, 16237, 16237, 16239, 16241, 16243, 16245, 16247, + 16249, 16252, 16254, 16257, 16260, 16263, 16266, 16268, 16271, 16275, 16278, 16282, 16286, 16290, + 16294, 16298, 16301, 16305, 16310, 16314, 16319, 16323, 16328, 16332, 16337, 16342, 16347, 16352, + 16357, 16361, 16366, 16371, 16377, 16382, 16387, 16391, 16396, 16402, 16407, 16412, 16417, 16421, + 16426, 16431, 16436, 16441, 16445, 16450, 16454, 16458, 16463, 16467, 16471, 16475, 16480, 16482, + 16486, 16490, 16494, 16497, 16500, 16504, 16507, 16510, 16511, 16514, 16517, 16519, 16522, 16524, + 16526, 16528, 16530, 16532, 16533, 16535, 16536, 16538, 16539, 16540, 16541, 16542, 16542, 16543, + 16543, 16544, 16545, 16545, 16546, 16546, 16546, 16547, 16547, 16547, 16548, 16548, 16548, 16548, + 16549, 16549, 16549, 16549, 16550, 16550, 16550, 16551, 16551, 16551, 16552, 16552, 16553, 16554, + 16554, 16555, 16556, 16556, 16557, 16558, 16559, 16560, 16561, 16562, 16563, 16564, 16565, 16566, + 16567, 16568, 16570, 16571, 16572, 16572, 16574, 16575, 16576, 16577, 16579, 16580, 16581, 16582, + 16583, 16585, 16586, 16587, 16588, 16589, 16589, 16590, 16591, 16592, 16592, 16593, 16593, 16593, + 16593, 16593, 16593, 16593, 16593, 16592, 16592, 16591, 16590, 16589, 16588, 16586, 16585, 16583, + 16581, 16579, 16576, 16574, 16572, 16569, 16566, 16562, 16559, 16555, 16551, 16546, 16542, 16538, + 16533, 16527, 16521, 16515, 16510, 16503, 16496, 16489, 16481, 16474, 16465, 16457, 16448, 16439, + 16428, 16419, 16408, 16396, 16385, 16373, 16360, 16347, 16333, 16320, 16305, 16290, 16274, 16258, + 16240, 16223, 16205, 16186, 16160, 16134, 16109, 16082, 16054, 16024, 15993, 15961, 15926, 15888, + 15849, 15808, 15763, 15717, 15667, 15615, 15560, 15502, 15441, 15376, 15308, 15236, 15161, 15082, + 14999, 14913, 14822, 14727, 14628, 14525, 14417, 14306, 14190, 14069, 13944, 13814, 13679, 13541, + 13398, 13250, 13098, 12943, 12782, 12616, 12447, 12273, 12096, 11915, 11729, 11541, 11348, 11151, + 10952, 10749, 10543, 10335, 10123, 9909, 9692, 9473, 9253, 9032, 8810, 8589, 8369, 8149, + 7929, 7711, 7492, 7276, 7059, 6845, 6631, 6418, 6207, 5997, 5789, 5582, 5378, 5175, + 4975, 4777, 4583, 4389, 4200, 4012, 3827, 3646, 3468, 3294, 3123, 2956, 2793, 2634, + 2479, 2328, 2181, 2039, 1902, 1768, 1639, 1517, 1398, 1284, 1176, 1072, 973, 879, + 791, 707, 629, 556, 486, 423, 364, 310, 261, 213, 163, 85, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#else +#define PhECU_preTdaFx16ms_FB_Q14 NULL +#endif + +RAM_ALIGN const Word16 *const PhECU_wins[5][3] = { + /* 3ms hamm(left part) , 16ms(center IWHR(periodic)*MDCT-anaQ14) , 2ms(initial MDCT-ana in Q14) */ + /*8 kHz*/ {PhECU_whr16ms_NB_Q15, PhECU_preTdaFx16ms_NB_Q14, PhECU_preTdaFx16ms_128_pre_Q14}, + /*16 kHz*/ {PhECU_whr16ms_WB_Q15, PhECU_preTdaFx16ms_WB_Q14, PhECU_preTdaFx16ms_256_pre_Q14}, + /*24 kHz*/ {PhECU_whr16ms_sWB_Q15, PhECU_preTdaFx16ms_sWB_Q14, PhECU_preTdaFx16ms_384_pre_Q14}, + /*32 kHz*/ {PhECU_whr16ms_SWB_Q15, PhECU_preTdaFx16ms_SWB_Q14, PhECU_preTdaFx16ms_512_pre_Q14}, + /*48 kHz*/ {PhECU_whr16ms_FB_Q15, PhECU_preTdaFx16ms_FB_Q14, PhECU_preTdaFx16ms_768_pre_Q14}}; + +/* x=(0:(5*8-1))*(2*pi)/32; y=sin(x);y_int=max(-32768,min(32767,round(y*32768))), y_int/32768 */ +/* 1.25 *2*pi table for low complex and low angle resolution rand_phase_fx */ +RAM_ALIGN const Word16 sincos_lowres_tab_sinQ15_fx[40] = { + 0, 6393, 12540, 18205, 23170, 27246, 30274, 32138, 32767, 32138, 30274, 27246, 23170, 18205, + 12540, 6393, 0, -6393, -12540, -18205, -23170, -27246, -30274, -32138, -32768, -32138, -30274, -27246, + -23170, -18205, -12540, -6393, 0, 6393, 12540, 18205, 23170, 27246, 30274, 32138}; + +/* (PHECU_LA_48K == 0) */ + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 w_new_fs_8_LA_0[OLA_LEN_8K] = {0, 411, 1623, 3574, 6169, 9275, 12738, + 16384, 20030, 23493, 26599, 29194, 31145, 32357}; + + +RAM_ALIGN const Word16 w_old_fs_8_LA_0[OLA_LEN_8K] = { + + /* ( 32768-fliplr(w_new_fs_8_LA_0) ) *[whr3ms(0:13)*/ + 2621, 2721, 3001, 3401, 3836, 4205, 4411, 4377, 4063, 3475, 2673, 1766, 901, 253}; +#else +#define w_new_fs_8_LA_0 NULL +#define w_old_fs_8_LA_0 NULL +#endif /* SUBSET_NB */ + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 w_new_fs_16_LA_0[OLA_LEN_16K] = { + 0, 103, 411, 919, 1623, 2511, 3574, 4799, 6169, 7667, 9275, 10973, 12738, 14550, + 16384, 18218, 20030, 21795, 23493, 25101, 26599, 27969, 29194, 30257, 31145, 31849, 32357, 32665}; + +RAM_ALIGN const Word16 w_old_fs_16_LA_0[OLA_LEN_16K] = {2621, 2646, 2719, 2835, 2990, 3175, 3379, 3592, 3801, 3994, + 4158, 4282, 4355, 4369, 4317, 4196, 4005, 3746, 3425, 3050, + 2635, 2192, 1740, 1299, 889, 531, 250, 66}; +#else +#define w_new_fs_16_LA_0 NULL +#define w_old_fs_16_LA_0 NULL +#endif /* SUBSET_WB */ + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 w_new_fs_24_LA_0[OLA_LEN_24K] = { + 0, 46, 183, 411, 728, 1133, 1623, 2195, 2847, 3574, 4374, 5240, 6169, 7155, + 8192, 9275, 10398, 11555, 12738, 13942, 15160, 16384, 17608, 18826, 20030, 21213, 22370, 23493, + 24576, 25613, 26599, 27528, 28394, 29194, 29921, 30573, 31145, 31635, 32040, 32357, 32585, 32722}; + +RAM_ALIGN const Word16 w_old_fs_24_LA_0[OLA_LEN_24K] = { + 2621, 2632, 2665, 2718, 2790, 2881, 2987, 3106, 3235, 3372, 3512, 3653, 3790, 3919, + 4038, 4143, 4229, 4295, 4337, 4353, 4340, 4298, 4225, 4121, 3986, 3821, 3628, 3408, + 3165, 2902, 2622, 2330, 2032, 1732, 1437, 1152, 884, 640, 426, 249, 114, 30}; +#else +#define w_new_fs_24_LA_0 NULL +#define w_old_fs_24_LA_0 NULL +#endif /* SUBSET_SSWB */ + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 w_new_fs_32_LA_0[OLA_LEN_32K] = { + 0, 26, 103, 231, 411, 640, 919, 1247, 1623, 2044, 2511, 3022, 3574, 4167, + 4799, 5467, 6169, 6903, 7667, 8459, 9275, 10114, 10973, 11848, 12738, 13640, 14550, 15465, + 16384, 17303, 18218, 19128, 20030, 20920, 21795, 22654, 23493, 24309, 25101, 25865, 26599, 27301, + 27969, 28601, 29194, 29746, 30257, 30724, 31145, 31521, 31849, 32128, 32357, 32537, 32665, 32742}; + +RAM_ALIGN const Word16 w_old_fs_32_LA_0[OLA_LEN_32K] = { + 2621, 2628, 2646, 2676, 2717, 2770, 2832, 2904, 2985, 3073, 3167, 3266, 3368, 3473, 3578, 3682, 3784, 3882, 3974, + 4059, 4135, 4202, 4257, 4299, 4328, 4342, 4340, 4323, 4288, 4236, 4167, 4081, 3977, 3856, 3719, 3567, 3400, 3220, + 3028, 2826, 2615, 2398, 2176, 1952, 1728, 1506, 1290, 1081, 882, 697, 528, 377, 248, 143, 65, 17}; +#else +#define w_new_fs_32_LA_0 NULL +#define w_old_fs_32_LA_0 NULL +#endif /* SUBSET_SWB */ + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 w_new_fs_48_LA_0[OLA_LEN_48K] = { + 0, 11, 46, 103, 183, 286, 411, 558, 728, 919, 1133, 1367, 1623, 1899, + 2195, 2511, 2847, 3201, 3574, 3965, 4374, 4799, 5240, 5697, 6169, 6655, 7155, 7667, + 8192, 8728, 9275, 9832, 10398, 10973, 11555, 12144, 12738, 13338, 13942, 14550, 15160, 15771, + 16384, 16997, 17608, 18218, 18826, 19430, 20030, 20624, 21213, 21795, 22370, 22936, 23493, 24040, + 24576, 25101, 25613, 26113, 26599, 27071, 27528, 27969, 28394, 28803, 29194, 29567, 29921, 30257, + 30573, 30869, 31145, 31401, 31635, 31849, 32040, 32210, 32357, 32482, 32585, 32665, 32722, 32757}; + +RAM_ALIGN const Word16 w_old_fs_48_LA_0[OLA_LEN_48K] = { + 2621, 2624, 2632, 2646, 2664, 2688, 2717, 2750, 2789, 2831, 2878, 2929, 2983, 3041, 3101, 3164, 3229, + 3296, 3365, 3434, 3504, 3573, 3643, 3711, 3778, 3844, 3907, 3967, 4024, 4078, 4128, 4173, 4213, 4248, + 4278, 4301, 4319, 4330, 4334, 4331, 4321, 4303, 4278, 4246, 4206, 4158, 4102, 4038, 3967, 3889, 3803, + 3710, 3611, 3505, 3392, 3274, 3150, 3021, 2888, 2750, 2609, 2465, 2319, 2171, 2022, 1873, 1724, 1576, + 1430, 1287, 1147, 1011, 880, 755, 637, 527, 424, 331, 248, 175, 114, 65, 29, 7}; +#else +#define w_new_fs_48_LA_0 NULL +#define w_old_fs_48_LA_0 NULL +#endif /* SUBSET_FB */ + +RAM_ALIGN const Word16 *const w_new[5] = {w_new_fs_8_LA_0, w_new_fs_16_LA_0, w_new_fs_24_LA_0, w_new_fs_32_LA_0, + w_new_fs_48_LA_0}; +RAM_ALIGN const Word16 *const w_old[5] = {w_old_fs_8_LA_0, w_old_fs_16_LA_0, w_old_fs_24_LA_0, w_old_fs_32_LA_0, + w_old_fs_48_LA_0}; + +RAM_ALIGN const Word16 COPY_LEN[5] = {COPY_LEN_8K, COPY_LEN_16K, COPY_LEN_24K, COPY_LEN_32K, COPY_LEN_48K}; /* 2ms */ +RAM_ALIGN const Word16 OLA_LEN[5] = {OLA_LEN_8K, OLA_LEN_16K, OLA_LEN_24K, OLA_LEN_32K, OLA_LEN_48K}; /*1.75 ms mix */ + +RAM_ALIGN const Word16 num_FsByResQ0[5] = {LPROT8K, LPROT16K, LPROT24K, LPROT32K, LPROT48K}; +RAM_ALIGN const Word16 *const LprotSzPtr = num_FsByResQ0; +RAM_ALIGN const Word16 InvLprot_Q22[5] = {INV_LPROT8K_Q22, INV_LPROT16K_Q22, INV_LPROT24K_Q22, INV_LPROT32K_Q22, + INV_LPROT48K_Q22}; +RAM_ALIGN const Word16 PhEcuFftScale[5] = {0, 0, 8, 0, 4}; + +RAM_ALIGN const Word16 oneOverFrameQ15Tab[5] = {INV_L_FRAME8K_Q15, INV_L_FRAME16K_Q15, INV_L_FRAME24K_Q15, + INV_L_FRAME32K_Q15, INV_L_FRAME48K_Q15}; + + +RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxDnShift[5] = {6, 7, 7, 8, 8}; /* TOTAL FFT adjutmenst shift */ +RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxScaleQ15[5] = {32767, 32767, 21845, 32767, + 21845}; /* fractional fft adjustment 1./ fft_fs_scale */ + +RAM_ALIGN const Word16 PhEcu_frac_thr_rise_lin_Q15[MAX_LGW] = {3277, 3277, 3277, 3277, 3277, + 3277, 3277, 3277, 3277}; /* for now all fixed to 10dB */ +RAM_ALIGN const Word16 PhEcu_frac_thr_decay_lin_Q15[MAX_LGW] = { + 3277, 3277, 3277, 3277, 3277, + 3277, 3277, 3277, 3277}; /* thresh_rise_dB=10; thresh_lin = 1.0/( 10^(thresh_rise_dB/10) ); */ + +RAM_ALIGN const Word16 mdct_grp_bins_fx[MAX_LGW + 2] = {4, 14, 24, 44, 84, 164, 244, 324, 404, 484}; +RAM_ALIGN const Word16 xavg_N_grp_fx[5] = {4, 5, 6, 7, 8}; + + +RAM_ALIGN const Word16 spec_shape_headroom[5] = {3, 4, 4, 4, 4}; +RAM_ALIGN const Word16 rectLengthTab[NUM_SAMP_FREQ] = {80, 160, 240, 320, 480, 960}; /* 10ms */ +RAM_ALIGN const Word16 hamm_len2Tab[5] = {24, 48, 72, 96, 144}; /* 3 ms*/ + +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +RAM_ALIGN const Word16 PLC_FADEOUT_TYPE_2_SELECTOR = 10; /* can take values from 0 to 10, default is 10 for longer fadeout*/ +#else +# ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH +RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_5MS[30] = { /* 0.5^(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0)*/ + 16384,11585,8192,5792,4096,2896,2048,1448,1024,724,512,362,256,181,128,91,64,45,32,23,16,11,8,6,4,3,2,1,1,1}; +RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_2_5MS[60] = { /* 0.5^(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0)*/ + 16384,13777,11585,9742,8192,6889,5793,4871,4096,3444,2896,2435,2048,1722,1448,1218,1024,861,724,609,512,431,362,304,256,215,181,152,128,108,91,76,64,54,45,38,32,27,23,19,16,13,11,10,8,7,6,5,4,3,3,2,2,2,1,1,1,1,1,1}; +# endif +#endif + +RAM_ALIGN const Word16 NN_thresh = 0x7800; /* 30*2^10 */ +RAM_ALIGN const Word16 NN_thresh_exp = -10; +/* Tone detector */ +#ifdef CR8_E_TONE_DETECTOR +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 TD_HR_thresh_10ms = 83402; +# ifdef ENABLE_075_DMS_MODE +RAM_ALIGN const Word32 TD_HR_thresh_7_5ms = 743496; +# endif +RAM_ALIGN const Word32 TD_HR_thresh_5ms = 382564; +RAM_ALIGN const Word32 TD_HR_thresh_2_5ms = 301695; +# endif /* ENABLE_HR_MODE */ +#endif /* CR8_E_TONE_DETECTOR */ +RAM_ALIGN const Word32 BW_thresh_quiet[4] = {0x14000000, 0xA000000, 0xA000000, 0xA000000}; /* [20,10,10,10]*2^24 */ +RAM_ALIGN const Word16 BW_thresh_quiet_exp = 31 - 24; +RAM_ALIGN const Word16 BW_thresh_brickwall[4] = { + 1036, 164, 327, 327}; /* (1/(10^(ctrl.BW_thresh_brickwall/10))*2^15) with [15,23,20,20] dB*/ + +RAM_ALIGN const Word16 BW_brickwall_dist[4] = {4, 4, 3, 1}; +RAM_ALIGN const Word16 BW_warp_idx_start_16k[4] = { + 53, 0, 0, 0}; /* indices for warped bands, with an offset of [17,23,23,23] bins for the start_idx */ +RAM_ALIGN const Word16 BW_warp_idx_stop_16k[4] = { + 63, 0, 0, + 0}; /*'-1' since this is not matlab and another '-1' because of the different formatting of acc_coeff_per_band*/ +RAM_ALIGN const Word16 BW_warp_idx_start_24k[4] = {47, 59, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_24k[4] = {56, 63, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_32k[4] = {44, 54, 60, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_32k[4] = {52, 59, 63, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_48k[4] = {41, 51, 57, 61}; +RAM_ALIGN const Word16 BW_warp_idx_stop_48k[4] = {49, 55, 60, 63}; +RAM_ALIGN const Word16 *const BW_warp_idx_start_all[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_start_16k, BW_warp_idx_start_24k, BW_warp_idx_start_32k, BW_warp_idx_start_48k}; +RAM_ALIGN const Word16 *const BW_warp_idx_stop_all[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_stop_16k, BW_warp_idx_stop_24k, BW_warp_idx_stop_32k, BW_warp_idx_stop_48k}; + +RAM_ALIGN const Word16 BW_brickwall_dist_5ms[4] = {4, 4, 3, 1}; +RAM_ALIGN const Word16 BW_warp_idx_start_16k_5ms[4] = {39, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_16k_5ms[4] = {49, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_24k_5ms[4] = {35, 47, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_24k_5ms[4] = {44, 51, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_32k_5ms[4] = {34, 44, 50, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_32k_5ms[4] = {42, 49, 53, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_48k_5ms[4] = {32, 42, 48, 52}; +RAM_ALIGN const Word16 BW_warp_idx_stop_48k_5ms[4] = {40, 46, 51, 54}; +RAM_ALIGN const Word16 *const BW_warp_idx_start_all_5ms[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_start_16k_5ms, BW_warp_idx_start_24k_5ms, BW_warp_idx_start_32k_5ms, BW_warp_idx_start_48k_5ms}; +RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_5ms[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_stop_16k_5ms, BW_warp_idx_stop_24k_5ms, BW_warp_idx_stop_32k_5ms, BW_warp_idx_stop_48k_5ms}; + +RAM_ALIGN const Word16 BW_brickwall_dist_2_5ms[4] = {4, 4, 3, 1}; +RAM_ALIGN const Word16 BW_warp_idx_start_16k_2_5ms[4] = {24, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_16k_2_5ms[4] = {34, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_24k_2_5ms[4] = {24, 35, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_24k_2_5ms[4] = {32, 39, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_32k_2_5ms[4] = {24, 33, 39, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_32k_2_5ms[4] = {31, 38, 42, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_48k_2_5ms[4] = {22, 31, 37, 41}; +RAM_ALIGN const Word16 BW_warp_idx_stop_48k_2_5ms[4] = {29, 35, 40, 43}; +RAM_ALIGN const Word16 *const BW_warp_idx_start_all_2_5ms[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_start_16k_2_5ms, BW_warp_idx_start_24k_2_5ms, BW_warp_idx_start_32k_2_5ms, BW_warp_idx_start_48k_2_5ms}; +RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_2_5ms[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_stop_16k_2_5ms, BW_warp_idx_stop_24k_2_5ms, BW_warp_idx_stop_32k_2_5ms, BW_warp_idx_stop_48k_2_5ms}; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 BW_brickwall_dist_7_5ms[4] = {4, 4, 3, 2}; +RAM_ALIGN const Word16 BW_warp_idx_start_16k_7_5ms[4] = {51, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_16k_7_5ms[4] = {63, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_24k_7_5ms[4] = {45, 58, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_24k_7_5ms[4] = {55, 63, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_32k_7_5ms[4] = {42, 53, 60, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_32k_7_5ms[4] = {51, 58, 63, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_48k_7_5ms[4] = {40, 51, 57, 61}; +RAM_ALIGN const Word16 BW_warp_idx_stop_48k_7_5ms[4] = {48, 55, 60, 63}; +RAM_ALIGN const Word16 *const BW_warp_idx_start_all_7_5ms[] = { + BW_warp_idx_start_16k_7_5ms, BW_warp_idx_start_24k_7_5ms, BW_warp_idx_start_32k_7_5ms, BW_warp_idx_start_48k_7_5ms}; +RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_7_5ms[] = { + BW_warp_idx_stop_16k_7_5ms, BW_warp_idx_stop_24k_7_5ms, BW_warp_idx_stop_32k_7_5ms, BW_warp_idx_stop_48k_7_5ms}; +# endif + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 BW_cutoff_bin_all[] = {80, 160, 240, 320, 400, 400}; +RAM_ALIGN const Word16 BW_cutoff_bin_all_HR[] = {80, 160, 240, 320, 400, 400}; +RAM_ALIGN const Word16 BW_cutoff_bits_all[] = {0, 1, 2, 2, 3, 0}; +#else /* ENABLE_HR_MODE */ +RAM_ALIGN const Word16 BW_cutoff_bin_all[] = {80, 160, 240, 320, 400}; +RAM_ALIGN const Word16 BW_cutoff_bits_all[] = {0, 1, 2, 2, 3}; +#endif /* ENABLE_HR_MODE */ + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 LowDelayShapes_n960_len[6] = {130, 260, 390, 520, 780, 1560}; +#else +RAM_ALIGN const Word16 LowDelayShapes_n960_len[5] = {130, 260, 390, 520, 780}; +#endif +RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes[NUM_SAMP_FREQ] = {30, + 60, + 90, + 120, + 180 +#ifdef ENABLE_HR_MODE + , 360 +#endif +}; + +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_HR_MODE +const Word16 LowDelayShapes_n960_len_7_5ms[6] = {106, 212, 318, 424, 636, 1272}; +# else +const Word16 LowDelayShapes_n960_len_7_5ms[5] = {106, 212, 318, 424, 636}; +# endif +const Word16 LowDelayShapes_n960_la_zeroes_7_5ms[NUM_SAMP_FREQ] = {14, 28, 42, 56, 84 +# ifdef ENABLE_HR_MODE + , 168 +# endif +}; +# ifdef ENABLE_HR_MODE +# ifdef SUBSET_NB +const Word32 MDCT_WINDOW_FS_8000_frame_ms_75[106] = { + 4627440, 11253200, 21594770, 36220454, 55523513, 79715027, 108949241, 143324500, 182870991, + 227518888, 277136190, 331449220, 390143896, 452770029, 518831181, 587821768, 659169189, 732247130, + 806397033, 880930033, 955136210, 1028289061, 1099721013, 1168761191, 1234831373, 1297335398, 1355817068, + 1409866562, 1459158403, 1503372583, 1542341368, 1575958063, 1604141948, 1626962506, 1644516439, 1657006271, + 1664740913, 1668084651, 1667510566, 1663566793, 1656808751, 1647805301, 1637186879, 1625507591, 1613355502, + 1601336341, 1590266842, 1579708994, 1571001708, 1564080946, 1558867236, 1555257286, 1553127519, 1552339115, + 1552734517, 1554146897, 1556401387, 1559318893, 1562715844, 1566405205, -1570197717, -1573904742, -1577333468, + -1580290211, -1582582625, -1584022156, -1584425628, -1583621336, -1581452727, -1577790475, -1572531065, -1565603566, + -1556974029, -1546637213, -1533223967, -1517247857, -1497930249, -1474813741, -1447477329, -1415559391, -1378853853, + -1337198324, -1290524957, -1238912889, -1182546000, -1121735805, -1056935470, -988679598, -917579357, -844370566, + -769774729, -694577976, -619621377, -545775321, -473935196, -404978161, -339758802, -279035319, -223452287, + -173535871, -129697804, -92268521, -61482210, -37424210, -19913685, -8400842}; +# else +# define MDCT_WINDOW_FS_8000_frame_ms_75 NULL +# endif +# ifdef SUBSET_WB +const Word32 MDCT_WINDOW_FS_16000_frame_ms_75[212] = { + 2448850, 4225281, 6560055, 9518849, 13169928, 17558685, 22724572, 28709046, 35532706, + 43206772, 51759643, 61197652, 71531905, 82773688, 94926633, 107995294, 121978042, 136866522, + 152653815, 169326944, 186873869, 205260070, 224464206, 244469708, 265226672, 286694090, 308842566, + 331620399, 354982140, 378884306, 403282899, 428126460, 453358062, 478925896, 504771155, 530831178, + 557056009, 583378298, 609738583, 636071404, 662314239, 688406753, 714278048, 739869110, 765133864, + 789997902, 814413107, 838333634, 861699657, 884456686, 906561215, 927970820, 948653245, 968562870, + 987675635, 1005965699, 1023398499, 1039938064, 1055570884, 1070287165, 1084066983, 1096897234, 1108786027, + 1119713468, 1129673618, 1138691939, 1146759882, 1153881756, 1160087929, 1165385723, 1169796304, 1173355296, + 1176085471, 1178017803, 1179194996, 1179657892, 1179448026, 1178622117, 1177223060, 1175290297, 1172896803, + 1170081494, 1166887472, 1163391971, 1159633509, 1155652038, 1151518603, 1147273273, 1142969676, 1138666561, + 1134412515, 1130255869, 1126558117, 1122496331, 1118765157, 1115363902, 1112285558, 1109526458, 1107080797, + 1104939816, 1103098430, 1101543766, 1100269289, 1099261964, 1098510648, 1098002762, 1097726182, 1097665183, + 1097807233, 1098135900, 1098637579, 1099295163, 1100094642, 1101018650, 1102052611, 1103178569, 1104381936, + 1105644852, 1106951761, 1108284322, -1109627660, -1110963442, -1112276637, -1113548581, -1114763260, -1115902204, + -1116950143, -1117888308, -1118701309, -1119370903, -1119882282, -1120217558, -1120362527, -1120300271, -1120018073, + -1119500244, -1118735095, -1117710865, -1116417682, -1114844247, -1112986355, -1110833953, -1108385410, -1105635984, + -1102584489, -1099232427, -1095578582, -1091628491, -1086655755, -1081531176, -1075887278, -1069676603, -1062851542, + -1055375495, -1047209387, -1038304906, -1028645771, -1018191542, -1006905821, -994788854, -981815515, -967960849, + -953236015, -937625018, -921120793, -903739802, -885489416, -866385515, -846456825, -825718325, -804213946, + -781984241, -759069751, -735509614, -711369811, -686704607, -661557703, -636008311, -610118476, -583941228, + -557562076, -531035554, -504439473, -477846967, -451338312, -424989596, -398869327, -373061710, -347653667, + -322717851, -298330826, -274560095, -251498346, -229196510, -207718889, -187124805, -167466055, -148790641, + -131139192, -114544857, -99042767, -84660988, -71425324, -59356162, -48470733, -38776535, -30272788, + -22943830, -16759108, -11669404, -7602417, -4461896 }; +# else +# define MDCT_WINDOW_FS_16000_frame_ms_75 NULL +# endif +# ifdef SUBSET_SSWB +const Word32 MDCT_WINDOW_FS_24000_frame_ms_75[318] = { + 3569045, 5343308, 7469087, 10008734, 12994076, 16456850, 20430606, 24935492, 29988837, + 35611849, 41823777, 48643571, 56071893, 64113030, 72783590, 82094564, 92046985, 102645585, + 113894977, 125803748, 138373328, 151602749, 165496877, 180058414, 195279760, 211161232, 227698398, + 244884561, 262716182, 281188032, 300290267, 320009308, 340323456, 361229416, 382724592, 404784463, + 427382077, 450499367, 474123138, 498236134, 522813796, 547827872, 573261791, 599094644, 625301687, + 651864990, 678758112, 705953149, 733423301, 761143017, 789088191, 817226769, 845526155, 873965021, + 902516713, 931147088, 959825021, 988524208, 1017210384, 1045855673, 1074425690, 1102896296, 1131233244, + 1159399102, 1187365932, 1215118091, 1242623432, 1269848445, 1296758792, 1323338775, 1349569176, 1375419011, + 1400856664, 1425860452, 1450405500, 1474469418, 1498033883, 1521084216, 1543600669, 1565562699, 1586950362, + 1607758181, 1627973678, 1647578495, 1666558705, 1684890994, 1702569411, 1719588669, 1735945131, 1751628259, + 1766631537, 1780942408, 1794568179, 1807511369, 1819759624, 1831304037, 1842145330, 1852303571, 1861781063, + 1870563512, 1878654482, 1886073254, 1892829269, 1898924017, 1904366694, 1909168622, 1913346034, 1916917451, + 1919887595, 1922277229, 1924098512, 1925377637, 1926138245, 1926390110, 1926159966, 1925475348, 1924365664, + 1922840889, 1920921471, 1918639476, 1916032510, 1913117957, 1909905898, 1906425851, 1902721668, 1898817211, + 1894724624, 1890460570, 1886061947, 1881561147, 1876974490, 1872321669, 1867634952, 1862942467, 1858269659, + 1853636539, 1849063935, 1844532585, 1840901848, 1836281978, 1831977326, 1827914309, 1824090826, 1820508133, + 1817156298, 1814036518, 1811148878, 1808486122, 1806045111, 1803824889, 1801820200, 1800024837, 1798435525, + 1797047955, 1795856425, 1794854508, 1794036436, 1793397182, 1792930395, 1792629275, 1792486811, 1792496288, + 1792650932, 1792943382, 1793366271, 1793912436, 1794574259, 1795343928, 1796214319, 1797177519, 1798225910, + 1799351580, 1800546365, 1801802795, 1803112835, 1804468826, 1805862173, 1807285016, 1808728934, 1810185719, + -1811649011, -1813108149, -1814556719, -1815986412, -1817388652, -1818755380, -1820077746, -1821347804, -1822557195, + -1823698097, -1824761958, -1825740466, -1826625594, -1827409009, -1828083190, -1828639928, -1829071236, -1829369628, + -1829527454, -1829537126, -1829391729, -1829084485, -1828608410, -1827956837, -1827123677, -1826104316, -1824893520, + -1823485537, -1821875510, -1820060164, -1818037432, -1815802468, -1813351581, -1810685587, -1807803281, -1804699559, + -1801376829, -1797838749, -1794078176, -1790099212, -1785902823, -1781420977, -1775757613, -1770414541, -1764657397, + -1758514553, -1751966917, -1744988832, -1737559493, -1729660865, -1721279216, -1712390301, -1702968220, -1693002531, + -1682487980, -1671402851, -1659722977, -1647435681, -1634547191, -1621051754, -1606928538, -1592163286, -1576765074, + -1560734340, -1544063625, -1526744164, -1508774562, -1490169863, -1470931267, -1451061598, -1430573380, -1409469788, + -1387774154, -1365486503, -1342628496, -1319212449, -1295268938, -1270814307, -1245866917, -1220443956, -1194576202, + -1168294208, -1141628864, -1114589888, -1087212858, -1059529377, -1031588154, -1003401722, -974995147, -946412027, + -917694623, -888859295, -859943075, -830987474, -802029563, -773092402, -744234412, -715477138, -686865195, + -658426713, -630207057, -602244426, -574581369, -547253226, -520293544, -493735699, -467628500, -441995738, + -416889401, -392319671, -368337811, -344954670, -322202233, -300117288, -278711744, -258020476, -238052276, + -218834457, -200381964, -182706579, -165829103, -149762124, -134517743, -120107705, -106542511, -93830987, + -81979923, -70993541, -60872925, -51615362, -43213756, -35655914, -28924065, -22994343, -17836407, + -13413907, -9700456, -6939916 }; +# else +# define MDCT_WINDOW_FS_24000_frame_ms_75 NULL +# endif +# ifdef SUBSET_SWB +const Word32 MDCT_WINDOW_FS_32000_frame_ms_75[424] = { + 2898737, 4022405, 5281441, 6723878, 8372060, 10235970, 12328606, 14657777, 17238266, + 20075996, 23180406, 26552429, 30204258, 34141418, 38374110, 42901881, 47726394, 52848657, + 58275464, 64009892, 70057240, 76417471, 83091786, 90080421, 97386522, 105014921, 112964415, + 121235754, 129827911, 138744722, 147986004, 157551876, 167437738, 177647147, 188174741, 199022831, + 210184946, 221662871, 233452811, 245554560, 257961285, 270671503, 283672733, 296964439, 310542664, + 324409414, 338557330, 352975270, 367652577, 382584217, 397764861, 413190770, 428852496, 444742036, + 460850489, 477166934, 493686689, 510401963, 527305552, 544386461, 561639986, 579055156, 596625027, + 614334635, 632177187, 650141962, 668224093, 686407908, 704684687, 723041108, 741470500, 759961912, + 778506953, 797092489, 815707619, 834339025, 852979862, 871616777, 890238991, 908834402, 927390921, + 945902091, 964354406, 982734524, 1001028580, 1019227984, 1037324578, 1055313224, 1073178103, 1090910419, + 1108493143, 1125919532, 1143183321, 1160279970, 1177195986, 1193922020, 1210443853, 1226757428, 1242848720, + 1258716966, 1274346305, 1289734310, 1304873724, 1319761111, 1334385677, 1348742053, 1362821420, 1376620057, + 1390134975, 1403361262, 1416296924, 1428929625, 1441257929, 1453270092, 1464967234, 1476341997, 1487396355, + 1498127704, 1508535547, 1518610856, 1528355951, 1537762901, 1546836443, 1555575202, 1563981756, 1572051527, + 1579779433, 1587162378, 1594203212, 1600912026, 1607289540, 1613333597, 1619037500, 1624404299, 1629439428, + 1634149881, 1638537653, 1642603536, 1646350593, 1649779860, 1652898979, 1655708955, 1658229426, 1660449352, + 1662377545, 1664024217, 1665388315, 1666481709, 1667311651, 1667891108, 1668216427, 1668300198, 1668150304, + 1667777789, 1667191944, 1666404102, 1665413150, 1664228568, 1662860495, 1661323561, 1659629730, 1657785817, + 1655794977, 1653662566, 1651401295, 1649028654, 1646557403, 1643989827, 1641331208, 1638586818, 1635770553, + 1632894967, 1629971201, 1627004437, 1624002536, 1620971847, 1617927153, 1614878122, 1611835451, 1608805100, + 1605795099, 1602815547, 1599884473, 1596942341, 1594771673, 1591702411, 1588839753, 1586088059, 1583448720, + 1580925703, 1578521775, 1576232766, 1574055288, 1571990953, 1570040827, 1568202332, 1566472498, 1564851004, + 1563337829, 1561931261, 1560628909, 1559429084, 1558330506, 1557331359, 1556429824, 1555624516, 1554913143, + 1554292592, 1553760945, 1553317125, 1552958916, 1552683122, 1552487276, 1552369480, 1552327252, 1552357490, + 1552457675, 1552625785, 1552859126, 1553154340, 1553508826, 1553920495, 1554386414, 1554903212, 1555468295, + 1556079427, 1556733719, 1557427851, 1558158741, 1558924090, 1559721218, 1560546581, 1561397206, 1562271110, + 1563165114, 1564075458, 1564999378, 1565934440, 1566877694, 1567825218, -1568775555, -1569724227, -1570669763, + -1571608214, -1572536583, -1573452385, -1574352788, -1575233942, -1576092574, -1576926600, -1577732933, -1578507896, + -1579248680, -1579952850, -1580617181, -1581238194, -1581812847, -1582338764, -1582813204, -1583232638, -1583593989, + -1583895045, -1584133086, -1584304626, -1584406873, -1584437736, -1584394635, -1584274418, -1584074588, -1583793268, + -1583428030, -1582975737, -1582434279, -1581802744, -1581079400, -1580261338, -1579346529, -1578333908, -1577222011, + -1576009429, -1574695339, -1573278552, -1571757228, -1570130264, -1568398303, -1566561731, -1564618340, -1562566382, + -1560407784, -1558145041, -1555775754, -1553296829, -1550712057, -1548026396, -1545242289, -1542268350, -1538423280, + -1535025262, -1531395445, -1527591708, -1523601949, -1519416343, -1515026680, -1510422354, -1505596841, -1500543057, + -1495258714, -1489733930, -1483960441, -1477928294, -1471632952, -1465071334, -1458241898, -1451136236, -1443746092, + -1436060907, -1428079531, -1419805847, -1411239360, -1402373353, -1393199823, -1383713926, -1373917135, -1363813377, + -1353400513, -1342677100, -1331640941, -1320284636, -1308611825, -1296630892, -1284342674, -1271742396, -1258835954, + -1245628407, -1232122065, -1218316234, -1204224404, -1189846207, -1175175506, -1160242956, -1145031655, -1129564821, + -1113844775, -1097879736, -1081675373, -1065238433, -1048578417, -1031707925, -1014636539, -997375667, -979937295, + -962314566, -944532531, -926597437, -908531127, -890341534, -872033654, -853615925, -835103871, -816513734, + -797862235, -779149108, -760390220, -741599202, -722791848, -703980340, -685176354, -666389658, -647646244, + -628944722, -610316405, -591754523, -573282405, -554915396, -536666275, -518550375, -500581949, -482775076, + -465139339, -447692836, -430439482, -413418994, -396596647, -380036004, -363729221, -347677810, -331912032, + -316431125, -301242631, -286354637, -271795849, -257560706, -243655300, -230096441, -216894979, -204043835, + -191560528, -179450345, -167715723, -156363602, -145400931, -134832648, -124663143, -114896281, -105536276, + -96587551, -88053476, -79936384, -72238586, -64962154, -58107752, -51674659, -45661585, -40066372, + -34884913, -30111469, -25739290, -21759792, -18161914, -14933570, -12062384, -9522842, -7254663, + -5656627 }; +# else +# define MDCT_WINDOW_FS_32000_frame_ms_75 NULL +# endif +# ifdef SUBSET_FB +const Word32 MDCT_WINDOW_FS_48000_frame_ms_75[636] = { + 2204435, 2827689, 3443319, 4131102, 4878935, 5703040, 6599364, 7574899, 8628974, + 9768536, 10991420, 12304931, 13709256, 15207323, 16799052, 18489324, 20275023, 22160933, + 24148496, 26240076, 28435235, 30739604, 33150351, 35668955, 38294878, 41029635, 43871618, + 46825882, 49890883, 53068998, 56360550, 59766888, 63284768, 66918075, 70664961, 74526448, + 78503039, 82597929, 86807681, 91135031, 95578822, 100139618, 104816236, 109611835, 114523552, + 119554039, 124702224, 129967749, 135348514, 140848111, 146462751, 152193324, 158039847, 164002831, + 170078327, 176269443, 182573647, 188991411, 195521914, 202165741, 208918745, 215783357, 222755240, + 229832331, 237013913, 244302241, 251692923, 259188940, 266788795, 274490295, 282289304, 290186132, + 298175224, 306257381, 314430505, 322694044, 331045821, 339487261, 348012274, 356620678, 365310317, + 374079074, 382922254, 391842074, 400834178, 409898068, 419031270, 428232881, 437497913, 446828175, + 456219802, 465670981, 475178925, 484743299, 494357854, 504022976, 513735237, 523492799, 533292796, + 543136028, 553015990, 562931887, 572880536, 582859524, 592864355, 602896501, 612951047, 623027190, + 633121825, 643232873, 653354882, 663488155, 673627234, 683771323, 693918098, 704065470, 714207061, + 724344108, 734471992, 744587758, 754688429, 764774608, 774840295, 784884831, 794903648, 804894011, + 814851825, 824777247, 834664477, 844515260, 854327259, 864098094, 873822193, 883500485, 893125924, + 902697010, 912211002, 921668164, 931065070, 940403253, 949676961, 958885223, 968024298, 977093615, + 986086667, 995005058, 1003845874, 1012604766, 1021282611, 1029879030, 1038386135, 1046806723, 1055138039, + 1063379017, 1071528406, 1079585832, 1087546197, 1095410412, 1103175087, 1110839263, 1118400067, 1125861251, + 1133217689, 1140469587, 1147616705, 1154658548, 1161589135, 1168411456, 1175122212, 1181718798, 1188199640, + 1194567214, 1200817042, 1206950737, 1212967954, 1218868269, 1224650873, 1230316551, 1235861165, 1241285527, + 1246589565, 1251772729, 1256831629, 1261771016, 1266587826, 1271284733, 1275860443, 1280315823, 1284645497, + 1288852346, 1292933744, 1296889962, 1300722079, 1304434734, 1308025653, 1311497310, 1314848195, 1318076916, + 1321181451, 1324164254, 1327024207, 1329764950, 1332387885, 1334893025, 1337281173, 1339554157, 1341707740, + 1343747791, 1345671522, 1347481634, 1349179572, 1350764422, 1352239980, 1353613012, 1354873992, 1356030340, + 1357079368, 1358026526, 1358871638, 1359613742, 1360257791, 1360804083, 1361255397, 1361617096, 1361885808, + 1362062609, 1362151603, 1362153995, 1362072233, 1361909271, 1361666938, 1361347766, 1360955593, 1360489817, + 1359950116, 1359340101, 1358660855, 1357916180, 1357108339, 1356243400, 1355321087, 1354344570, 1353313776, + 1352230258, 1351093731, 1349909242, 1348677915, 1347405592, 1346095404, 1344750475, 1343369336, 1341955495, + 1340508098, 1339029437, 1337520955, 1335988076, 1334432030, 1332857982, 1331266254, 1329659151, 1328036799, + 1326403000, 1324757066, 1323104230, 1321446604, 1319787700, 1318127699, 1316471738, 1314818892, 1313173031, + 1311534229, 1309906742, 1308289975, 1306691587, 1305107061, 1303560954, 1302485706, 1300837265, 1299230148, + 1297667349, 1296147118, 1294669845, 1293233008, 1291838729, 1290486465, 1289178223, 1287911298, 1286686132, + 1285500617, 1284356733, 1283253302, 1282192039, 1281170798, 1280190420, 1279248602, 1278346792, 1277483349, + 1276659918, 1275874601, 1275128550, 1274419448, 1273748350, 1273113203, 1272515449, 1271953180, 1271427649, + 1270936717, 1270481540, 1270059928, 1269672963, 1269318382, 1268997326, 1268707731, 1268450837, 1268224483, + 1268029756, 1267864381, 1267729424, 1267622629, 1267545013, 1267494302, 1267471571, 1267474578, 1267504402, + 1267558747, 1267638603, 1267741668, 1267868942, 1268018115, 1268190239, 1268383008, 1268597404, 1268831071, + 1269084943, 1269356717, 1269647473, 1269954877, 1270279875, 1270620090, 1270976496, 1271346828, 1271732058, + 1272129716, 1272540744, 1272962829, 1273396990, 1273840888, 1274295422, 1274758248, 1275230417, 1275709517, + 1276196415, 1276688706, 1277187379, 1277690114, 1278197794, 1278707969, 1279221647, 1279736503, 1280253498, + -1280770244, -1281287656, -1281803343, -1282318265, -1282830085, -1283339807, -1283844964, -1284346432, -1284841866, + -1285332250, -1285815146, -1286291410, -1286758593, -1287217737, -1287666452, -1288105628, -1288532876, -1288949203, + -1289352245, -1289742931, -1290118731, -1290480607, -1290826232, -1291156571, -1291469183, -1291765004, -1292041634, + -1292300151, -1292538184, -1292756663, -1292953166, -1293128674, -1293280819, -1293410658, -1293515818, -1293597309, + -1293652773, -1293683213, -1293686282, -1293663081, -1293611326, -1293532118, -1293423149, -1293285472, -1293116803, + -1292918254, -1292687534, -1292425784, -1292130842, -1291804017, -1291443255, -1291049775, -1290621337, -1290159111, + -1289660945, -1289128099, -1288558489, -1287953483, -1287311252, -1286633366, -1285917866, -1285165943, -1284375393, + -1283547520, -1282680564, -1281776335, -1280833350, -1279853230, -1278833852, -1277776244, -1276678466, -1275542433, + -1274367185, -1273154903, -1271903726, -1270614321, -1269284275, -1267915816, -1266508671, -1265065178, -1263583140, + -1262063220, -1260504007, -1258908698, -1256628331, -1254761985, -1252853377, -1250881358, -1248844632, -1246741358, + -1244569594, -1242327619, -1240012651, -1237623600, -1235156149, -1232610864, -1229984110, -1227275248, -1224482272, + -1221606271, -1218642652, -1215591412, -1212448650, -1209213243, -1205881571, -1202455146, -1198931234, -1195311772, + -1191594196, -1187777826, -1183858288, -1179836046, -1175706321, -1171469469, -1167124636, -1162674694, -1158117379, + -1153454731, -1148683225, -1143802349, -1138808714, -1133702904, -1128481825, -1123149280, -1117704914, -1112149514, + -1106481061, -1100702139, -1094806903, -1088800296, -1082676113, -1076437274, -1070082677, -1063618676, -1057039488, + -1050351248, -1043548836, -1036634133, -1029608325, -1022475106, -1015230021, -1007878923, -1000415821, -992849913, + -985179219, -977404151, -969525479, -961538535, -953457394, -945280420, -936999272, -928626277, -920160734, + -911603664, -902957625, -894223210, -885402362, -876498250, -867508512, -858440255, -849293347, -840074392, + -830781521, -821419104, -811990901, -802499334, -792938179, -783315469, -773636100, -763901035, -754111866, + -744278025, -734399140, -724475975, -714510329, -704504133, -694460237, -684383382, -674277250, -664145566, + -653994294, -643817229, -633622219, -623410967, -613187040, -602954520, -592717105, -582476532, -572238350, + -562002979, -551770150, -541551921, -531349514, -521160592, -510991643, -500852505, -490735715, -480646079, + -470590740, -460574626, -450595871, -440662753, -430774557, -420941335, -411160195, -401435877, -391774603, + -382174290, -372642476, -363180190, -353786746, -344482765, -335253937, -326094163, -317034690, -308063867, + -299187762, -290405275, -281715156, -273134873, -264653333, -256282164, -248014183, -239853113, -231807709, + -223884020, -216073113, -208387006, -200816625, -193373144, -186056104, -178871459, -171808633, -164881963, + -158086310, -151426496, -144902306, -138514809, -132265008, -126156408, -120188845, -114364736, -108683712, + -103148269, -97758088, -92515604, -87420431, -82474860, -77678410, -73033188, -68538592, -64196501, + -60006167, -55969182, -52084610, -48353698, -44775286, -41350196, -38077002, -34956005, -31985545, + -29165263, -26493253, -23968386, -21588587, -19351751, -17255806, -15297341, -13474667, -11782386, + -10220076, -8778515, -7460996, -6246830, -5152154, -4038973 }; +# else +# define MDCT_WINDOW_FS_48000_frame_ms_75 NULL +# endif + +const Word32 *const LowDelayShapes_n960_7_5ms[5] = { + MDCT_WINDOW_FS_8000_frame_ms_75, MDCT_WINDOW_FS_16000_frame_ms_75, MDCT_WINDOW_FS_24000_frame_ms_75, MDCT_WINDOW_FS_32000_frame_ms_75, MDCT_WINDOW_FS_48000_frame_ms_75 }; +# else + +RAM_ALIGN const Word16 LowDelayShapes_n960_N60_7_5ms[106] = { + 71, 172, 330, 553, 847, 1216, 1662, 2187, 2790, 3472, 4229, 5058, 5953, 6909, + 7917, 8969, 10058, 11173, 12305, 13442, 14574, 15690, 16780, 17834, 18842, 19796, 20688, 21513, + 22265, 22940, 23534, 24047, 24477, 24825, 25093, 25284, 25402, 25453, 25444, 25384, 25281, 25144, + 24981, 24803, 24618, 24434, 24266, 24104, 23972, 23866, 23786, 23731, 23699, 23687, 23693, 23714, + 23749, 23793, 23845, 23901, -23959, -24016, -24068, -24113, -24148, -24170, -24176, -24164, -24131, -24075, + -23995, -23889, -23758, -23600, -23395, -23151, -22857, -22504, -22087, -21600, -21040, -20404, -19692, -18904, + -18044, -17116, -16128, -15086, -14001, -12884, -11746, -10598, -9455, -8328, -7232, -6179, -5184, -4258, + -3410, -2648, -1979, -1408, -938, -571, -304, -128}; + +RAM_ALIGN const Word16 LowDelayShapes_n960_N120_7_5ms[212] = { + 37, 64, 100, 145, 201, 268, 347, 438, 542, 659, 790, 934, 1091, 1263, + 1448, 1648, 1861, 2088, 2329, 2584, 2851, 3132, 3425, 3730, 4047, 4375, 4713, 5060, + 5417, 5781, 6154, 6533, 6918, 7308, 7702, 8100, 8500, 8902, 9304, 9706, 10106, 10504, + 10899, 11290, 11675, 12054, 12427, 12792, 13148, 13496, 13833, 14160, 14475, 14779, 15071, 15350, + 15616, 15868, 16107, 16331, 16542, 16737, 16919, 17085, 17237, 17375, 17498, 17607, 17702, 17782, + 17850, 17904, 17946, 17975, 17993, 18000, 17997, 17984, 17963, 17934, 17897, 17854, 17805, 17752, + 17695, 17634, 17571, 17506, 17440, 17375, 17310, 17246, 17190, 17128, 17071, 17019, 16972, 16930, + 16893, 16860, 16832, 16808, 16789, 16773, 16762, 16754, 16750, 16749, 16751, 16756, 16764, 16774, + 16786, 16800, 16816, 16833, 16852, 16871, 16891, 16911, -16932, -16952, -16972, -16991, -17010, -17027, + -17043, -17058, -17070, -17080, -17088, -17093, -17095, -17094, -17090, -17082, -17071, -17055, -17035, -17011, + -16983, -16950, -16913, -16871, -16824, -16773, -16717, -16657, -16581, -16503, -16417, -16322, -16218, -16104, + -15979, -15843, -15696, -15536, -15364, -15179, -14981, -14770, -14545, -14307, -14055, -13790, -13511, -13220, + -12916, -12599, -12271, -11932, -11582, -11223, -10855, -10478, -10095, -9705, -9310, -8910, -8508, -8103, + -7697, -7291, -6887, -6485, -6086, -5692, -5305, -4924, -4552, -4189, -3838, -3497, -3170, -2855, + -2555, -2270, -2001, -1748, -1511, -1292, -1090, -906, -740, -592, -462, -350, -256, -178, + -116, -68}; + +RAM_ALIGN const Word16 LowDelayShapes_n960_N180_7_5ms[318] = { + 54, 82, 114, 153, 198, 251, 312, 380, 458, 543, 638, 742, 856, 978, + 1111, 1253, 1405, 1566, 1738, 1920, 2111, 2313, 2525, 2747, 2980, 3222, 3474, 3737, + 4009, 4291, 4582, 4883, 5193, 5512, 5840, 6177, 6521, 6874, 7235, 7602, 7978, 8359, + 8747, 9141, 9541, 9947, 10357, 10772, 11191, 11614, 12041, 12470, 12902, 13336, 13771, 14208, + 14646, 15084, 15521, 15958, 16394, 16829, 17261, 17691, 18118, 18541, 18961, 19376, 19787, 20193, + 20593, 20987, 21375, 21757, 22131, 22499, 22858, 23210, 23553, 23889, 24215, 24532, 24841, 25140, + 25430, 25709, 25979, 26239, 26488, 26728, 26957, 27175, 27383, 27580, 27767, 27943, 28109, 28264, + 28409, 28543, 28666, 28779, 28882, 28975, 29058, 29132, 29195, 29250, 29295, 29332, 29359, 29379, + 29391, 29394, 29391, 29380, 29363, 29340, 29311, 29276, 29236, 29192, 29143, 29090, 29033, 28974, + 28911, 28846, 28779, 28710, 28640, 28569, 28498, 28426, 28355, 28284, 28214, 28145, 28090, 28019, + 27954, 27892, 27833, 27779, 27728, 27680, 27636, 27595, 27558, 27524, 27494, 27466, 27442, 27421, + 27403, 27387, 27375, 27365, 27358, 27353, 27351, 27351, 27354, 27358, 27365, 27373, 27383, 27395, + 27408, 27423, 27439, 27456, 27474, 27493, 27513, 27534, 27555, 27577, 27599, 27621, -27644, -27666, + -27688, -27710, -27731, -27752, -27772, -27792, -27810, -27827, -27844, -27859, -27872, -27884, -27894, -27903, + -27909, -27914, -27916, -27917, -27914, -27910, -27902, -27892, -27880, -27864, -27846, -27824, -27800, -27772, + -27741, -27707, -27670, -27629, -27585, -27538, -27487, -27433, -27375, -27315, -27251, -27182, -27096, -27014, + -26927, -26833, -26733, -26626, -26513, -26393, -26265, -26129, -25985, -25833, -25673, -25504, -25325, -25138, + -24941, -24735, -24520, -24294, -24060, -23815, -23561, -23296, -23022, -22738, -22445, -22141, -21829, -21507, + -21176, -20836, -20487, -20130, -19764, -19391, -19010, -18622, -18228, -17827, -17420, -17007, -16590, -16167, + -15741, -15311, -14877, -14441, -14003, -13563, -13122, -12680, -12238, -11796, -11356, -10917, -10481, -10047, + -9616, -9190, -8767, -8350, -7939, -7534, -7135, -6744, -6361, -5986, -5620, -5264, -4916, -4579, + -4253, -3937, -3632, -3339, -3058, -2788, -2530, -2285, -2053, -1833, -1626, -1432, -1251, -1083, + -929, -788, -659, -544, -441, -351, -272, -205, -148, -106}; + +RAM_ALIGN const Word16 LowDelayShapes_n960_N240_7_5ms[424] = { + 44, 61, 81, 103, 128, 156, 188, 224, 263, 306, 354, 405, 461, 521, + 586, 655, 728, 806, 889, 977, 1069, 1166, 1268, 1375, 1486, 1602, 1724, 1850, + 1981, 2117, 2258, 2404, 2555, 2711, 2871, 3037, 3207, 3382, 3562, 3747, 3936, 4130, + 4329, 4531, 4739, 4950, 5166, 5386, 5610, 5838, 6069, 6305, 6544, 6786, 7032, 7281, + 7533, 7788, 8046, 8307, 8570, 8836, 9104, 9374, 9646, 9920, 10196, 10474, 10753, 11033, + 11314, 11596, 11879, 12163, 12447, 12731, 13015, 13300, 13584, 13868, 14151, 14433, 14715, 14995, + 15274, 15552, 15828, 16103, 16375, 16646, 16914, 17180, 17444, 17704, 17963, 18218, 18470, 18719, + 18964, 19206, 19445, 19680, 19911, 20138, 20361, 20580, 20795, 21006, 21212, 21414, 21611, 21804, + 21992, 22175, 22354, 22527, 22696, 22860, 23018, 23172, 23321, 23464, 23603, 23736, 23864, 23988, + 24106, 24218, 24326, 24428, 24525, 24618, 24705, 24786, 24863, 24935, 25002, 25064, 25121, 25174, + 25221, 25264, 25303, 25336, 25366, 25391, 25412, 25428, 25441, 25450, 25455, 25456, 25454, 25448, + 25439, 25427, 25412, 25394, 25373, 25350, 25324, 25296, 25265, 25233, 25198, 25162, 25124, 25085, + 25045, 25003, 24960, 24916, 24871, 24826, 24780, 24734, 24688, 24641, 24595, 24548, 24502, 24457, + 24412, 24367, 24334, 24287, 24244, 24202, 24162, 24123, 24086, 24051, 24018, 23987, 23957, 23929, + 23902, 23878, 23855, 23833, 23813, 23795, 23778, 23763, 23749, 23737, 23726, 23717, 23709, 23702, + 23696, 23692, 23689, 23687, 23687, 23687, 23689, 23691, 23695, 23699, 23705, 23711, 23718, 23726, + 23735, 23744, 23754, 23764, 23776, 23787, 23799, 23812, 23825, 23838, 23852, 23866, 23880, 23894, + 23909, 23923, -23938, -23952, -23967, -23981, -23995, -24009, -24023, -24036, -24049, -24062, -24074, -24086, + -24097, -24108, -24118, -24128, -24137, -24145, -24152, -24158, -24164, -24168, -24172, -24175, -24176, -24177, + -24176, -24174, -24171, -24167, -24161, -24154, -24146, -24136, -24125, -24113, -24099, -24083, -24066, -24048, + -24028, -24006, -23983, -23958, -23932, -23904, -23874, -23843, -23810, -23775, -23739, -23701, -23662, -23621, + -23579, -23533, -23474, -23423, -23367, -23309, -23248, -23184, -23117, -23047, -22974, -22896, -22816, -22732, + -22643, -22551, -22455, -22355, -22251, -22143, -22030, -21913, -21791, -21665, -21534, -21399, -21259, -21114, + -20964, -20810, -20651, -20488, -20319, -20146, -19968, -19785, -19598, -19405, -19208, -19007, -18801, -18590, + -18375, -18156, -17932, -17704, -17472, -17236, -16996, -16752, -16505, -16254, -16000, -15743, -15482, -15219, + -14953, -14684, -14412, -14139, -13863, -13586, -13306, -13025, -12743, -12459, -12174, -11889, -11603, -11316, + -11029, -10742, -10455, -10168, -9882, -9597, -9313, -9029, -8748, -8467, -8189, -7912, -7638, -7367, + -7097, -6831, -6568, -6308, -6052, -5799, -5550, -5305, -5065, -4828, -4597, -4369, -4147, -3930, + -3718, -3511, -3310, -3113, -2923, -2738, -2559, -2386, -2219, -2057, -1902, -1753, -1610, -1474, + -1344, -1220, -1102, -991, -887, -788, -697, -611, -532, -459, -393, -332, -277, -228, + -184, -145, -111, -86}; + +RAM_ALIGN const Word16 LowDelayShapes_n960_N360_7_5ms[636] = { + 34, 43, 53, 63, 74, 87, 101, 116, 132, 149, 168, 188, 209, 232, + 256, 282, 309, 338, 368, 400, 434, 469, 506, 544, 584, 626, 669, 715, + 761, 810, 860, 912, 966, 1021, 1078, 1137, 1198, 1260, 1325, 1391, 1458, 1528, + 1599, 1673, 1747, 1824, 1903, 1983, 2065, 2149, 2235, 2322, 2411, 2502, 2595, 2690, + 2786, 2884, 2983, 3085, 3188, 3293, 3399, 3507, 3617, 3728, 3841, 3955, 4071, 4188, + 4307, 4428, 4550, 4673, 4798, 4924, 5051, 5180, 5310, 5442, 5574, 5708, 5843, 5979, + 6116, 6255, 6394, 6534, 6676, 6818, 6961, 7106, 7251, 7397, 7543, 7691, 7839, 7988, + 8137, 8288, 8438, 8590, 8741, 8894, 9046, 9199, 9353, 9507, 9661, 9815, 9969, 10124, + 10279, 10434, 10588, 10743, 10898, 11053, 11207, 11362, 11516, 11670, 11823, 11976, 12129, 12282, + 12434, 12585, 12736, 12886, 13036, 13185, 13333, 13481, 13628, 13774, 13919, 14064, 14207, 14349, + 14491, 14631, 14771, 14909, 15046, 15183, 15317, 15451, 15584, 15715, 15845, 15973, 16100, 16226, + 16350, 16473, 16595, 16715, 16833, 16950, 17065, 17179, 17292, 17402, 17511, 17619, 17724, 17829, + 17931, 18032, 18130, 18228, 18323, 18417, 18508, 18598, 18687, 18773, 18858, 18941, 19021, 19101, + 19178, 19253, 19327, 19398, 19468, 19536, 19602, 19666, 19729, 19789, 19847, 19904, 19959, 20012, + 20063, 20112, 20160, 20205, 20249, 20291, 20331, 20369, 20405, 20440, 20473, 20504, 20533, 20561, + 20587, 20611, 20634, 20654, 20674, 20691, 20707, 20722, 20735, 20746, 20756, 20764, 20771, 20777, + 20781, 20783, 20785, 20785, 20784, 20781, 20777, 20773, 20767, 20759, 20751, 20742, 20732, 20720, + 20708, 20695, 20681, 20666, 20650, 20633, 20616, 20598, 20579, 20560, 20540, 20519, 20498, 20477, + 20455, 20432, 20409, 20386, 20362, 20338, 20314, 20289, 20264, 20239, 20214, 20189, 20164, 20138, + 20113, 20088, 20063, 20037, 20012, 19988, 19963, 19939, 19914, 19891, 19874, 19849, 19825, 19801, + 19778, 19755, 19733, 19712, 19691, 19671, 19652, 19633, 19615, 19598, 19581, 19565, 19549, 19534, + 19520, 19506, 19493, 19480, 19468, 19457, 19446, 19436, 19426, 19417, 19408, 19400, 19393, 19386, + 19380, 19374, 19368, 19363, 19359, 19355, 19352, 19349, 19346, 19344, 19342, 19341, 19340, 19340, + 19340, 19341, 19341, 19343, 19344, 19346, 19348, 19351, 19354, 19357, 19361, 19365, 19369, 19373, + 19378, 19383, 19388, 19394, 19399, 19405, 19411, 19417, 19424, 19430, 19437, 19444, 19451, 19458, + 19466, 19473, 19481, 19488, 19496, 19504, 19512, 19519, 19527, 19535, -19543, -19551, -19559, -19567, + -19574, -19582, -19590, -19598, -19605, -19613, -19620, -19627, -19634, -19641, -19648, -19655, -19661, -19668, + -19674, -19680, -19686, -19691, -19696, -19701, -19706, -19711, -19715, -19719, -19723, -19726, -19729, -19732, + -19734, -19736, -19737, -19739, -19740, -19740, -19740, -19740, -19739, -19738, -19736, -19734, -19731, -19728, + -19725, -19721, -19716, -19711, -19706, -19700, -19693, -19686, -19679, -19671, -19662, -19653, -19643, -19632, + -19622, -19610, -19598, -19585, -19572, -19558, -19544, -19529, -19513, -19497, -19481, -19463, -19445, -19427, + -19408, -19388, -19368, -19347, -19325, -19303, -19281, -19258, -19234, -19209, -19175, -19146, -19117, -19087, + -19056, -19024, -18991, -18956, -18921, -18885, -18847, -18808, -18768, -18727, -18684, -18640, -18595, -18548, + -18500, -18451, -18400, -18348, -18294, -18239, -18182, -18124, -18064, -18003, -17940, -17875, -17809, -17741, + -17671, -17600, -17528, -17453, -17377, -17299, -17219, -17138, -17055, -16970, -16884, -16795, -16705, -16614, + -16520, -16425, -16328, -16230, -16129, -16027, -15923, -15818, -15711, -15602, -15491, -15379, -15265, -15150, + -15033, -14914, -14794, -14672, -14549, -14424, -14297, -14170, -14041, -13910, -13778, -13645, -13510, -13374, + -13237, -13099, -12959, -12819, -12677, -12534, -12390, -12245, -12099, -11952, -11805, -11656, -11507, -11357, + -11206, -11055, -10903, -10750, -10597, -10443, -10289, -10134, -9979, -9824, -9668, -9512, -9356, -9200, + -9044, -8888, -8732, -8575, -8419, -8263, -8108, -7952, -7797, -7642, -7488, -7334, -7181, -7028, + -6876, -6724, -6573, -6423, -6274, -6125, -5978, -5832, -5686, -5542, -5398, -5256, -5116, -4976, + -4838, -4701, -4565, -4431, -4299, -4168, -4038, -3911, -3784, -3660, -3537, -3416, -3297, -3180, + -3064, -2951, -2839, -2729, -2622, -2516, -2412, -2311, -2211, -2114, -2018, -1925, -1834, -1745, + -1658, -1574, -1492, -1412, -1334, -1258, -1185, -1114, -1046, -980, -916, -854, -795, -738, + -683, -631, -581, -533, -488, -445, -404, -366, -329, -295, -263, -233, -206, -180, + -156, -134, -114, -95, -79, -62}; + +const Word16 *const LowDelayShapes_n960_7_5ms[5] = { + LowDelayShapes_n960_N60_7_5ms, LowDelayShapes_n960_N120_7_5ms, LowDelayShapes_n960_N180_7_5ms, + LowDelayShapes_n960_N240_7_5ms, LowDelayShapes_n960_N360_7_5ms}; +# endif +#endif + +# ifdef ENABLE_HR_MODE +# ifdef SUBSET_NB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_100[130] = { + -961400, -2849747, -6146069, -11183287, -18168658, -27159976, -38041614, -50544991, -64266305, + -78702302, -93275005, -107359966, -120331449, -131585369, -140567185, -146788394, -149841031, -149374845, + -145077849, -136659567, -123818556, -106218681, -83483575, -55188103, -20866242, 19967468, 67769998, + 122921021, 185652202, 255975827, 333632994, 418021593, 508185345, 602779388, 700109939, 798161092, + 894722554, 987480940, 1074157272, 1152645644, 1221190247, 1278509567, 1323911980, 1357388583, 1379593462, + 1391784272, 1395720478, 1393489246, 1387290092, 1379158144, 1370909958, 1362952657, 1356680081, 1351822616, + 1348129706, 1345389974, 1343434137, 1342132875, 1341380238, 1341082389, 1341146030, 1341475565, 1341976666, + 1342558820, 1343143270, 1343665484, 1344082633, 1344377759, 1344564351, 1344687981, 1344819951, 1345048163, + 1345462207, 1346140636, 1347141158, 1348493131, 1350195802, 1352216474, 1354492706, 1356936321, -1359440659, + -1361893201, -1364185723, -1366227332, -1367952395, -1369325253, -1370343007, -1371033982, -1371456025, -1371688758, + -1371823378, -1371949513, -1372139932, -1372441219, -1372867302, -1373401073, -1373998949, -1374594994, -1375108467, + -1375446347, -1375511619, -1375206190, -1374435007, -1373103717, -1371107592, -1368321163, -1364583182, -1359697421, + -1353439826, -1345583929, -1334252006, -1318640435, -1296625734, -1266042179, -1224814360, -1171299094, -1104589425, + -1024691930, -932610693, -830326556, -720679178, -607287900, -494260157, -385949065, -286606097, -199964372, + -128792415, -74461791, -36690922, -13577456 }; +# else +# define MDCT_WINDOW_FS_8000_frame_ms_100 NULL +# endif +# ifdef SUBSET_WB +Word32 MDCT_WINDOW_FS_16000_frame_ms_100[260] = { + -887375, -1872204, -3197066, -4988439, -7310990, -10227337, -13783209, -18021567, -22958367, + -28610377, -34970773, -42018157, -49718535, -58023758, -66873408, -76198163, -85910142, -95927481, + -106148057, -116469926, -126789141, -136988509, -146961365, -156599505, -165784108, -174413613, -182384155, + -189593925, -195957243, -201380750, -205787662, -209112092, -211278626, -212225338, -211904063, -210251417, + -207219014, -202758648, -196811500, -189330359, -180258003, -169532917, -157095614, -142881796, -126812734, + -108824087, -88825077, -66738724, -42479347, -15962398, 12903137, 44189991, 77985216, 114347898, + 153341694, 195002709, 239360583, 286415769, 336147305, 388513668, 443439084, 500814289, 560507827, + 622347139, 686131895, 751624641, 818548945, 886612081, 955480469, 1024792378, 1094174334, 1163233060, + 1231563801, 1298756609, 1364398281, 1428080024, 1489417472, 1548030726, 1603570137, 1655722624, 1704220353, + 1748832761, 1789380048, 1825732185, 1857837021, 1885694068, 1909350182, 1928926255, 1944599555, 1956591988, + 1965173692, 1970654814, 1973392048, 1973753741, 1972126549, 1968905622, 1964477747, 1959200677, 1953414096, + 1947497068, 1941982397, 1935699544, 1930081097, 1925079908, 1920651209, 1916744799, 1913315837, 1910318315, + 1907712617, 1905458724, 1903525160, 1901880657, 1900501434, 1899362031, 1898444320, 1897728470, 1897199074, + 1896837448, 1896629442, 1896556474, 1896603942, 1896753023, 1896988900, 1897292512, 1897649018, 1898040860, + 1898455207, 1898875282, 1899290274, 1899686952, 1900057791, 1900392969, 1900688703, 1900940068, 1901148890, + 1901315261, 1901446916, 1901549632, 1901635772, 1901716579, 1901808596, 1901925470, 1902085313, 1902301944, + 1902593430, 1902971628, 1903450623, 1904038863, 1904746055, 1905575675, 1906532421, 1907613683, 1908818837, + 1910139810, 1911570484, 1913097876, 1914709921, 1916389064, 1918119705, 1919880868, -1921655075, -1923419485, + -1925156475, -1926844779, -1928468408, -1930009301, -1931454857, -1932791495, -1934012556, -1935109403, -1936080977, + -1936924245, -1937643651, -1938242459, -1938730331, -1939115713, -1939412840, -1939633721, -1939796733, -1939915942, + -1940009808, -1940092245, -1940180131, -1940284940, -1940419293, -1940589100, -1940802279, -1941058948, -1941361010, + -1941703474, -1942082515, -1942488131, -1942912654, -1943342567, -1943766803, -1944168168, -1944533482, -1944844704, + -1945086561, -1945239453, -1945288139, -1945213300, -1944999989, -1944629251, -1944086772, -1943353711, -1942414745, + -1941250214, -1939842441, -1938166561, -1936199807, -1933912258, -1931274378, -1928248720, -1924799179, -1920884332, + -1916465285, -1911499377, -1905951172, -1899784891, -1891449639, -1882086102, -1871092605, -1858022426, -1842504117, + -1824150091, -1802570281, -1777395508, -1748280284, -1714926445, -1677106435, -1634654127, -1587483810, -1535592652, + -1479074019, -1418108336, -1352953154, -1283959587, -1211573312, -1136287716, -1058670176, -979383239, -899114678, + -818587615, -738568308, -659827651, -583145988, -509279027, -438949979, -372825231, -311497711, -255465040, + -205107348, -160673323, -122260482, -89825442, -63156242, -41931466, -25668784, -12980788 }; +# else +# define MDCT_WINDOW_FS_16000_frame_ms_100 NULL +# endif +# ifdef SUBSET_SSWB +Word32 MDCT_WINDOW_FS_24000_frame_ms_100[390] = { + -566705, -1110129, -1685050, -2404955, -3290604, -4357398, -5620992, -7096870, -8797110, + -10732247, -12913348, -15346312, -18033576, -20979359, -24186040, -27648819, -31361639, -35319387, + -39511857, -43926672, -48550894, -53369201, -58364329, -63516998, -68804773, -74208337, -79706124, + -85271101, -90877590, -96504202, -102123140, -107704698, -113222623, -118652834, -123968611, -129140789, + -134141816, -138946789, -143532274, -147872644, -151941696, -155718471, -159183810, -162313004, -165085094, + -167485061, -169496638, -171101141, -172281631, -173021519, -173310456, -173136812, -172483214, -171335676, + -169686052, -167521471, -164827705, -161591409, -157800875, -153444385, -148507128, -142973353, -136828628, + -130059834, -122650769, -114582255, -105836248, -96398529, -86248633, -75363800, -63725732, -51315501, + -38111620, -24094261, -9239538, 6471742, 23056447, 40536457, 58931280, 78254053, 98521159, + 119745967, 141936970, 165102364, 189247343, 214372698, 240474371, 267544931, 295575426, 324551903, + 354450456, 385246198, 416908490, 449403326, 482689758, 516718794, 551441284, 586801891, 622731215, + 659163373, 696029684, 733249762, 770740975, 808417324, 846185475, 883956761, 921637043, 959124688, + 996324031, 1033136615, 1069460208, 1105195788, 1140244773, 1174510921, 1207903363, 1240329980, 1271701586, + 1301936917, 1330960546, 1358704531, 1385106661, 1410109035, 1433668094, 1455740664, 1476295686, 1495314659, + 1512790051, 1528721877, 1543118961, 1555993720, 1567377327, 1577311901, 1585840140, 1593017314, 1598905809, + 1603572858, 1607094048, 1609553036, 1611038032, 1611639187, 1611445924, 1610554709, 1609062783, 1607062660, + 1604647205, 1601904616, 1598915994, 1595761439, 1592514651, 1589411075, 1586578699, 1582990467, 1579691165, + 1576632996, 1573802167, 1571187222, 1568776964, 1566559220, 1564523108, 1562656830, 1560950303, 1559392538, + 1557974462, 1556686097, 1555520279, 1554467590, 1553522528, 1552677071, 1551926380, 1551264122, 1550685851, + 1550186120, 1549761554, 1549406743, 1549118648, 1548892484, 1548724782, 1548611579, 1548548556, 1548532064, + 1548557824, 1548622043, 1548720068, 1548848512, 1549002557, 1549178941, 1549372811, 1549581179, 1549799479, + 1550025081, 1550253392, 1550482320, 1550707996, 1550928257, 1551140242, 1551341918, 1551531258, 1551707132, + 1551867783, 1552012940, 1552142171, 1552255441, 1552353722, 1552437360, 1552508729, 1552569181, 1552621341, + 1552667742, 1552711935, 1552756861, 1552806540, 1552864321, 1552934727, 1553021212, 1553127838, 1553258419, + 1553416594, 1553605935, 1553829154, 1554089545, 1554389317, 1554730803, 1555115388, 1555544621, 1556019161, + 1556539764, 1557105744, 1557717296, 1558373006, 1559071819, 1559811599, 1560590143, 1561405090, 1562252936, + 1563130339, 1564033457, 1564958401, 1565900358, 1566855101, 1567817123, -1568783655, -1569746861, -1570703949, + -1571649364, -1572578812, -1573487389, -1574371102, -1575225988, -1576048579, -1576835227, -1577583436, -1578290863, + -1578955234, -1579575367, -1580149723, -1580678399, -1581160607, -1581597028, -1581988259, -1582335808, -1582641029, + -1582906248, -1583133678, -1583326640, -1583487877, -1583621010, -1583729737, -1583817938, -1583889747, -1583948684, + -1583999362, -1584045193, -1584090279, -1584137621, -1584190841, -1584252527, -1584325358, -1584410718, -1584511035, + -1584626668, -1584758614, -1584906848, -1585070936, -1585250612, -1585444090, -1585650227, -1585866958, -1586092212, + -1586323072, -1586557326, -1586791018, -1587022005, -1587245580, -1587459040, -1587657701, -1587838487, -1587996409, + -1588128112, -1588228637, -1588294501, -1588320923, -1588304007, -1588239369, -1588123278, -1587951328, -1587719494, + -1587424275, -1587060842, -1586626176, -1586114863, -1585523601, -1584847006, -1584080761, -1583218674, -1582256132, + -1581185350, -1580001184, -1578694604, -1577258975, -1575684935, -1573964180, -1572086641, -1570043344, -1567823810, + -1565418712, -1562817696, -1560011672, -1556991601, -1553746487, -1550232508, -1545614483, -1540661510, -1535326382, + -1529347469, -1522634820, -1515104434, -1506662411, -1497214433, -1486667044, -1474925134, -1461899585, -1447505979, + -1431661421, -1414293801, -1395342396, -1374757780, -1352499694, -1328538688, -1302862307, -1275470003, -1246373968, + -1215606643, -1183212323, -1149244754, -1113774081, -1076886070, -1038679407, -999271421, -958778521, -917331256, + -875071965, -832168635, -788780400, -745078907, -701235665, -657439320, -613872407, -570722470, -528178104, + -486428392, -445655594, -406038238, -367747699, -330944214, -295781070, -262392452, -230898968, -201404745, + -173990773, -148716671, -125619512, -104711740, -85981071, -69390841, -54880490, -42367028, -31748204, + -22909680, -15677896, -8320202 }; +# else +# define MDCT_WINDOW_FS_24000_frame_ms_100 NULL +# endif +# ifdef SUBSET_SWB +Word32 MDCT_WINDOW_FS_32000_frame_ms_100[520] = { + -410329, -796949, -1136328, -1530183, -1997206, -2544529, -3177199, -3900727, -4721409, + -5644580, -6674901, -7816606, -9073542, -10449649, -11947654, -13568981, -15314575, -17185616, + -19183576, -21308469, -23557934, -25929130, -28420717, -31030313, -33753791, -36586142, -39522623, + -42558881, -45688908, -48905915, -52203334, -55573600, -59008578, -62500911, -66043225, -69627153, + -73242249, -76878656, -80528547, -84184130, -87834359, -91467738, -95074499, -98645962, -102173556, + -105646999, -109055430, -112389025, -115637823, -118792264, -121843979, -124784385, -127604158, -130292837, + -132842231, -135246333, -137497670, -139586545, -141504332, -143245396, -144804682, -146175706, -147351477, + -148325994, -149093197, -149646348, -149980871, -150094482, -149982174, -149636889, -149052616, -148226262, + -147155224, -145834061, -144257234, -142420419, -140318794, -137947501, -135302755, -132379903, -129173499, + -125677248, -121885484, -117793976, -113398013, -108690888, -103666131, -98316590, -92636250, -86619948, + -80260566, -73550172, -66480755, -59045143, -51237113, -43048956, -34473252, -25502546, -16127957, + -6341514, 3862818, 14491541, 25552349, 37053485, 49000846, 61399638, 74255377, 87574137, + 101359692, 115615618, 130345077, 145550314, 161232640, 177393068, 194030243, 211141818, 228724496, + 246775667, 265291298, 284263733, 303683434, 323542122, 343829307, 364532416, 385638632, 407133703, + 428999825, 451218622, 473771892, 496640476, 519799290, 543222449, 566886347, 590766871, 614834881, + 639060282, 663412218, 687860455, 712370477, 736908535, 761442526, 785938885, 810359699, 834668800, + 858831376, 882812136, 906573323, 930077938, 953289749, 976173461, 998692986, 1020814305, 1042504195, + 1063729320, 1084456529, 1104654343, 1124293323, 1143346837, 1161788685, 1179595571, 1196744793, 1213214499, + 1228990130, 1244053625, 1258390343, 1271989157, 1284842646, 1296945646, 1308295983, 1318894029, 1328742964, + 1337845893, 1346207620, 1353840346, 1360760354, 1366981286, 1372519590, 1377396138, 1381633759, 1385255026, + 1388285177, 1390752262, 1392686884, 1394119237, 1395082423, 1395609697, 1395734288, 1395488163, 1394907750, + 1394029226, 1392887172, 1391513953, 1389943438, 1388208885, 1386340921, 1384367440, 1382316364, 1380214130, + 1378106162, 1376182641, 1374415552, 1372026612, 1369811233, 1367710559, 1365724178, 1363849407, 1362082203, + 1360417744, 1358852161, 1357381258, 1356001076, 1354706993, 1353494673, 1352361089, 1351302228, 1350313689, + 1349392506, 1348535330, 1347739116, 1347001032, 1346317031, 1345686404, 1345105561, 1344572298, 1344084536, + 1343640384, 1343238137, 1342875748, 1342550922, 1342263301, 1342010831, 1341791477, 1341604203, 1341447356, + 1341320237, 1341220346, 1341146654, 1341097800, 1341072665, 1341069082, 1341085615, 1341121386, 1341174740, + 1341243587, 1341326852, 1341422956, 1341530950, 1341648658, 1341774344, 1341907686, 1342046793, 1342189996, + 1342336371, 1342484315, 1342633509, 1342781772, 1342928111, 1343072442, 1343213120, 1343349339, 1343480101, + 1343605189, 1343724192, 1343836029, 1343940104, 1344037064, 1344126250, 1344207727, 1344281010, 1344347228, + 1344406398, 1344458631, 1344504740, 1344545486, 1344582197, 1344614878, 1344644716, 1344673602, 1344702406, + 1344732123, 1344764116, 1344799913, 1344841581, 1344889533, 1344945396, 1345011275, 1345087987, 1345177164, + 1345279600, 1345397199, 1345531309, 1345682002, 1345850876, 1346039023, 1346247352, 1346476070, 1346725599, + 1346997017, 1347290788, 1347606421, 1347944342, 1348304546, 1348687326, 1349091759, 1349517389, 1349964590, + 1350432001, 1350919119, 1351424549, 1351948150, 1352488782, 1353044492, 1353614173, 1354196920, 1354791164, + 1355395130, 1356006741, 1356625062, 1357248513, 1357874066, -1358501833, -1359127963, -1359752565, -1360372594, + -1360986451, -1361593178, -1362190669, -1362777107, -1363350886, -1363911059, -1364456475, -1364985125, -1365495818, + -1365988370, -1366461329, -1366914145, -1367345397, -1367755425, -1368143727, -1368509329, -1368852492, -1369173176, + -1369471783, -1369747786, -1370001627, -1370234382, -1370446455, -1370638040, -1370810046, -1370963570, -1371100229, + -1371220085, -1371324505, -1371415420, -1371493639, -1371560818, -1371617789, -1371666695, -1371709196, -1371745710, + -1371778346, -1371808661, -1371838047, -1371867517, -1371897959, -1371931304, -1371968763, -1372010342, -1372057396, + -1372110702, -1372171094, -1372238686, -1372313498, -1372396683, -1372487751, -1372586771, -1372693072, -1372807320, + -1372928910, -1373056739, -1373190393, -1373329652, -1373473500, -1373621114, -1373770813, -1373922515, -1374075203, + -1374226645, -1374376513, -1374523166, -1374665655, -1374802265, -1374931057, -1375051695, -1375162397, -1375260925, + -1375346302, -1375416903, -1375471622, -1375508310, -1375525267, -1375521592, -1375495812, -1375445706, -1375370134, + -1375267707, -1375137383, -1374976617, -1374784711, -1374559999, -1374301455, -1374007032, -1373674676, -1373304076, + -1372892947, -1372439276, -1371941405, -1371397503, -1370805562, -1370163465, -1369467701, -1368717718, -1367909588, + -1367040649, -1366108055, -1365108685, -1364039842, -1362897427, -1361677778, -1360378277, -1358995048, -1357523990, + -1355961737, -1354304757, -1352549921, -1350693234, -1348731568, -1346663222, -1344488796, -1342151873, -1339094859, + -1335868526, -1332575618, -1329015998, -1325134514, -1320899332, -1316281926, -1311249778, -1305767783, -1299801189, + -1293316467, -1286278496, -1278652937, -1270407089, -1261510752, -1251931832, -1241641304, -1230612600, -1218823121, + -1206251778, -1192882032, -1178699247, -1163691417, -1147850058, -1131172617, -1113659053, -1095312137, -1076139342, + -1056154695, -1035374650, -1013817533, -991505119, -968465043, -944729088, -920331658, -895311402, -869713787, + -843580319, -816956722, -789893244, -762442487, -734669461, -706629428, -678385082, -649998064, -621530231, + -593051422, -564628794, -536328929, -508220768, -480373259, -452855166, -425735746, -399081503, -372957401, + -347428629, -322556345, -298398778, -275013415, -252453167, -230765335, -209993816, -190178661, -171354066, + -153547820, -136781064, -121069202, -106422336, -92843298, -80326106, -68858674, -58425411, -49003701, + -40559788, -33054527, -26453090, -20722011, -15806421, -11453718, -6043487 }; +# else +# define MDCT_WINDOW_FS_32000_frame_ms_100 NULL +# endif +# ifdef SUBSET_FB +Word32 MDCT_WINDOW_FS_48000_frame_ms_100[780] = { + -260941, -512326, -694531, -879311, -1080918, -1308853, -1562751, -1845827, -2158684, + -2503004, -2880077, -3290946, -3737685, -4221002, -4742864, -5303548, -5904756, -6546614, + -7230857, -7957740, -8729060, -9544323, -10404756, -11309433, -12259734, -13255019, -14296724, + -15384139, -16518209, -17697344, -18921986, -20190385, -21503384, -22859520, -24259194, -25700342, + -27183029, -28705009, -30266328, -31864635, -33500032, -35169872, -36873876, -38609380, -40375887, + -42170731, -43993030, -45839524, -47709533, -49600244, -51511244, -53439376, -55383757, -57340675, + -59308752, -61284610, -63267293, -65253972, -67243943, -69233263, -71220507, -73201745, -75175694, + -77138930, -79090353, -81026756, -82947219, -84848184, -86728232, -88583507, -90412766, -92212306, + -93980997, -95715499, -97414829, -99075933, -100697747, -102276727, -103811934, -105299541, -106738717, + -108126346, -109462104, -110743333, -111969072, -113135967, -114242829, -115286640, -116267230, -117181898, + -118030913, -118811562, -119523250, -120163192, -120730923, -121223904, -121641755, -121981772, -122243774, + -122425704, -122528356, -122549198, -122488317, -122342868, -122112204, -121794056, -121388712, -120894363, + -120311595, -119637953, -118873094, -118014671, -117062760, -116014831, -114871079, -113629173, -112289425, + -110849719, -109309933, -107667532, -105922420, -104072007, -102115976, -100051888, -97879875, -95597465, + -93204875, -90699195, -88080200, -85345024, -82492843, -79520968, -76429175, -73215366, -69879179, + -66417490, -62829616, -59111848, -55264005, -51283182, -47168943, -42918760, -38531620, -34004372, + -29336594, -24525462, -19570192, -14467231, -9215895, -3812888, 1741410, 7449630, 13312759, + 19333517, 25513103, 31854549, 38357631, 45024786, 51855914, 58853769, 66018789, 73353520, + 80857218, 88531868, 96377212, 104395033, 112584867, 120948431, 129484622, 138194897, 147077806, + 156134120, 165362222, 174762717, 184333381, 194074737, 203984869, 214063752, 224308471, 234717970, + 245288658, 256019674, 266907692, 277950967, 289145264, 300489211, 311977987, 323609345, 335378203, + 347280982, 359312288, 371469093, 383745604, 396138434, 408640853, 421247404, 433950689, 446746484, + 459627611, 472589454, 485624370, 498725842, 511885724, 525097999, 538353697, 551646906, 564968308, + 578310445, 591664155, 605022969, 618377829, 631721846, 645044713, 658338326, 671592921, 684801497, + 697954218, 711043692, 724059806, 736994360, 749837478, 762581648, 775216823, 787735715, 800128161, + 812386829, 824502387, 836468309, 848275065, 859915578, 871380881, 882663894, 893755956, 904651429, + 915341669, 925821650, 936083534, 946122397, 955931903, 965507514, 974842174, 983932079, 992771963, + 1001359538, 1009689065, 1017758097, 1025562027, 1033099052, 1040366302, 1047363095, 1054086968, 1060539102, + 1066717272, 1072622704, 1078255082, 1083616279, 1088705978, 1093526428, 1098077639, 1102363841, 1106387711, + 1110154526, 1113666093, 1116927603, 1119941829, 1122715077, 1125251563, 1127558143, 1129638911, 1131501374, + 1133150240, 1134593560, 1135837167, 1136890075, 1137758087, 1138450616, 1138974310, 1139338430, 1139549551, + 1139617253, 1139547254, 1139350624, 1139033981, 1138607794, 1138078811, 1137457063, 1136748191, 1135963275, + 1135107610, 1134191756, 1133220410, 1132203794, 1131145038, 1130056206, 1128938553, 1127804154, 1126651875, + 1125505224, 1124387956, 1123424960, 1122502936, 1121204059, 1119950632, 1118742198, 1117576653, 1116454214, + 1115372925, 1114332841, 1113331819, 1112370092, 1111445403, 1110557933, 1109705650, 1108888492, 1108104203, + 1107353139, 1106633126, 1105944161, 1105284140, 1104653414, 1104049906, 1103473745, 1102922793, 1102397465, + 1101895930, 1101418393, 1100962642, 1100529407, 1100117107, 1099725702, 1099353203, 1099000764, 1098666499, + 1098350488, 1098051309, 1097769862, 1097504226, 1097255015, 1097020632, 1096801846, 1096597180, 1096407228, + 1096230254, 1096067339, 1095917048, 1095779800, 1095654043, 1095540974, 1095438919, 1095348396, 1095268166, + 1095199173, 1095139611, 1095090409, 1095050175, 1095019519, 1094996963, 1094983471, 1094977391, 1094979525, + 1094988385, 1095004796, 1095027271, 1095056499, 1095090869, 1095131425, 1095176627, 1095227052, 1095281232, + 1095340201, 1095402343, 1095468278, 1095536534, 1095608171, 1095681620, 1095757514, 1095834402, 1095913392, + 1095992947, 1096073625, 1096154019, 1096235421, 1096316155, 1096396797, 1096476293, 1096555751, 1096633346, + 1096710075, 1096784773, 1096858327, 1096929351, 1096998877, 1097065514, 1097130458, 1097192392, 1097252182, + 1097308660, 1097363134, 1097414177, 1097462864, 1097508260, 1097551529, 1097591240, 1097628824, 1097663320, + 1097695680, 1097724878, 1097752577, 1097777519, 1097800889, 1097821938, 1097842083, 1097860192, 1097877707, + 1097893767, 1097909925, 1097925238, 1097941056, 1097956579, 1097973457, 1097990704, 1098009705, 1098029761, + 1098052600, 1098077182, 1098104865, 1098135087, 1098169468, 1098206820, 1098248699, 1098294539, 1098345796, + 1098401373, 1098462829, 1098529452, 1098602617, 1098681182, 1098766743, 1098858507, 1098957729, 1099063375, + 1099176931, 1099297350, 1099425943, 1099561602, 1099705648, 1099857107, 1100017184, 1100184629, 1100360829, + 1100544624, 1100737006, 1100936785, 1101145313, 1101361273, 1101585583, 1101817094, 1102057069, 1102303875, + 1102558446, 1102819734, 1103088684, 1103363640, 1103645734, 1103933619, 1104228082, 1104527573, 1104833025, + 1105142974, 1105458288, 1105777328, 1106100968, 1106427742, 1106758401, 1107091175, 1107426928, 1107764262, + 1108103811, 1108443736, 1108785137, -1109126464, -1109468075, -1109808418, -1110148595, -1110486758, -1110823540, + -1111157536, -1111489609, -1111817975, -1112143382, -1112464352, -1112781755, -1113093934, -1113401755, -1113703734, + -1114000803, -1114291390, -1114576277, -1114854097, -1115125982, -1115390248, -1115647841, -1115897690, -1116140732, + -1116375302, -1116602670, -1116821661, -1117033199, -1117235935, -1117431235, -1117617882, -1117796873, -1117967024, + -1118129738, -1118283734, -1118430232, -1118568236, -1118699084, -1118821642, -1118937239, -1119044805, -1119145850, + -1119239316, -1119326479, -1119406526, -1119481081, -1119548979, -1119611618, -1119668271, -1119720525, -1119767262, + -1119809963, -1119848051, -1119883112, -1119913933, -1119942166, -1119967238, -1119990533, -1120010991, -1120030373, + -1120047967, -1120065185, -1120081021, -1120097158, -1120112780, -1120129265, -1120145650, -1120163521, -1120181998, + -1120202553, -1120224032, -1120247880, -1120273333, -1120301601, -1120331401, -1120364428, -1120399639, -1120438004, + -1120478543, -1120522718, -1120569068, -1120618782, -1120670906, -1120726540, -1120784227, -1120845302, -1120908575, + -1120974930, -1121043024, -1121114079, -1121186673, -1121261863, -1121338234, -1121416691, -1121496045, -1121577316, + -1121658638, -1121741144, -1121823756, -1121907065, -1121989354, -1122071945, -1122153400, -1122234287, -1122313032, + -1122390771, -1122466015, -1122539413, -1122609356, -1122676929, -1122740622, -1122801070, -1122856613, -1122908312, + -1122954661, -1122996249, -1123031496, -1123061471, -1123084522, -1123101354, -1123110442, -1123112631, -1123106394, + -1123092556, -1123069422, -1123037982, -1122996721, -1122946267, -1122885196, -1122814464, -1122732221, -1122639444, + -1122534864, -1122419021, -1122290207, -1122149656, -1121995788, -1121829044, -1121647967, -1121453676, -1121244410, + -1121020792, -1120781333, -1120526836, -1120255693, -1119968555, -1119663488, -1119341437, -1119000986, -1118642248, + -1118263342, -1117865480, -1117446686, -1117006965, -1116544763, -1116060878, -1115553126, -1115021782, -1114465065, + -1113883468, -1113274918, -1112639632, -1111975615, -1111283324, -1110560756, -1109808026, -1109023086, -1108206431, + -1107355953, -1106471748, -1105551963, -1104596956, -1103604680, -1102575570, -1101507722, -1100401422, -1099254985, + -1098068882, -1096841318, -1095572135, -1093824443, -1092028958, -1090297711, -1088504795, -1086622918, -1084627237, + -1082515433, -1080275819, -1077903929, -1075390736, -1072729748, -1069911131, -1066927638, -1063770248, -1060430896, + -1056901504, -1053173546, -1049238310, -1045087876, -1040714437, -1036109920, -1031267875, -1026179775, -1020838674, + -1015237521, -1009370093, -1003230227, -996813209, -990113245, -983126698, -975849235, -968277852, -960408557, + -952239544, -943768000, -934993585, -925915442, -916534205, -906849190, -896862428, -886574831, -875990255, + -865111684, -853943783, -842489873, -830755484, -818745230, -806465779, -793923840, -781127868, -768084617, + -754803973, -741294413, -727567055, -713632929, -699502178, -685184041, -670691428, -656036019, -641230326, + -626286760, -611223511, -596053211, -580789367, -565447177, -550042966, -534590207, -519104101, -503600887, + -488098220, -472611780, -457157918, -441752495, -426412611, -411154642, -395995557, -380951672, -366040108, + -351277307, -336679493, -322262126, -308041137, -294032383, -280251079, -266711613, -253427888, -240414233, + -227684137, -215250748, -203125310, -191319486, -179843288, -168707738, -157921160, -147492810, -137428529, + -127735992, -118418783, -109483185, -100930269, -92764786, -84984919, -77594007, -70587122, -63966522, + -57723857, -51860743, -46364893, -41238076, -36463273, -32043815, -27956560, -24209143, -20769591, + -17655994, -14819879, -12293428, -9917917, -7494462, -3886267 }; +# else +# define MDCT_WINDOW_FS_48000_frame_ms_100 NULL +# endif + +# ifdef PACK_MDCT_WINDOWS +RAM_ALIGN const Word16 * LowDelayShapes_n960[6]; +# else +RAM_ALIGN const Word32 *const LowDelayShapes_n960[6] = { MDCT_WINDOW_FS_8000_frame_ms_100, MDCT_WINDOW_FS_16000_frame_ms_100, + MDCT_WINDOW_FS_24000_frame_ms_100, MDCT_WINDOW_FS_32000_frame_ms_100, + MDCT_WINDOW_FS_48000_frame_ms_100, NULL }; +# endif + +#else +RAM_ALIGN const Word16 *const LowDelayShapes_n960[6] = {LowDelayShapes_n960_N80, LowDelayShapes_n960_N160, + LowDelayShapes_n960_N240, LowDelayShapes_n960_N320, + LowDelayShapes_n960_N480, NULL}; +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[6] = {70, 140, 210, 280, 420, 840}; +# else +RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[5] = {70, 140, 210, 280, 420}; +# endif + +RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_5ms[NUM_SAMP_FREQ] = {10, + 20, + 30, + 40, + 60 +# ifdef ENABLE_HR_MODE + , 120 +# endif +}; + +# ifdef ENABLE_HR_MODE +# ifdef SUBSET_NB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_25[40] = { + 9151354, 37109627, 83712740, 151998210, 242715442, 354150912, 482126354, 620379048, + 761296862, 896901837, 1019922302, 1124767307, 1208223590, 1269735636, 1311202326, 1336324669, + 1349655864, 1355605615, 1357680847, 1358157082, -1358157082, -1357680847, -1355605615, -1349655864, + -1336324669, -1311202326, -1269735636, -1208223590, -1124767307, -1019922302, -896901837, -761296862, + -620379048, -482126354, -354150912, -242715442, -151998210, -83712740, -37109627, -9151354}; +# else +# define MDCT_WINDOW_FS_8000_frame_ms_25 NULL +# endif +# ifdef SUBSET_WB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_16000_frame_ms_25[80] = { + 9151337, 23138265, 42763907, 68767772, 101782534, 142300433, 190643613, 246939893, 311105303, + 382834448, 461599452, 546657840, 637069348, 731721202, 829361019, 928636120, 1028137675, 1126447891, + 1222188210, 1314066414, 1400920509, 1481757333, 1555784035, 1622430811, 1681363664, 1732486397, 1775931558, + 1812040689, 1841334847, 1864477074, 1882229157, 1895405578, 1904827946, 1911283293, 1915489337, 1918069115, + 1919536352, 1920291661, 1920628396, 1920745966, -1920745966, -1920628396, -1920291661, -1919536352, -1918069115, + -1915489337, -1911283293, -1904827946, -1895405578, -1882229157, -1864477074, -1841334847, -1812040689, -1775931558, + -1732486397, -1681363664, -1622430811, -1555784035, -1481757333, -1400920509, -1314066414, -1222188210, -1126447891, + -1028137675, -928636120, -829361019, -731721202, -637069348, -546657840, -461599452, -382834448, -311105303, + -246939893, -190643613, -142300433, -101782534, -68767772, -42763907, -23138265, -9151337 }; +# else +# define MDCT_WINDOW_FS_16000_frame_ms_25 NULL +# endif +# ifdef SUBSET_SSWB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_24000_frame_ms_25[120] = { + 6100899, 12864132, 21489409, 32196712, 45171875, 60580072, 78565098, 99246695, 122717635, + 149041013, 178247915, 210335558, 245265970, 282965259, 323323502, 366195270, 411400805, 458727828, + 507933969, 558749783, 610882290, 664019005, 717832373, 771984525, 826132286, 879932323, 933046345, + 985146249, 1035919114, 1085071930, 1132335985, 1177470792, 1220267489, 1260551623, 1298185265, 1333068386, + 1365139469, 1394375330, 1420790145, 1444433697, 1465388876, 1483768499, 1499711524, 1513378754, 1524948163, + 1534609980, 1542561681, 1549003060, 1554131535, 1558137849, 1561202310, 1563491688, 1565156852, 1566331192, + 1567129839, 1567649635, 1567969785, 1568153080, 1568247554, 1568288448, -1568288448, -1568247554, -1568153080, + -1567969785, -1567649635, -1567129839, -1566331192, -1565156852, -1563491688, -1561202310, -1558137849, -1554131535, + -1549003060, -1542561681, -1534609980, -1524948163, -1513378754, -1499711524, -1483768499, -1465388876, -1444433697, + -1420790145, -1394375330, -1365139469, -1333068386, -1298185265, -1260551623, -1220267489, -1177470792, -1132335985, + -1085071930, -1035919114, -985146249, -933046345, -879932323, -826132286, -771984525, -717832373, -664019005, + -610882290, -558749783, -507933969, -458727828, -411400805, -366195270, -323323502, -282965259, -245265970, + -210335558, -178247915, -149041013, -122717635, -99246695, -78565098, -60580072, -45171875, -32196712, + -21489409, -12864132, -6100899 }; +# else +# define MDCT_WINDOW_FS_24000_frame_ms_25 NULL +# endif +# ifdef SUBSET_SWB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_32000_frame_ms_25[160] = { + 4575679, 8767860, 13776210, 19722611, 26689435, 34747238, 43959497, 54383445, 66069923, + 79062931, 93399091, 109107106, 126207257, 144710958, 164620379, 185928150, 208617151, 232660396, + 258021008, 284652300, 312497943, 341492250, 371560541, 402619617, 434578316, 467338167, 500794115, + 534835326, 569346062, 604206611, 639294264, 674484335, 709651210, 744669409, 779414654, 813764938, + 847601565, 880810169, 913281687, 944913281, 975609194, 1005281536, 1033850982, 1061247376, 1087410241, + 1112289173, 1135844126, 1158045581, 1178874586, 1198322683, 1216391705, 1233093455, 1248449271, 1262489470, + 1275252698, 1286785178, 1297139874, 1306375586, 1314555990, 1321748631, 1328023899, 1333453999, 1338111934, + 1342070524, 1345401476, 1348174521, 1350456644, 1352311405, 1353798377, 1354972700, 1355884752, 1356579954, + 1357098688, 1357476324, 1357743362, 1357925654, 1358044707, 1358118045, 1358159612, 1358180205, -1358180205, + -1358159612, -1358118045, -1358044707, -1357925654, -1357743362, -1357476324, -1357098688, -1356579954, -1355884752, + -1354972700, -1353798377, -1352311405, -1350456644, -1348174521, -1345401476, -1342070524, -1338111934, -1333453999, + -1328023899, -1321748631, -1314555990, -1306375586, -1297139874, -1286785178, -1275252698, -1262489470, -1248449271, + -1233093455, -1216391705, -1198322683, -1178874586, -1158045581, -1135844126, -1112289173, -1087410241, -1061247376, + -1033850982, -1005281536, -975609194, -944913281, -913281687, -880810169, -847601565, -813764938, -779414654, + -744669409, -709651210, -674484335, -639294264, -604206611, -569346062, -534835326, -500794115, -467338167, + -434578316, -402619617, -371560541, -341492250, -312497943, -284652300, -258021008, -232660396, -208617151, + -185928150, -164620379, -144710958, -126207257, -109107106, -93399091, -79062931, -66069923, -54383445, + -43959497, -34747238, -26689435, -19722611, -13776210, -8767860, -4575679 }; +# else +# define MDCT_WINDOW_FS_32000_frame_ms_25 NULL +# endif +# ifdef SUBSET_FB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_48000_frame_ms_25[240] = { + 3050456, 5295536, 7753004, 10501942, 13578229, 17006497, 20806969, 24997575, 29594719, + 34613583, 40068237, 45971662, 52335732, 59171174, 66487516, 74293042, 82594732, 91398213, + 100707709, 110526001, 120854381, 131692624, 143038956, 154890033, 167240926, 180085109, 193414462, + 207219271, 221488240, 236208515, 251365705, 266943917, 282925795, 299292569, 316024108, 333098980, + 350494519, 368186897, 386151203, 404361529, 422791056, 441412148, 460196455, 479115006, 498138325, + 517236531, 536379451, 555536738, 574677975, 593772799, 612791011, 631702693, 650478321, 669088878, + 687505964, 705701904, 723649854, 741323899, 758699157, 775751861, 792459455, 808800673, 824755609, + 840305794, 855434253, 870125559, 884365881, 898143024, 911446458, 924267340, 936598527, 948434586, + 959771781, 970608068, 980943072, 990778052, 1000115868, 1008960932, 1017319150, 1025197865, 1032605778, + 1039552878, 1046050356, 1052110513, 1057746665, 1062973048, 1067804709, 1072257401, 1076347473, 1080091765, + 1083507488, 1086612119, 1089423293, 1091958692, 1094235940, 1096272508, 1098085614, 1099692137, 1101108528, + 1102350741, 1103434158, 1104373531, 1105182928, 1105875693, 1106464406, 1106960861, 1107376047, 1107720140, + 1108002502, 1108231688, 1108415463, 1108560820, 1108674010, 1108760573, 1108825377, 1108872657, 1108906059, + 1108928685, 1108943144, 1108951592, -1108951592, -1108943144, -1108928685, -1108906059, -1108872657, -1108825377, + -1108760573, -1108674010, -1108560820, -1108415463, -1108231688, -1108002502, -1107720140, -1107376047, -1106960861, + -1106464406, -1105875693, -1105182928, -1104373531, -1103434158, -1102350741, -1101108528, -1099692137, -1098085614, + -1096272508, -1094235940, -1091958692, -1089423293, -1086612119, -1083507488, -1080091765, -1076347473, -1072257401, + -1067804709, -1062973048, -1057746665, -1052110513, -1046050356, -1039552878, -1032605778, -1025197865, -1017319150, + -1008960932, -1000115868, -990778052, -980943072, -970608068, -959771781, -948434586, -936598527, -924267340, + -911446458, -898143024, -884365881, -870125559, -855434253, -840305794, -824755609, -808800673, -792459455, + -775751861, -758699157, -741323899, -723649854, -705701904, -687505964, -669088878, -650478321, -631702693, + -612791011, -593772799, -574677975, -555536738, -536379451, -517236531, -498138325, -479115006, -460196455, + -441412148, -422791056, -404361529, -386151203, -368186897, -350494519, -333098980, -316024108, -299292569, + -282925795, -266943917, -251365705, -236208515, -221488240, -207219271, -193414462, -180085109, -167240926, + -154890033, -143038956, -131692624, -120854381, -110526001, -100707709, -91398213, -82594732, -74293042, + -66487516, -59171174, -52335732, -45971662, -40068237, -34613583, -29594719, -24997575, -20806969, + -17006497, -13578229, -10501942, -7753004, -5295536, -3050456 }; +# else +# define MDCT_WINDOW_FS_48000_frame_ms_25 NULL +# endif +#endif + +# ifdef ENABLE_HR_MODE +# ifdef SUBSET_NB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_50[70] = { + 1912909, 7335521, 18325724, 36910622, 64974178, 104198418, 155981280, 221305462, 300589079, + 393635120, 499623692, 617106989, 744004208, 877694270, 1015162828, 1153137249, 1288239038, 1417150998, + 1536791945, 1644447880, 1737962977, 1815833349, 1877263804, 1922306058, 1951829636, 1967471711, 1971505676, + 1966594148, 1955602246, 1941502114, 1927310881, 1914588900, 1905592841, 1900063224, 1897652925, 1897963170, + 1900562354, 1904988644, 1910750498, 1917333371, -1924208315, -1930837552, -1936677590, -1941187989, -1943846368, + -1944164165, -1941697923, -1936063536, -1926966575, -1914246866, -1895468226, -1869147188, -1832534703, -1783214725, + -1719263259, -1639330989, -1542778136, -1429960741, -1302431717, -1162827131, -1014564422, -861762630, -709123640, + -561741289, -424627691, -302165309, -197940066, -114914393, -55161222, -18600494 }; +# else +# define MDCT_WINDOW_FS_8000_frame_ms_50 NULL +# endif +# ifdef SUBSET_WB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_16000_frame_ms_50[140] = { + 834388, 2023133, 3917156, 6701705, 10565521, 15685856, 22235650, 30384241, 40286022, + 52095516, 65948322, 81967398, 100265346, 120927126, 144016301, 169574495, 197607091, 228098907, + 261006859, 296253144, 333742048, 373344049, 414902600, 458235462, 503129294, 549353006, 596652543, + 644762423, 693401311, 742277119, 791098023, 839557429, 887360048, 934211532, 979820668, 1023922652, + 1066251747, 1106569674, 1144656239, 1180316465, 1213396318, 1243758349, 1271300584, 1295946391, 1317664404, + 1336461856, 1352374790, 1365487180, 1375907723, 1383780765, 1389286272, 1392625157, 1394020824, 1393712039, + 1391944281, 1388970703, 1385052050, 1380450904, 1375432870, 1370255673, 1365493257, 1360311818, 1355815371, + 1351987330, 1348809662, 1346259072, 1344307938, 1342925268, 1342077528, 1341729312, 1341843769, 1342382749, + 1343306801, 1344575110, 1346145481, 1347974400, 1350017219, 1352228384, 1354561632, 1356970112, -1359406807, + -1361823903, -1364173707, -1366408059, -1368478813, -1370338075, -1371938535, -1373233878, -1374179166, -1374731135, + -1374848407, -1374491689, -1373624022, -1372211199, -1370222452, -1367631371, -1364416934, -1360564607, -1356067324, + -1350921653, -1344029735, -1336226439, -1326949476, -1315967441, -1303050661, -1287981322, -1270565808, -1250633190, + -1228037147, -1202659404, -1174406746, -1143219019, -1109079369, -1072015866, -1032110341, -989504343, -944386484, + -896992664, -847599093, -796504062, -744037160, -690570612, -636495945, -582226621, -528203723, -474881089, + -422717084, -372160937, -323635430, -277529378, -234193138, -193941056, -157058932, -123809989, -94431397, + -69117849, -47990622, -31057417, -18172622, -9019056 }; +# else +# define MDCT_WINDOW_FS_16000_frame_ms_50 NULL +# endif +# ifdef SUBSET_SSWB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_24000_frame_ms_50[210] = { + 564151, 1104419, 1865494, 2894039, 4235165, 5932159, 8033172, 10580362, 13613959, + 17177173, 21310358, 26053470, 31441110, 37512859, 44302113, 51841191, 60158985, 69285016, + 79244161, 90055834, 101740044, 114307277, 127770768, 142131061, 157390145, 173545185, 190584386, + 208498576, 227265343, 246867205, 267275117, 288457873, 310382420, 333006130, 356286886, 380173162, + 404613227, 429551030, 454926373, 480676280, 506737023, 533041379, 559520739, 586104532, 612719819, + 639298867, 665764101, 692044954, 718069120, 743765156, 769064062, 793893410, 818192510, 841895640, + 864939671, 887267243, 908824605, 929558785, 949422426, 968375342, 986383128, 1003413393, 1019433821, + 1034427350, 1048371873, 1061257817, 1073079562, 1083838763, 1093544388, 1102204732, 1109843920, 1116483171, + 1122153769, 1126889366, 1130731703, 1133726105, 1135920322, 1137368676, 1138125139, 1138249333, 1137797435, + 1136832092, 1135413661, 1133604477, 1131468200, 1129067483, 1126468580, 1123733695, 1120926768, 1118121453, + 1115661504, 1112733456, 1110039679, 1107592275, 1105388417, 1103424195, 1101694785, 1100194540, 1098917076, + 1097855409, 1097002014, 1096348961, 1095887953, 1095610427, 1095507566, 1095570351, 1095789547, 1096155725, + 1096659227, 1097290187, 1098038501, 1098893850, 1099845706, 1100883348, 1101995893, 1103172315, 1104401472, + 1105672121, 1106972938, 1108292669, -1109619302, -1110942189, -1112249205, -1113528884, -1114769580, -1115959638, + -1117087420, -1118141328, -1119109856, -1119981619, -1120745408, -1121390225, -1121905319, -1122280224, -1122504764, + -1122569097, -1122463704, -1122179448, -1121707579, -1121039818, -1120168401, -1119086203, -1117786804, -1116264645, + -1114515111, -1112534671, -1110320979, -1107872954, -1105190944, -1102290376, -1098369607, -1094349090, -1089850335, + -1084803470, -1079152632, -1072839707, -1065811535, -1058014404, -1049399648, -1039922082, -1029539502, -1018216878, + -1005918442, -992617105, -978287110, -962909114, -946468188, -928955851, -910372331, -890723372, -870025772, + -848301812, -825588219, -801924529, -777362543, -751959302, -725776798, -698887464, -671358557, -643273732, + -614708529, -585759042, -556515015, -527075925, -497538887, -468010517, -438598442, -409412725, -380564000, + -352163661, -324321484, -297140687, -270721761, -245158912, -220540161, -196946958, -174455223, -153136078, + -133056674, -114280750, -96868231, -80874056, -66345855, -53320577, -41820223, -31847346, -23380692, + -16371397, -10739000, -6256916 }; +# else +# define MDCT_WINDOW_FS_24000_frame_ms_50 NULL +# endif +# ifdef SUBSET_SWB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_32000_frame_ms_50[280] = { + 882763, 1521118, 2358563, 3425984, 4762639, 6395771, 8362131, 10689006, 13418692, + 16576000, 20193865, 24299300, 28928500, 34104984, 39865074, 46229302, 53228467, 60887056, + 69236180, 78292965, 88087142, 98634050, 109959733, 122081209, 135019424, 148782425, 163392710, + 178855011, 195181305, 212377526, 230451659, 249395809, 269219382, 289915225, 311477904, 333897457, + 357170677, 381274098, 406199848, 431929301, 458441926, 485710203, 513718369, 542430861, 571822196, + 601857045, 632504350, 663719412, 695470641, 727711424, 760403450, 793496784, 826949741, 860710772, + 894737379, 928972875, 963373530, 997882662, 1032450522, 1067021806, 1101552211, 1135977909, 1170251366, + 1204317771, 1238127288, 1271622131, 1304759595, 1337479850, 1369736833, 1401482421, 1432674669, 1463259078, + 1493196881, 1522440628, 1550955893, 1578698536, 1605635690, 1631726882, 1656947594, 1681264014, 1704659250, + 1727103999, 1748576205, 1769054798, 1788533700, 1806990078, 1824418644, 1840812466, 1856170505, 1870488908, + 1883781944, 1896047096, 1907297858, 1917548829, 1926819646, 1935123035, 1942490021, 1948939055, 1954502859, + 1959211322, 1963101243, 1966202102, 1968559589, 1970206964, 1971189283, 1971546464, 1971324022, 1970559672, + 1969305529, 1967600289, 1965492731, 1963026251, 1960251018, 1957207403, 1953949375, 1950518787, 1946965804, + 1943332468, 1939669743, 1936018211, 1933074896, 1929170790, 1925511708, 1922091318, 1918913458, 1915970631, + 1913265545, 1910789617, 1908544525, 1906520767, 1904719178, 1903129502, 1901751868, 1900575443, 1899599816, + 1898813735, 1898216400, 1897796234, 1897552155, 1897472330, 1897555435, 1897789418, 1898172732, 1898693091, + 1899348726, 1900127098, 1901026195, 1902033230, 1903145941, 1904351313, 1905646871, 1907019391, 1908466229, + 1909973977, 1911539869, 1913150363, 1914802598, 1916482920, 1918188394, 1919905292, -1921630629, -1923350609, + -1925062194, -1926751519, -1928415501, -1930040212, -1931622556, -1933148598, -1934615259, -1936008644, -1937325739, + -1938552759, -1939686835, -1940714349, -1941632651, -1942428351, -1943099088, -1943631764, -1944024336, -1944264050, + -1944349204, -1944267410, -1944017355, -1943587051, -1942975631, -1942171601, -1941174620, -1939973809, -1938569504, + -1936951577, -1935121231, -1933069293, -1930798023, -1928299406, -1925576914, -1922623868, -1919445128, -1916035514, + -1912401346, -1908538993, -1903226832, -1898165387, -1892651677, -1886636702, -1880083188, -1872945708, -1865186866, + -1856760038, -1847633035, -1837760249, -1827110036, -1815644193, -1803335041, -1790145270, -1776055593, -1761033530, + -1745059396, -1728108424, -1710167501, -1691212572, -1671237793, -1650226116, -1628174600, -1605075941, -1580936677, + -1555754529, -1529546654, -1502320930, -1474101256, -1444909741, -1414780308, -1383738492, -1351831573, -1319095487, + -1285577912, -1251324682, -1216394344, -1180827594, -1144691880, -1108040592, -1070930654, -1033434550, -995621142, + -957552560, -919309430, -880954958, -842572374, -804234470, -766025822, -728021485, -690307576, -652960034, + -616065598, -579699451, -543943367, -508866771, -474546527, -441046910, -408438534, -376778154, -346129113, + -316541929, -288074358, -260771792, -234687576, -209863469, -186348825, -164181088, -143404068, -124048067, + -106147028, -89718620, -74780184, -61329654, -49360094, -38842904, -29739589, -21991349, -15513048, + -10180154 }; +# else +# define MDCT_WINDOW_FS_32000_frame_ms_50 NULL +# endif +# ifdef SUBSET_FB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_48000_frame_ms_50[420] = { + 641452, 963468, 1344309, 1798864, 2336113, 2963727, 3690212, 4523143, 5470567, + 6539876, 7738462, 9075874, 10560639, 12200013, 14000287, 15968479, 18112467, 20440430, + 22959153, 25675517, 28597257, 31731569, 35084700, 38662325, 42471171, 46518292, 50811124, + 55354756, 60154720, 65216952, 70547205, 76150562, 82031461, 88195322, 94647798, 101393537, + 108435354, 115776449, 123420676, 131372779, 139634617, 148207504, 157093536, 166295700, 175815910, + 185653595, 195807761, 206278987, 217068929, 228177014, 239600679, 251337195, 263385931, 275745715, + 288413583, 301384760, 314655039, 328222340, 342083665, 356233498, 370664518, 385372123, 400351243, + 415596618, 431100575, 446855251, 462853492, 479088256, 495551477, 512233512, 529124734, 546216403, + 563499351, 580963667, 598598648, 616393743, 634338212, 652420945, 670630244, 688955012, 707384418, + 725906000, 744507517, 763176760, 781901922, 800670867, 819470287, 838286395, 857107788, 875922821, + 894718707, 913481313, 932196408, 950852353, 969437415, 987938553, 1006342043, 1024635125, 1042806406, + 1060844237, 1078734559, 1096464849, 1114023247, 1131399453, 1148583332, 1165562052, 1182324038, 1198858240, + 1215154081, 1231201466, 1246990634, 1262512157, 1277756598, 1292714571, 1307377034, 1321735176, 1335781943, + 1349510011, 1362912058, 1375982854, 1388718627, 1401109382, 1413152613, 1424839949, 1436168435, 1447135603, + 1457737882, 1467971469, 1477831821, 1487317959, 1496429995, 1505166563, 1513525606, 1521507797, 1529115290, + 1536350460, 1543213224, 1549704472, 1555827692, 1561587898, 1566989343, 1572034920, 1576728782, 1581076815, + 1585086027, 1588761389, 1592109107, 1595136511, 1597852394, 1600264963, 1602381209, 1604209606, 1605759882, + 1607041997, 1608065019, 1608838122, 1609371538, 1609676596, 1609763199, 1609640908, 1609320042, 1608811796, + 1608127979, 1607278811, 1606274326, 1605125864, 1603845218, 1602443629, 1600931810, 1599320348, 1597621250, + 1595846595, 1594007402, 1592114826, 1590179414, 1588213076, 1586227163, 1584231653, 1582234964, 1580207977, + 1578973545, 1576735799, 1574650444, 1572657612, 1570752789, 1568935343, 1567204832, 1565560739, 1564002460, + 1562529304, 1561140497, 1559835185, 1558612434, 1557471243, 1556410547, 1555429220, 1554526076, 1553699872, + 1552949321, 1552273100, 1551669839, 1551138129, 1550676530, 1550283581, 1549957792, 1549697644, 1549501594, + 1549368091, 1549295559, 1549282400, 1549326998, 1549427723, 1549582929, 1549790946, 1550050083, 1550358639, + 1550714889, 1551117086, 1551563464, 1552052237, 1552581604, 1553149738, 1553754795, 1554394911, 1555068212, + 1555772800, 1556506765, 1557268182, 1558055112, 1558865609, 1559697712, 1560549450, 1561418844, 1562303905, + 1563202640, 1564113045, 1565033113, 1565960825, 1566894119, 1567830370, -1568770400, -1569707772, -1570643299, + -1571574337, -1572498793, -1573414613, -1574319739, -1575212113, -1576089676, -1576950365, -1577792121, -1578612885, + -1579410602, -1580183223, -1580928704, -1581645010, -1582330113, -1582982003, -1583598681, -1584178165, -1584718489, + -1585217707, -1585673898, -1586085163, -1586449622, -1586765423, -1587030743, -1587243787, -1587402781, -1587505982, + -1587551679, -1587538195, -1587463877, -1587327103, -1587126293, -1586859906, -1586526431, -1586124397, -1585652387, + -1585109032, -1584493010, -1583803053, -1583037961, -1582196603, -1581277917, -1580280911, -1579204680, -1578048412, + -1576811384, -1575492968, -1574092640, -1572609980, -1571044684, -1569396562, -1567665543, -1565851670, -1563955090, + -1561975794, -1559909960, -1557699231, -1554579493, -1551951859, -1549122074, -1546121016, -1542941389, -1539572601, + -1536005010, -1532229275, -1528234689, -1524011122, -1519548313, -1514837211, -1509868869, -1504633300, -1499121016, + -1493323395, -1487232726, -1480841309, -1474140699, -1467123022, -1459782240, -1452112311, -1444106817, -1435759114, + -1427063276, -1418015155, -1408610288, -1398843935, -1388711462, -1378209682, -1367336091, -1356088102, -1344462791, + -1332458664, -1320075617, -1307313612, -1294173092, -1280654545, -1266760135, -1252493498, -1237857298, -1222855659, + -1207493934, -1191778366, -1175716859, -1159315327, -1142581197, -1125524357, -1108155092, -1090483582, -1072519662, + -1054273467, -1035757912, -1016986859, -997971439, -978723129, -959255645, -939584189, -919723670, -899686034, + -879484158, -859140109, -838667380, -818082710, -797402257, -776643501, -755824703, -734962210, -714073915, + -693179322, -672297393, -651446511, -630646657, -609917124, -589277150, -568746490, -548345449, -528092326, + -508008241, -488111645, -468421183, -448956496, -429734434, -410773661, -392090517, -373702005, -355624406, + -337873208, -320463322, -303409145, -286724555, -270422942, -254517317, -239020241, -223943842, -209300003, + -195100311, -181356034, -168078124, -155277193, -142963461, -131146681, -119836028, -109039985, -98766166, + -89021184, -79810417, -71137840, -63005796, -55414797, -48363340, -41847826, -35862016, -30397367, + -25442735, -20983937, -17003804, -13482292, -10414308, -8112352 }; +# else +# define MDCT_WINDOW_FS_48000_frame_ms_50 NULL +# endif +#endif + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 *const LowDelayShapes_n960_5ms[6] = { + MDCT_WINDOW_FS_8000_frame_ms_50, MDCT_WINDOW_FS_16000_frame_ms_50, MDCT_WINDOW_FS_24000_frame_ms_50, MDCT_WINDOW_FS_32000_frame_ms_50, MDCT_WINDOW_FS_48000_frame_ms_50, NULL }; +#else +RAM_ALIGN const Word16 *const LowDelayShapes_n960_5ms[6] = {LowDelayShapes_n960_N40_5ms, LowDelayShapes_n960_N80_5ms, + LowDelayShapes_n960_N120_5ms, LowDelayShapes_n960_N160_5ms, + LowDelayShapes_n960_N240_5ms, NULL}; +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[6] = {40, 80, 120, 160, 240, 480}; +# else +RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[5] = {40, 80, 120, 160, 240}; +# endif + +RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_2_5ms[NUM_SAMP_FREQ] = {0, + 0, + 0, + 0, + 0 }; -const LC3_INT16 ari_tns_order_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, - {0, 14, 56, 156, 313, 494, 672, 839, 1024}}; +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 *const LowDelayShapes_n960_2_5ms[6] = { + MDCT_WINDOW_FS_8000_frame_ms_25, MDCT_WINDOW_FS_16000_frame_ms_25, MDCT_WINDOW_FS_24000_frame_ms_25, MDCT_WINDOW_FS_32000_frame_ms_25, MDCT_WINDOW_FS_48000_frame_ms_25, NULL }; +#else +RAM_ALIGN const Word16 *const LowDelayShapes_n960_2_5ms[6] = { + LowDelayShapes_n960_N40_2_5ms, LowDelayShapes_n960_N80_2_5ms, LowDelayShapes_n960_N120_2_5ms, + LowDelayShapes_n960_N160_2_5ms, LowDelayShapes_n960_N240_2_5ms, NULL}; +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_HR[6] = {12, 74, 137, 200, 266, 333}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_HR[6] = {74, 137, 200, 266, 333, 400}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_HR[6] = {12, 74, 137, 200, 266, 333}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_HR[6] = {74, 137, 200, 266, 333, 400}; +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_HR[2] = {tns_subdiv_startfreq_48k_HR, tns_subdiv_startfreq_96k_HR}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_HR[2] = {tns_subdiv_stopfreq_48k_HR, tns_subdiv_stopfreq_96k_HR}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_5ms_HR[4] = {6, 53, 100, 150}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_5ms_HR[4] = {53, 100, 150, 200}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_5ms_HR[4] = {6, 53, 100, 150}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_5ms_HR[4] = {53, 100, 150, 200}; + +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms_HR[2] = {tns_subdiv_startfreq_48k_5ms_HR, + tns_subdiv_startfreq_96k_5ms_HR}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms_HR[2] = {tns_subdiv_stopfreq_48k_5ms_HR, + tns_subdiv_stopfreq_96k_5ms_HR}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_2_5ms_HR[2] = {3, 51}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_2_5ms_HR[2] = {51, 100}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_2_5ms_HR[2] = {3, 51}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_2_5ms_HR[2] = {51, 100}; + +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms_HR[2] = {tns_subdiv_startfreq_48k_2_5ms_HR, + tns_subdiv_startfreq_96k_2_5ms_HR}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms_HR[2] = {tns_subdiv_stopfreq_48k_2_5ms_HR, + tns_subdiv_stopfreq_96k_2_5ms_HR}; +# endif + + +RAM_ALIGN const Word16 tns_subdiv_startfreq_8k[6] = {12, 34, 57, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k[6] = {34, 57, 80, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_16k[6] = {12, 61, 110, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k[6] = {61, 110, 160, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_24k[6] = {12, 88, 164, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k[6] = {88, 164, 240, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_32k[6] = {12, 61, 110, 160, 213, 266}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k[6] = {61, 110, 160, 213, 266, 320}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k[6] = {12, 74, 137, 200, 266, 333}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k[6] = {74, 137, 200, 266, 333, 400}; +RAM_ALIGN const Word16 *const tns_subdiv_startfreq[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_startfreq_8k, tns_subdiv_startfreq_16k, tns_subdiv_startfreq_24k, tns_subdiv_startfreq_32k, + tns_subdiv_startfreq_48k}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_stopfreq_8k, tns_subdiv_stopfreq_16k, tns_subdiv_stopfreq_24k, tns_subdiv_stopfreq_32k, + tns_subdiv_stopfreq_48k}; + + +RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_5ms[4] = {6, 23, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_5ms[4] = {23, 40, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_5ms[4] = {6, 43, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_5ms[4] = {43, 80, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_5ms[4] = {6, 63, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_5ms[4] = {63, 120, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_5ms[4] = {6, 43, 80, 120}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_5ms[4] = {43, 80, 120, 160}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_5ms[4] = {6, 53, 100, 150}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_5ms[4] = {53, 100, 150, 200}; +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_startfreq_8k_5ms, tns_subdiv_startfreq_16k_5ms, tns_subdiv_startfreq_24k_5ms, + tns_subdiv_startfreq_32k_5ms, tns_subdiv_startfreq_48k_5ms}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_stopfreq_8k_5ms, tns_subdiv_stopfreq_16k_5ms, tns_subdiv_stopfreq_24k_5ms, tns_subdiv_stopfreq_32k_5ms, + tns_subdiv_stopfreq_48k_5ms}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_2_5ms[2] = {3, 11}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_2_5ms[2] = {11, 20}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_2_5ms[2] = {3, 21}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_2_5ms[2] = {21, 40}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_2_5ms[2] = {3, 31}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_2_5ms[2] = {31, 60}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_2_5ms[2] = {3, 41}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_2_5ms[2] = {41, 80}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_2_5ms[2] = {3, 51}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_2_5ms[2] = {51, 100}; + +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_startfreq_8k_2_5ms, tns_subdiv_startfreq_16k_2_5ms, tns_subdiv_startfreq_24k_2_5ms, + tns_subdiv_startfreq_32k_2_5ms, tns_subdiv_startfreq_48k_2_5ms}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_stopfreq_8k_2_5ms, tns_subdiv_stopfreq_16k_2_5ms, tns_subdiv_stopfreq_24k_2_5ms, + tns_subdiv_stopfreq_32k_2_5ms, tns_subdiv_stopfreq_48k_2_5ms}; + +#ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_7_5ms[6] = {9, 26, 43, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_7_5ms[6] = {26, 43, 60, 0, 0, 0}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_7_5ms[6] = {9, 46, 83, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_7_5ms[6] = {46, 83, 120, 0, 0, 0}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_7_5ms[6] = {9, 66, 123, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_7_5ms[6] = {66, 123, 180, 0, 0, 0}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_7_5ms[6] = {9, 46, 82, 120, 159, 200}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_7_5ms[6] = {46, 82, 120, 159, 200, 240}; -const LC3_INT16 ari_tns_freq_cf[8][18] = { - {0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 17, 60, 154, 293, 466, 626, 780, 911, 989, 1016, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 13, 56, 162, 361, 578, 788, 929, 1003, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 6, 17, 66, 270, 555, 852, 972, 1011, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 5, 12, 54, 295, 636, 950, 1008, 1017, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 5, 6, 19, 224, 590, 967, 1014, 1019, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 5, 6, 19, 300, 630, 1001, 1018, 1019, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 5, 6, 11, 308, 309, 991, 1017, 1019, 1020, 1021, 1022, 1023, 1024}}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_7_5ms[6] = {9, 56, 103, 150, 200, 250}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_7_5ms[6] = {56, 103, 150, 200, 250, 300}; -const LC3_INT ari_spec_lookup_fl[4096] = { +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_7_5ms[6] = {9, 56, 103, 150, 200, 250}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_7_5ms[6] = {56, 103, 150, 200, 250, 300}; +# endif + +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_7_5ms[] = { + tns_subdiv_startfreq_8k_7_5ms, tns_subdiv_startfreq_16k_7_5ms, tns_subdiv_startfreq_24k_7_5ms, + tns_subdiv_startfreq_32k_7_5ms, tns_subdiv_startfreq_48k_7_5ms +# ifdef ENABLE_HR_MODE + , tns_subdiv_startfreq_96k_7_5ms +# endif +}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_7_5ms[] = { + tns_subdiv_stopfreq_8k_7_5ms, tns_subdiv_stopfreq_16k_7_5ms, tns_subdiv_stopfreq_24k_7_5ms, + tns_subdiv_stopfreq_32k_7_5ms, tns_subdiv_stopfreq_48k_7_5ms +# ifdef ENABLE_HR_MODE + , tns_subdiv_stopfreq_96k_7_5ms +# endif +}; +# endif + +RAM_ALIGN const Word16 Tab_esc_nb[4] = {0 << (NBITS_CONTEXT + NBITS_RATEQ), 1 << (NBITS_CONTEXT + NBITS_RATEQ), + 2 << (NBITS_CONTEXT + NBITS_RATEQ), 3 << (NBITS_CONTEXT + NBITS_RATEQ)}; +RAM_ALIGN const Word8 ari_spec_lookup[4096] = { 0x01, 0x27, 0x07, 0x19, 0x16, 0x16, 0x1C, 0x16, 0x16, 0x16, 0x16, 0x1C, 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x28, 0x2B, 0x2E, 0x31, 0x34, 0x0E, 0x11, 0x24, 0x24, 0x24, 0x26, 0x00, 0x39, 0x26, 0x16, 0x00, 0x08, 0x09, 0x0B, 0x2F, 0x0E, 0x0E, 0x11, 0x24, 0x24, 0x24, 0x26, 0x3B, 0x3B, 0x26, 0x16, 0x16, 0x1A, 0x2E, 0x1D, 0x1E, 0x20, 0x21, 0x23, 0x24, @@ -280,73 +3230,139 @@ const LC3_INT ari_spec_lookup_fl[4096] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -const LC3_INT16 ari_spec_cumfreq_fl[64][18] = { - {0, 1, 2, 177, 225, 226, 227, 336, 372, 543, 652, 699, 719, 768, 804, 824, 834, 1024}, - {0, 18, 44, 61, 71, 98, 135, 159, 175, 197, 229, 251, 265, 282, 308, 328, 341, 1024}, - {0, 71, 163, 212, 237, 318, 420, 481, 514, 556, 613, 652, 675, 697, 727, 749, 764, 1024}, - {0, 160, 290, 336, 354, 475, 598, 653, 677, 722, 777, 808, 823, 842, 866, 881, 890, 1024}, - {0, 71, 144, 177, 195, 266, 342, 385, 411, 445, 489, 519, 539, 559, 586, 607, 622, 1024}, - {0, 48, 108, 140, 159, 217, 285, 327, 354, 385, 427, 457, 478, 497, 524, 545, 561, 1024}, - {0, 138, 247, 290, 308, 419, 531, 584, 609, 655, 710, 742, 759, 780, 807, 825, 836, 1024}, - {0, 16, 40, 62, 79, 103, 139, 170, 195, 215, 245, 270, 290, 305, 327, 346, 362, 1024}, - {0, 579, 729, 741, 743, 897, 970, 980, 982, 996, 1007, 1010, 1011, 1014, 1017, 1018, 1019, 1024}, - {0, 398, 582, 607, 612, 788, 902, 925, 931, 956, 979, 987, 990, 996, 1002, 1005, 1007, 1024}, - {0, 13, 34, 52, 63, 83, 112, 134, 149, 163, 183, 199, 211, 221, 235, 247, 257, 1024}, - {0, 281, 464, 501, 510, 681, 820, 857, 867, 902, 938, 953, 959, 968, 978, 984, 987, 1024}, - {0, 198, 362, 408, 421, 575, 722, 773, 789, 832, 881, 905, 915, 928, 944, 954, 959, 1024}, - {0, 1, 2, 95, 139, 140, 141, 213, 251, 337, 407, 450, 475, 515, 551, 576, 592, 1024}, - {0, 133, 274, 338, 366, 483, 605, 664, 691, 730, 778, 807, 822, 837, 857, 870, 878, 1024}, - {0, 128, 253, 302, 320, 443, 577, 636, 659, 708, 767, 799, 814, 833, 857, 872, 881, 1024}, - {0, 1, 2, 25, 42, 43, 44, 67, 85, 105, 126, 144, 159, 174, 191, 205, 217, 1024}, - {0, 70, 166, 229, 267, 356, 468, 533, 569, 606, 653, 685, 705, 722, 745, 762, 774, 1024}, - {0, 55, 130, 175, 200, 268, 358, 416, 449, 488, 542, 581, 606, 628, 659, 683, 699, 1024}, - {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 1024}, - {0, 34, 85, 123, 147, 196, 265, 317, 352, 386, 433, 470, 497, 518, 549, 574, 593, 1024}, - {0, 30, 73, 105, 127, 170, 229, 274, 305, 335, 377, 411, 436, 455, 483, 506, 524, 1024}, - {0, 9, 24, 38, 51, 65, 87, 108, 126, 139, 159, 177, 193, 204, 221, 236, 250, 1024}, - {0, 30, 74, 105, 125, 166, 224, 266, 294, 322, 361, 391, 413, 431, 457, 478, 494, 1024}, - {0, 15, 38, 58, 73, 95, 128, 156, 178, 196, 222, 245, 263, 276, 296, 314, 329, 1024}, - {0, 11, 28, 44, 57, 74, 100, 123, 142, 157, 179, 199, 216, 228, 246, 262, 276, 1024}, - {0, 448, 619, 639, 643, 821, 926, 944, 948, 971, 991, 998, 1000, 1005, 1010, 1012, 1013, 1024}, - {0, 332, 520, 549, 555, 741, 874, 903, 910, 940, 970, 981, 985, 991, 998, 1002, 1004, 1024}, - {0, 8, 21, 34, 45, 58, 78, 96, 112, 124, 141, 157, 170, 180, 194, 207, 219, 1024}, - {0, 239, 415, 457, 468, 631, 776, 820, 833, 872, 914, 933, 940, 951, 964, 971, 975, 1024}, - {0, 165, 310, 359, 375, 513, 652, 707, 727, 774, 828, 856, 868, 884, 904, 916, 923, 1024}, - {0, 3, 8, 13, 18, 23, 30, 37, 44, 48, 55, 62, 68, 72, 78, 84, 90, 1024}, - {0, 115, 237, 289, 311, 422, 547, 608, 635, 680, 737, 771, 788, 807, 832, 849, 859, 1024}, - {0, 107, 221, 272, 293, 399, 521, 582, 610, 656, 714, 749, 767, 787, 813, 831, 842, 1024}, - {0, 6, 16, 26, 35, 45, 60, 75, 89, 98, 112, 125, 137, 145, 157, 168, 178, 1024}, - {0, 72, 160, 210, 236, 320, 422, 482, 514, 555, 608, 644, 665, 685, 712, 732, 745, 1024}, - {0, 45, 108, 153, 183, 244, 327, 385, 421, 455, 502, 536, 559, 578, 605, 626, 641, 1024}, - {0, 1, 2, 9, 16, 17, 18, 26, 34, 40, 48, 55, 62, 68, 75, 82, 88, 1024}, - {0, 29, 73, 108, 132, 174, 236, 284, 318, 348, 391, 426, 452, 471, 500, 524, 543, 1024}, - {0, 20, 51, 76, 93, 123, 166, 200, 225, 247, 279, 305, 326, 342, 365, 385, 401, 1024}, - {0, 742, 845, 850, 851, 959, 997, 1001, 1002, 1009, 1014, 1016, 1017, 1019, 1020, 1021, 1022, 1024}, - {0, 42, 94, 121, 137, 186, 244, 280, 303, 330, 366, 392, 410, 427, 451, 470, 484, 1024}, - {0, 13, 33, 51, 66, 85, 114, 140, 161, 178, 203, 225, 243, 256, 275, 292, 307, 1024}, - {0, 501, 670, 689, 693, 848, 936, 952, 956, 975, 991, 997, 999, 1004, 1008, 1010, 1011, 1024}, - {0, 445, 581, 603, 609, 767, 865, 888, 895, 926, 954, 964, 968, 977, 986, 991, 993, 1024}, - {0, 285, 442, 479, 489, 650, 779, 818, 830, 870, 912, 930, 937, 949, 963, 971, 975, 1024}, - {0, 349, 528, 561, 569, 731, 852, 883, 892, 923, 953, 965, 970, 978, 987, 992, 994, 1024}, - {0, 199, 355, 402, 417, 563, 700, 750, 767, 811, 860, 884, 894, 909, 926, 936, 942, 1024}, - {0, 141, 275, 325, 343, 471, 606, 664, 686, 734, 791, 822, 836, 854, 877, 891, 899, 1024}, - {0, 243, 437, 493, 510, 649, 775, 820, 836, 869, 905, 923, 931, 941, 953, 960, 964, 1024}, - {0, 91, 197, 248, 271, 370, 487, 550, 580, 625, 684, 721, 741, 761, 788, 807, 819, 1024}, - {0, 107, 201, 242, 262, 354, 451, 503, 531, 573, 626, 660, 680, 701, 730, 751, 765, 1024}, - {0, 168, 339, 407, 432, 553, 676, 731, 755, 789, 830, 854, 866, 879, 895, 906, 912, 1024}, - {0, 67, 147, 191, 214, 290, 384, 441, 472, 513, 567, 604, 627, 648, 678, 700, 715, 1024}, - {0, 46, 109, 148, 171, 229, 307, 359, 391, 427, 476, 513, 537, 558, 588, 612, 629, 1024}, - {0, 848, 918, 920, 921, 996, 1012, 1013, 1014, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024}, - {0, 36, 88, 123, 145, 193, 260, 308, 340, 372, 417, 452, 476, 496, 525, 548, 565, 1024}, - {0, 24, 61, 90, 110, 145, 196, 237, 266, 292, 330, 361, 385, 403, 430, 453, 471, 1024}, - {0, 85, 182, 230, 253, 344, 454, 515, 545, 590, 648, 685, 706, 727, 756, 776, 789, 1024}, - {0, 22, 55, 82, 102, 135, 183, 222, 252, 278, 315, 345, 368, 385, 410, 431, 448, 1024}, - {0, 1, 2, 56, 89, 90, 91, 140, 172, 221, 268, 303, 328, 358, 388, 412, 430, 1024}, - {0, 45, 109, 152, 177, 239, 320, 376, 411, 448, 499, 537, 563, 585, 616, 640, 658, 1024}, - {0, 247, 395, 433, 445, 599, 729, 771, 785, 829, 875, 896, 905, 920, 937, 946, 951, 1024}, - {0, 231, 367, 408, 423, 557, 676, 723, 742, 786, 835, 860, 872, 889, 909, 921, 928, 1024}}; - -const LC3_INT ari_spec_bits_fl[64][17] = { +RAM_ALIGN const UWord16 ari_spec_cumfreq[64][17] = { + {0, 1, 2, 177, 225, 226, 227, 336, 372, 543, 652, 699, 719, 768, 804, 824, 834}, + {0, 18, 44, 61, 71, 98, 135, 159, 175, 197, 229, 251, 265, 282, 308, 328, 341}, + {0, 71, 163, 212, 237, 318, 420, 481, 514, 556, 613, 652, 675, 697, 727, 749, 764}, + {0, 160, 290, 336, 354, 475, 598, 653, 677, 722, 777, 808, 823, 842, 866, 881, 890}, + {0, 71, 144, 177, 195, 266, 342, 385, 411, 445, 489, 519, 539, 559, 586, 607, 622}, + {0, 48, 108, 140, 159, 217, 285, 327, 354, 385, 427, 457, 478, 497, 524, 545, 561}, + {0, 138, 247, 290, 308, 419, 531, 584, 609, 655, 710, 742, 759, 780, 807, 825, 836}, + {0, 16, 40, 62, 79, 103, 139, 170, 195, 215, 245, 270, 290, 305, 327, 346, 362}, + {0, 579, 729, 741, 743, 897, 970, 980, 982, 996, 1007, 1010, 1011, 1014, 1017, 1018, 1019}, + {0, 398, 582, 607, 612, 788, 902, 925, 931, 956, 979, 987, 990, 996, 1002, 1005, 1007}, + {0, 13, 34, 52, 63, 83, 112, 134, 149, 163, 183, 199, 211, 221, 235, 247, 257}, + {0, 281, 464, 501, 510, 681, 820, 857, 867, 902, 938, 953, 959, 968, 978, 984, 987}, + {0, 198, 362, 408, 421, 575, 722, 773, 789, 832, 881, 905, 915, 928, 944, 954, 959}, + {0, 1, 2, 95, 139, 140, 141, 213, 251, 337, 407, 450, 475, 515, 551, 576, 592}, + {0, 133, 274, 338, 366, 483, 605, 664, 691, 730, 778, 807, 822, 837, 857, 870, 878}, + {0, 128, 253, 302, 320, 443, 577, 636, 659, 708, 767, 799, 814, 833, 857, 872, 881}, + {0, 1, 2, 25, 42, 43, 44, 67, 85, 105, 126, 144, 159, 174, 191, 205, 217}, + {0, 70, 166, 229, 267, 356, 468, 533, 569, 606, 653, 685, 705, 722, 745, 762, 774}, + {0, 55, 130, 175, 200, 268, 358, 416, 449, 488, 542, 581, 606, 628, 659, 683, 699}, + {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, + {0, 34, 85, 123, 147, 196, 265, 317, 352, 386, 433, 470, 497, 518, 549, 574, 593}, + {0, 30, 73, 105, 127, 170, 229, 274, 305, 335, 377, 411, 436, 455, 483, 506, 524}, + {0, 9, 24, 38, 51, 65, 87, 108, 126, 139, 159, 177, 193, 204, 221, 236, 250}, + {0, 30, 74, 105, 125, 166, 224, 266, 294, 322, 361, 391, 413, 431, 457, 478, 494}, + {0, 15, 38, 58, 73, 95, 128, 156, 178, 196, 222, 245, 263, 276, 296, 314, 329}, + {0, 11, 28, 44, 57, 74, 100, 123, 142, 157, 179, 199, 216, 228, 246, 262, 276}, + {0, 448, 619, 639, 643, 821, 926, 944, 948, 971, 991, 998, 1000, 1005, 1010, 1012, 1013}, + {0, 332, 520, 549, 555, 741, 874, 903, 910, 940, 970, 981, 985, 991, 998, 1002, 1004}, + {0, 8, 21, 34, 45, 58, 78, 96, 112, 124, 141, 157, 170, 180, 194, 207, 219}, + {0, 239, 415, 457, 468, 631, 776, 820, 833, 872, 914, 933, 940, 951, 964, 971, 975}, + {0, 165, 310, 359, 375, 513, 652, 707, 727, 774, 828, 856, 868, 884, 904, 916, 923}, + {0, 3, 8, 13, 18, 23, 30, 37, 44, 48, 55, 62, 68, 72, 78, 84, 90}, + {0, 115, 237, 289, 311, 422, 547, 608, 635, 680, 737, 771, 788, 807, 832, 849, 859}, + {0, 107, 221, 272, 293, 399, 521, 582, 610, 656, 714, 749, 767, 787, 813, 831, 842}, + {0, 6, 16, 26, 35, 45, 60, 75, 89, 98, 112, 125, 137, 145, 157, 168, 178}, + {0, 72, 160, 210, 236, 320, 422, 482, 514, 555, 608, 644, 665, 685, 712, 732, 745}, + {0, 45, 108, 153, 183, 244, 327, 385, 421, 455, 502, 536, 559, 578, 605, 626, 641}, + {0, 1, 2, 9, 16, 17, 18, 26, 34, 40, 48, 55, 62, 68, 75, 82, 88}, + {0, 29, 73, 108, 132, 174, 236, 284, 318, 348, 391, 426, 452, 471, 500, 524, 543}, + {0, 20, 51, 76, 93, 123, 166, 200, 225, 247, 279, 305, 326, 342, 365, 385, 401}, + {0, 742, 845, 850, 851, 959, 997, 1001, 1002, 1009, 1014, 1016, 1017, 1019, 1020, 1021, 1022}, + {0, 42, 94, 121, 137, 186, 244, 280, 303, 330, 366, 392, 410, 427, 451, 470, 484}, + {0, 13, 33, 51, 66, 85, 114, 140, 161, 178, 203, 225, 243, 256, 275, 292, 307}, + {0, 501, 670, 689, 693, 848, 936, 952, 956, 975, 991, 997, 999, 1004, 1008, 1010, 1011}, + {0, 445, 581, 603, 609, 767, 865, 888, 895, 926, 954, 964, 968, 977, 986, 991, 993}, + {0, 285, 442, 479, 489, 650, 779, 818, 830, 870, 912, 930, 937, 949, 963, 971, 975}, + {0, 349, 528, 561, 569, 731, 852, 883, 892, 923, 953, 965, 970, 978, 987, 992, 994}, + {0, 199, 355, 402, 417, 563, 700, 750, 767, 811, 860, 884, 894, 909, 926, 936, 942}, + {0, 141, 275, 325, 343, 471, 606, 664, 686, 734, 791, 822, 836, 854, 877, 891, 899}, + {0, 243, 437, 493, 510, 649, 775, 820, 836, 869, 905, 923, 931, 941, 953, 960, 964}, + {0, 91, 197, 248, 271, 370, 487, 550, 580, 625, 684, 721, 741, 761, 788, 807, 819}, + {0, 107, 201, 242, 262, 354, 451, 503, 531, 573, 626, 660, 680, 701, 730, 751, 765}, + {0, 168, 339, 407, 432, 553, 676, 731, 755, 789, 830, 854, 866, 879, 895, 906, 912}, + {0, 67, 147, 191, 214, 290, 384, 441, 472, 513, 567, 604, 627, 648, 678, 700, 715}, + {0, 46, 109, 148, 171, 229, 307, 359, 391, 427, 476, 513, 537, 558, 588, 612, 629}, + {0, 848, 918, 920, 921, 996, 1012, 1013, 1014, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023}, + {0, 36, 88, 123, 145, 193, 260, 308, 340, 372, 417, 452, 476, 496, 525, 548, 565}, + {0, 24, 61, 90, 110, 145, 196, 237, 266, 292, 330, 361, 385, 403, 430, 453, 471}, + {0, 85, 182, 230, 253, 344, 454, 515, 545, 590, 648, 685, 706, 727, 756, 776, 789}, + {0, 22, 55, 82, 102, 135, 183, 222, 252, 278, 315, 345, 368, 385, 410, 431, 448}, + {0, 1, 2, 56, 89, 90, 91, 140, 172, 221, 268, 303, 328, 358, 388, 412, 430}, + {0, 45, 109, 152, 177, 239, 320, 376, 411, 448, 499, 537, 563, 585, 616, 640, 658}, + {0, 247, 395, 433, 445, 599, 729, 771, 785, 829, 875, 896, 905, 920, 937, 946, 951}, + {0, 231, 367, 408, 423, 557, 676, 723, 742, 786, 835, 860, 872, 889, 909, 921, 928}}; + +RAM_ALIGN const UWord16 ari_spec_freq[64][17] = { + {1, 1, 175, 48, 1, 1, 109, 36, 171, 109, 47, 20, 49, 36, 20, 10, 190}, + {18, 26, 17, 10, 27, 37, 24, 16, 22, 32, 22, 14, 17, 26, 20, 13, 683}, + {71, 92, 49, 25, 81, 102, 61, 33, 42, 57, 39, 23, 22, 30, 22, 15, 260}, + {160, 130, 46, 18, 121, 123, 55, 24, 45, 55, 31, 15, 19, 24, 15, 9, 134}, + {71, 73, 33, 18, 71, 76, 43, 26, 34, 44, 30, 20, 20, 27, 21, 15, 402}, + {48, 60, 32, 19, 58, 68, 42, 27, 31, 42, 30, 21, 19, 27, 21, 16, 463}, + {138, 109, 43, 18, 111, 112, 53, 25, 46, 55, 32, 17, 21, 27, 18, 11, 188}, + {16, 24, 22, 17, 24, 36, 31, 25, 20, 30, 25, 20, 15, 22, 19, 16, 662}, + {579, 150, 12, 2, 154, 73, 10, 2, 14, 11, 3, 1, 3, 3, 1, 1, 5}, + {398, 184, 25, 5, 176, 114, 23, 6, 25, 23, 8, 3, 6, 6, 3, 2, 17}, + {13, 21, 18, 11, 20, 29, 22, 15, 14, 20, 16, 12, 10, 14, 12, 10, 767}, + {281, 183, 37, 9, 171, 139, 37, 10, 35, 36, 15, 6, 9, 10, 6, 3, 37}, + {198, 164, 46, 13, 154, 147, 51, 16, 43, 49, 24, 10, 13, 16, 10, 5, 65}, + {1, 1, 93, 44, 1, 1, 72, 38, 86, 70, 43, 25, 40, 36, 25, 16, 432}, + {133, 141, 64, 28, 117, 122, 59, 27, 39, 48, 29, 15, 15, 20, 13, 8, 146}, + {128, 125, 49, 18, 123, 134, 59, 23, 49, 59, 32, 15, 19, 24, 15, 9, 143}, + {1, 1, 23, 17, 1, 1, 23, 18, 20, 21, 18, 15, 15, 17, 14, 12, 807}, + {70, 96, 63, 38, 89, 112, 65, 36, 37, 47, 32, 20, 17, 23, 17, 12, 250}, + {55, 75, 45, 25, 68, 90, 58, 33, 39, 54, 39, 25, 22, 31, 24, 16, 325}, + {1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 993}, + {34, 51, 38, 24, 49, 69, 52, 35, 34, 47, 37, 27, 21, 31, 25, 19, 431}, + {30, 43, 32, 22, 43, 59, 45, 31, 30, 42, 34, 25, 19, 28, 23, 18, 500}, + {9, 15, 14, 13, 14, 22, 21, 18, 13, 20, 18, 16, 11, 17, 15, 14, 774}, + {30, 44, 31, 20, 41, 58, 42, 28, 28, 39, 30, 22, 18, 26, 21, 16, 530}, + {15, 23, 20, 15, 22, 33, 28, 22, 18, 26, 23, 18, 13, 20, 18, 15, 695}, + {11, 17, 16, 13, 17, 26, 23, 19, 15, 22, 20, 17, 12, 18, 16, 14, 748}, + {448, 171, 20, 4, 178, 105, 18, 4, 23, 20, 7, 2, 5, 5, 2, 1, 11}, + {332, 188, 29, 6, 186, 133, 29, 7, 30, 30, 11, 4, 6, 7, 4, 2, 20}, + {8, 13, 13, 11, 13, 20, 18, 16, 12, 17, 16, 13, 10, 14, 13, 12, 805}, + {239, 176, 42, 11, 163, 145, 44, 13, 39, 42, 19, 7, 11, 13, 7, 4, 49}, + {165, 145, 49, 16, 138, 139, 55, 20, 47, 54, 28, 12, 16, 20, 12, 7, 101}, + {3, 5, 5, 5, 5, 7, 7, 7, 4, 7, 7, 6, 4, 6, 6, 6, 934}, + {115, 122, 52, 22, 111, 125, 61, 27, 45, 57, 34, 17, 19, 25, 17, 10, 165}, + {107, 114, 51, 21, 106, 122, 61, 28, 46, 58, 35, 18, 20, 26, 18, 11, 182}, + {6, 10, 10, 9, 10, 15, 15, 14, 9, 14, 13, 12, 8, 12, 11, 10, 846}, + {72, 88, 50, 26, 84, 102, 60, 32, 41, 53, 36, 21, 20, 27, 20, 13, 279}, + {45, 63, 45, 30, 61, 83, 58, 36, 34, 47, 34, 23, 19, 27, 21, 15, 383}, + {1, 1, 7, 7, 1, 1, 8, 8, 6, 8, 7, 7, 6, 7, 7, 6, 936}, + {29, 44, 35, 24, 42, 62, 48, 34, 30, 43, 35, 26, 19, 29, 24, 19, 481}, + {20, 31, 25, 17, 30, 43, 34, 25, 22, 32, 26, 21, 16, 23, 20, 16, 623}, + {742, 103, 5, 1, 108, 38, 4, 1, 7, 5, 2, 1, 2, 1, 1, 1, 2}, + {42, 52, 27, 16, 49, 58, 36, 23, 27, 36, 26, 18, 17, 24, 19, 14, 540}, + {13, 20, 18, 15, 19, 29, 26, 21, 17, 25, 22, 18, 13, 19, 17, 15, 717}, + {501, 169, 19, 4, 155, 88, 16, 4, 19, 16, 6, 2, 5, 4, 2, 1, 13}, + {445, 136, 22, 6, 158, 98, 23, 7, 31, 28, 10, 4, 9, 9, 5, 2, 31}, + {285, 157, 37, 10, 161, 129, 39, 12, 40, 42, 18, 7, 12, 14, 8, 4, 49}, + {349, 179, 33, 8, 162, 121, 31, 9, 31, 30, 12, 5, 8, 9, 5, 2, 30}, + {199, 156, 47, 15, 146, 137, 50, 17, 44, 49, 24, 10, 15, 17, 10, 6, 82}, + {141, 134, 50, 18, 128, 135, 58, 22, 48, 57, 31, 14, 18, 23, 14, 8, 125}, + {243, 194, 56, 17, 139, 126, 45, 16, 33, 36, 18, 8, 10, 12, 7, 4, 60}, + {91, 106, 51, 23, 99, 117, 63, 30, 45, 59, 37, 20, 20, 27, 19, 12, 205}, + {107, 94, 41, 20, 92, 97, 52, 28, 42, 53, 34, 20, 21, 29, 21, 14, 259}, + {168, 171, 68, 25, 121, 123, 55, 24, 34, 41, 24, 12, 13, 16, 11, 6, 112}, + {67, 80, 44, 23, 76, 94, 57, 31, 41, 54, 37, 23, 21, 30, 22, 15, 309}, + {46, 63, 39, 23, 58, 78, 52, 32, 36, 49, 37, 24, 21, 30, 24, 17, 395}, + {848, 70, 2, 1, 75, 16, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1}, + {36, 52, 35, 22, 48, 67, 48, 32, 32, 45, 35, 24, 20, 29, 23, 17, 459}, + {24, 37, 29, 20, 35, 51, 41, 29, 26, 38, 31, 24, 18, 27, 23, 18, 553}, + {85, 97, 48, 23, 91, 110, 61, 30, 45, 58, 37, 21, 21, 29, 20, 13, 235}, + {22, 33, 27, 20, 33, 48, 39, 30, 26, 37, 30, 23, 17, 25, 21, 17, 576}, + {1, 1, 54, 33, 1, 1, 49, 32, 49, 47, 35, 25, 30, 30, 24, 18, 594}, + {45, 64, 43, 25, 62, 81, 56, 35, 37, 51, 38, 26, 22, 31, 24, 18, 366}, + {247, 148, 38, 12, 154, 130, 42, 14, 44, 46, 21, 9, 15, 17, 9, 5, 73}, + {231, 136, 41, 15, 134, 119, 47, 19, 44, 49, 25, 12, 17, 20, 12, 7, 96}}; + +RAM_ALIGN const UWord16 ari_spec_bits[64][17] = { {20480, 20480, 5220, 9042, 20480, 20480, 6619, 9892, 5289, 6619, 9105, 11629, 8982, 9892, 11629, 13677, 4977}, {11940, 10854, 12109, 13677, 10742, 9812, 11090, 12288, 11348, 10240, 11348, 12683, 12109, 10854, 11629, 12902, 1197}, @@ -426,183 +3442,20 @@ const LC3_INT ari_spec_bits_fl[64][17] = { {4202, 5716, 9733, 13138, 5598, 6099, 9437, 12683, 9300, 9168, 11485, 13988, 12479, 12109, 13988, 15725, 7804}, {4400, 5965, 9508, 12479, 6009, 6360, 9105, 11781, 9300, 8982, 10970, 13138, 12109, 11629, 13138, 14731, 6994}}; -const LC3_FLOAT sns_LFCB[8][32] = { - {2.26283365592678, 2.94516479191376, -2.18610707009979, 0.693688236528920, -1.29752132315296, 0.914652037830672, - -2.51428812578962, -0.922188404812385, 0.790322288369266, 1.44775580178724, 0.793354526417474, 2.72425347385034, - -0.530830198375400, 1.68728410845006, -2.95183272801858, 0.101878342785628, 2.68254575498426, 4.82697923680403, - 0.0878419936470335, 1.39102308204326, 0.384585893889182, 1.93227399441719, 0.175080462899884, -1.18817020250556, - 2.53322203327061, 3.99889837485606, 0.507902593186381, 3.16856825107569, 1.89414766731764, 0.948880604517188, - -1.88026757045628, 0.246375746277129}, - {0.813311269061339, 2.41143317956679, -1.97152135675228, 0.955609857158220, -0.740369057177853, - 1.74293043435257, -2.89175271384373, 0.632495141440552, 0.628401261876199, 2.72399951674952, - 0.0143931185523454, 2.95947572404824, -0.212690682812164, 2.43614509237656, -1.59393496773345, - 0.589857324228917, 1.32738010899420, 3.11947804492488, -0.569586840238501, 1.98146479199466, - -0.160588785536510, 3.01030180412057, -0.750522832248985, 0.366792873662636, 2.11274642695908, - 4.07901751451956, 1.58838449789527, 3.25853458159407, 1.25108694609232, 2.13239439249982, - -1.26431072758705, 0.955621773393099}, - {-0.530193494871436, 0.960455106400727, -1.78718619681006, 0.575230787038733, -0.345372483642106, - 1.90906626859986, -2.00450666759434, 1.08736431254641, 0.393117923540450, 2.31083268737528, - -0.567834844729679, 1.84953559268461, 0.00576613628377097, 2.33019429078225, -0.109918772878022, - 0.619047646793466, 0.130185273804048, 1.39513671385178, -1.14506015668811, 1.11265796388770, - -0.539366809557710, 3.06543893826204, -1.03943893342231, 1.30957830409096, 1.26288411502064, - 2.82285661102496, 1.72899023869209, 2.42230591328599, 0.590451210720628, 2.72345350344278, - 0.311424976968699, 1.52046776741766}, - {-1.35664835903442, -0.443226488076917, -1.91865895685577, -0.114603419462889, -0.313285696247940, - 1.54408483842665, -0.750912273903127, 0.608628624535820, 0.480007710866901, 0.935051269566529, - -0.654760467916745, 0.563284922322364, 0.424871484383745, 1.77983777835091, 0.388609072919257, - 1.26731313851796, -0.338533088511347, 0.250295315918722, -1.66968488172598, -0.220107509420743, - -0.529309078789857, 2.50110160870008, -1.13577508937648, 1.68330687280491, 0.761513512430427, - 1.72607212849580, 1.00692230241726, 1.79446077643261, 0.608358583293714, 2.76986076866588, - 1.83670210306430, 1.97647400419457}, - {-1.59952176563196, -1.22913612425590, -1.79399121836596, -0.646050637436029, -0.402977242824477, - 1.09344960761455, 0.441202104904691, 0.131174567547348, 0.447815138050143, -0.274743911383688, - -0.479458998475743, 0.139917088125072, 0.473128952158668, 1.44411295390082, 0.512932649517584, - 2.41961047769804, -0.368219235899667, -0.393613839379793, -1.84534417603682, -0.774965611552366, - 0.190433547437932, 1.93089592978934, -1.04197903837494, 1.25100924225127, 0.522117937976170, - 0.647144377348619, 0.377121231816382, 1.52177910653089, 0.878171010011082, 2.54286973254946, - 2.25634191839874, 1.94043867177462}, - {-1.44098768430095, -1.55590039118170, -1.35738404257288, -0.952351370449625, -0.372020853465227, - 0.647479549518278, 1.20190987601009, -0.296149157743752, 0.209734214552234, -0.902077696828602, - -0.173894661902889, 0.359641093366222, 0.858894199321281, 1.51995177009730, 0.628112597063497, - 2.25174252572187, -0.191689946715961, -0.643458173054701, -1.56468027328802, -0.594063874149117, - 2.56062918106522, 0.572153810961837, -0.0152060098993382, 0.942375751628615, 0.118680069757121, - -0.331148521217238, 0.476370766899498, 1.17196706537602, 1.11912510950950, 2.02046263825019, - 2.04818998463474, 2.23375847282686}, - {-1.14381648305821, -1.49688655952376, -0.705444279353869, -1.07405247226150, -0.0783414177323738, - 0.0361790752449642, 1.32742857257290, -0.207013516525629, 0.00656691996428021, -0.940681511945404, - 0.0680162705515438, 0.689461354774589, 1.19111160854435, 1.47199393750425, 0.822621796430634, - 0.526537030991201, -0.154782377153908, -0.642570736856943, -1.11746759076420, 0.136937680628923, - 2.81896398245248, -0.811741794081091, 2.07048391716707, 0.826250483374133, -0.452346827507370, - -0.884042570848749, 1.08754740372170, 0.489394596980695, 1.01857661550342, 0.830045859400910, - 2.19526837458568, 1.98835977758407}, - {-0.755203767909064, -1.11689986501469, -0.0478172944777711, -0.758087707094905, 0.0970441303992295, - -0.297092807178889, 1.22049081140984, 0.134924916642080, -0.0861242342061857, -0.633697038974310, - 0.295125948369794, 0.639790176833105, 0.996189669638358, 0.977682473891761, 0.875891424655081, - -0.396591513227999, -0.234207177774392, -0.723193223444072, -0.533981663366786, 0.818242891264338, - 0.656670875696161, -1.17641810861903, 3.42948918081689, 0.439952741120956, -0.700352426161103, - -1.12697340645478, 1.08756266099221, -0.0622795715718769, 0.620453891011724, -0.0275569173888263, - 2.02659613836619, 1.27232672554701}}; - -const LC3_FLOAT sns_HFCB[8][32] = { - {0.232028419124465, -1.29503936673618, 0.139285716045803, -0.316513102185725, 0.879518405226496, - -0.296701922455375, 0.340981100469697, -1.41229759077597, -0.228839511827379, -1.07148628544449, - -0.590988511188051, -0.848434098836164, 1.14069145562382, -0.376283237967464, 0.665004120598402, - -0.826265953982679, 1.41008326832173, 0.361386817574348, 0.437469239330329, 0.648100318996503, - 1.11919833091304, 0.141847497087176, 0.504046955390252, -0.501076050479357, 3.74970982709642, - -1.15258990980549, 1.02827246422140, 0.128831971707817, 1.34033030334757, 2.13843105419313, - 0.564830487355396, -0.422460547586087}, - {-1.00890270604455, -1.79929965384339, -0.258185126171752, -0.477747657209805, 0.298340096007189, - -0.975004919174553, 0.268899788946055, -1.48522119349852, -0.333719069784662, -1.41767015456261, - -0.0711737758537628, -0.583226810708889, 0.964016892398293, 0.0425675462096105, 1.09790764690795, - -0.671181232766603, 0.754441907835468, -0.0219991705427826, 0.305440419605961, 0.682299133640680, - 1.23465532536005, -0.110660070633151, 0.826982162959097, -0.325678006081417, 1.52342611847045, - -1.10800885906241, 1.09770519389828, 0.689439395264878, 1.38996825067789, 4.24711267303104, - 1.59184977958743, 0.326149625049801}, - {-2.14223502789471, -1.88703147531519, -0.650804572670110, -0.551162075879755, -0.915386396405710, - -1.35857500246993, 0.0563335684828033, -1.18603579834700, -0.809321359324656, -1.54891762265441, - 0.345719522947313, 0.0900423688142873, 0.381461205984798, 0.516547696592306, 1.38342667112079, - -0.228495592779472, -1.30550584958631, -0.579368833633824, -0.00738786566478374, 0.253247464332976, - 0.589170238085318, -0.282824592543629, 1.11981236291828, 0.0280798194947077, -0.457715661897855, - -0.562615116512472, 0.768645545764776, 1.12346905009575, 1.04467921708883, 2.89734109830439, - 2.39771699015146, 1.39171313342261}, - {-2.37533813570664, -1.80991659687332, -1.06815731781969, -0.484788283381197, -2.20645974739762, - -0.983721105837444, 0.0499114046826685, -0.625001634441352, -1.63587876923797, -1.45296062475530, - 0.300549460996251, 0.845025007556886, -0.482849340608998, 0.251716881864630, 1.34327358628285, - 0.518980852551937, -1.87133711350971, -0.879427960941070, -0.495649854710252, 0.0735842143788469, - -1.37192459653166, -0.00659813474614194, 1.17914044332734, 0.262054554763133, -0.798711008243192, - -0.220562123765675, 0.206081977740766, 1.30934523106594, 0.635822746244367, 0.932730658026815, - 3.03697343600704, 2.23146614636474}, - {-2.23041933049655, -1.76340038479206, -1.61928741524302, -0.238388394455814, -2.74142180959951, - -0.652956939100809, -0.0954130727414369, 0.153902497468304, -1.88486397330982, -1.03182970062270, - -1.11865218295857, 1.06572384501716, -1.81632721260589, -0.216179967524303, 0.822978836855922, - 1.36721896340278, -1.24008685156305, -0.850685023408119, -0.806651271118393, 0.314216709389010, - -2.37095707241577, 0.285929279627216, 1.07987429197260, 0.360590806085767, -0.386819329309100, - -0.349842880336644, -0.342805735091998, 1.35511964713935, -0.274733755518482, -0.292822249729810, - 2.66424350337151, 2.61179442169688}, - {-2.17595881223696, -1.83418428467950, -2.18762566441756, -0.143024507285504, -2.86139074276891, - -0.989986992921811, -0.760166146083885, 0.576386497810755, -1.64496691316356, -0.690642640272584, - -2.44089151148049, 0.737582999377756, -2.80279512728555, -0.534074091124504, 0.215876798515679, - 2.18023038253092, -1.26712924866274, -0.779397050155816, -1.22431891984401, 0.234729880923679, - -2.00779782682360, 0.0460445529952971, 0.697536239067500, 0.635623722053700, -0.375901062231203, - -0.753432770250495, -0.754939404625340, 1.42311381470799, -1.54923372430695, -0.810404296853182, - 1.39304485032606, 2.66540340196570}, - {-2.29065913541000, -1.80480980687405, -2.63757586939054, 0.0683186673649074, -2.88841597105271, - -1.61467224598900, -2.32758120177007, 0.795092603798871, -1.40515778046612, -0.428843804532171, - -2.22854732450735, 0.256590452459912, -3.23385724833864, -0.640786096262196, -0.404925753080293, - 2.53596092750107, -2.03670813003907, -0.732182927291826, -1.70157770043181, 0.144600134479837, - -1.66688540224395, -0.602596415577886, -0.912548817371081, 0.959012467178154, -0.657836899930538, - -0.988596593396384, -1.04196177632000, 1.15706449190905, -2.44239710278007, -0.788868098756483, - 0.403834023595745, 2.40103554105707}, - {-2.53286397979846, -1.73679545317401, -2.97897749575096, 0.0883061717288066, -2.95182608262521, - -2.40712302385116, -3.77155485385656, 0.596564632144913, -1.46666471326146, -0.494960215408874, - -1.89509228210853, -0.491963359762378, -3.45908714491473, -0.869745032374135, -1.07025605870523, - 2.20121098860036, -2.89685162242381, -0.888348514821255, -2.24491913755611, -0.0682120178880174, - -1.92631846258406, -2.26568728632575, -3.57684747062773, 1.30745156688653, -1.28163964243603, - -1.28790471791471, -1.50335652955529, 0.406319437516838, -3.02457606944550, -0.935353148761338, - -0.656270971328114, 1.75920379670881}}; - -const LC3_INT pvq_enc_A[16][11] = {{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19}, - {0, 1, 5, 13, 25, 41, 61, 85, 113, 145, 181}, - {0, 1, 7, 25, 63, 129, 231, 377, 575, 833, 1159}, - {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649, 5641}, - {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073, 22363}, - {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081, 75517}, - {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545, 224143}, - {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729, 598417}, - {0, 1, 19, 181, 1159, 5641, 22363, 75517, 224143, 598417, 1462563}, - {0, 1, 21, 221, 1561, 8361, 36365, 134245, 433905, 1256465, 3317445}, - {0, 1, 23, 265, 2047, 11969, 56695, 227305, 795455, 2485825, 7059735}, - {0, 1, 25, 313, 2625, 16641, 85305, 369305, 1392065, 4673345, 14218905}, - {0, 1, 27, 365, 3303, 22569, 124515, 579125, 2340495, 8405905, 27298155}, - {0, 1, 29, 421, 4089, 29961, 177045, 880685, 3800305, 14546705, 50250765}, - {0, 1, 31, 481, 4991, 39041, 246047, 1303777, 5984767, 24331777, 89129247}}; - -const LC3_FLOAT lp_scale_factors[6] = {1, 1, 0.6666666666666666, .5, 0.3333333333333333, 0.16666666666666666}; - - -/* 12.8 kHz resampler */ -const LC3_FLOAT highpass50_filt_b[3] = {0.9827947082978771, -1.965589416595754, 0.9827947082978771}; -const LC3_FLOAT highpass50_filt_a[3] = {1, -1.9652933726226904, 0.9658854605688177}; - -const LC3_INT32 resamp_params[][4] = { - {24, 5, 0, 15}, - {12, 10, 1, 3}, - {8, 15, 1, 7}, - {6, 20, 2, 3}, - {4, 30, 3, 3}, - {2, 60, 7, 1} -}; - - -const LC3_FLOAT lp_filter_8[240] = {0.0065408750, 0.0127360141, -0.0320970677, -0.1382038444, 0.8005587459, -0.1382038444, -0.0320970677, 0.0127360141, 0.0065408750, 0.0000000000, 0.0064595463, 0.0084537705, -0.0391003005, -0.1198658869, 0.7945935130, -0.1519452035, -0.0230523963, 0.0167804975, 0.0063002659, -0.0002451667, 0.0060938913, 0.0041435249, -0.0439039879, -0.0980933905, 0.7768620253, -0.1600013375, -0.0122310519, 0.0203715712, 0.0057131811, -0.0005356151, 0.0054914863, 0.0000000000, -0.0464562289, -0.0740769655, 0.7478516698, -0.1614013463, 0.0000000000, 0.0232978407, 0.0047708568, -0.0008596397, 0.0047065411, -0.0038048958, -0.0468063876, -0.0489920303, 0.7083564401, -0.1553338468, 0.0131809860, 0.0253629088, 0.0034824028, -0.0012012133, 0.0037965439, -0.0071282135, -0.0450960808, -0.0239577144, 0.6594504118, -0.1411849856, 0.0267735831, 0.0263961889, 0.0018761361, -0.0015404741, 0.0028190494, -0.0098603060, -0.0415467210, -0.0000000000, 0.6024519205, -0.1185704023, 0.0401797108, 0.0262632743, -0.0000000000, -0.0018545259, 0.0018287648, -0.0119272992, -0.0364444591, 0.0219798349, 0.5388799906, -0.0873604342, 0.0527642742, 0.0248753466, -0.0020790326, -0.0021185349, 0.0008750616, -0.0132916924, -0.0301232301, 0.0412303619, 0.4704038501, -0.0476967618, 0.0638811216, 0.0221970305, -0.0042766319, -0.0023070835, 0.0000000000, -0.0139512215, -0.0229468606, 0.0571681485, 0.3987891078, 0.0000000000, 0.0729012638, 0.0182522610, -0.0064938627, -0.0023957258, -0.0007630716, -0.0139361415, -0.0152910165, 0.0693885013, 0.3258404732, 0.0550325289, 0.0792422444, 0.0131276902, -0.0086209681, -0.0023626641, -0.0013903243, -0.0133052040, -0.0075258445, 0.0776687115, 0.2533447146, 0.1164389849, 0.0823974460, 0.0069732964, -0.0105420630, -0.0021904600, -0.0018676731, -0.0121405739, -0.0000000000, 0.0819641128, 0.1830149740, 0.1830149740, 0.0819641128, -0.0000000000, -0.0121405739, -0.0018676731, -0.0021904600, -0.0105420630, 0.0069732964, 0.0823974460, 0.1164389849, 0.2533447146, 0.0776687115, -0.0075258445, -0.0133052040, -0.0013903243, -0.0023626641, -0.0086209681, 0.0131276902, 0.0792422444, 0.0550325289, 0.3258404732, 0.0693885013, -0.0152910165, -0.0139361415, -0.0007630716, -0.0023957258, -0.0064938627, 0.0182522610, 0.0729012638, 0.0000000000, 0.3987891078, 0.0571681485, -0.0229468606, -0.0139512215, 0.0000000000, -0.0023070835, -0.0042766319, 0.0221970305, 0.0638811216, -0.0476967618, 0.4704038501, 0.0412303619, -0.0301232301, -0.0132916924, 0.0008750616, -0.0021185349, -0.0020790326, 0.0248753466, 0.0527642742, -0.0873604342, 0.5388799906, 0.0219798349, -0.0364444591, -0.0119272992, 0.0018287648, -0.0018545259, -0.0000000000, 0.0262632743, 0.0401797108, -0.1185704023, 0.6024519205, -0.0000000000, -0.0415467210, -0.0098603060, 0.0028190494, -0.0015404741, 0.0018761361, 0.0263961889, 0.0267735831, -0.1411849856, 0.6594504118, -0.0239577144, -0.0450960808, -0.0071282135, 0.0037965439, -0.0012012133, 0.0034824028, 0.0253629088, 0.0131809860, -0.1553338468, 0.7083564401, -0.0489920303, -0.0468063876, -0.0038048958, 0.0047065411, -0.0008596397, 0.0047708568, 0.0232978407, 0.0000000000, -0.1614013463, 0.7478516698, -0.0740769655, -0.0464562289, 0.0000000000, 0.0054914863, -0.0005356151, 0.0057131811, 0.0203715712, -0.0122310519, -0.1600013375, 0.7768620253, -0.0980933905, -0.0439039879, 0.0041435249, 0.0060938913, -0.0002451667, 0.0063002659, 0.0167804975, -0.0230523963, -0.1519452035, 0.7945935130, -0.1198658869, -0.0391003005, 0.0084537705, 0.0064595463}; - -const LC3_FLOAT lp_filter_16[240] = { --0.0018676731, 0.0065408750, -0.0121405739, 0.0127360141, -0.0000000000, -0.0320970677, 0.0819641128, -0.1382038444, 0.1830149740, 0.8005587459, 0.1830149740, -0.1382038444, 0.0819641128, -0.0320970677, -0.0000000000, 0.0127360141, -0.0121405739, 0.0065408750, -0.0018676731, 0.0000000000, -0.0021904600, 0.0064595463, -0.0105420630, 0.0084537705, 0.0069732964, -0.0391003005, 0.0823974460, -0.1198658869, 0.1164389849, 0.7945935130, 0.2533447146, -0.1519452035, 0.0776687115, -0.0230523963, -0.0075258445, 0.0167804975, -0.0133052040, 0.0063002659, -0.0013903243, -0.0002451667, -0.0023626641, 0.0060938913, -0.0086209681, 0.0041435249, 0.0131276902, -0.0439039879, 0.0792422444, -0.0980933905, 0.0550325289, 0.7768620253, 0.3258404732, -0.1600013375, 0.0693885013, -0.0122310519, -0.0152910165, 0.0203715712, -0.0139361415, 0.0057131811, -0.0007630716, -0.0005356151, -0.0023957258, 0.0054914863, -0.0064938627, 0.0000000000, 0.0182522610, -0.0464562289, 0.0729012638, -0.0740769655, 0.0000000000, 0.7478516698, 0.3987891078, -0.1614013463, 0.0571681485, 0.0000000000, -0.0229468606, 0.0232978407, -0.0139512215, 0.0047708568, 0.0000000000, -0.0008596397, -0.0023070835, 0.0047065411, -0.0042766319, -0.0038048958, 0.0221970305, -0.0468063876, 0.0638811216, -0.0489920303, -0.0476967618, 0.7083564401, 0.4704038501, -0.1553338468, 0.0412303619, 0.0131809860, -0.0301232301, 0.0253629088, -0.0132916924, 0.0034824028, 0.0008750616, -0.0012012133, -0.0021185349, 0.0037965439, -0.0020790326, -0.0071282135, 0.0248753466, -0.0450960808, 0.0527642742, -0.0239577144, -0.0873604342, 0.6594504118, 0.5388799906, -0.1411849856, 0.0219798349, 0.0267735831, -0.0364444591, 0.0263961889, -0.0119272992, 0.0018761361, 0.0018287648, -0.0015404741, -0.0018545259, 0.0028190494, -0.0000000000, -0.0098603060, 0.0262632743, -0.0415467210, 0.0401797108, -0.0000000000, -0.1185704023, 0.6024519205, 0.6024519205, -0.1185704023, -0.0000000000, 0.0401797108, -0.0415467210, 0.0262632743, -0.0098603060, -0.0000000000, 0.0028190494, -0.0018545259, -0.0015404741, 0.0018287648, 0.0018761361, -0.0119272992, 0.0263961889, -0.0364444591, 0.0267735831, 0.0219798349, -0.1411849856, 0.5388799906, 0.6594504118, -0.0873604342, -0.0239577144, 0.0527642742, -0.0450960808, 0.0248753466, -0.0071282135, -0.0020790326, 0.0037965439, -0.0021185349, -0.0012012133, 0.0008750616, 0.0034824028, -0.0132916924, 0.0253629088, -0.0301232301, 0.0131809860, 0.0412303619, -0.1553338468, 0.4704038501, 0.7083564401, -0.0476967618, -0.0489920303, 0.0638811216, -0.0468063876, 0.0221970305, -0.0038048958, -0.0042766319, 0.0047065411, -0.0023070835, -0.0008596397, 0.0000000000, 0.0047708568, -0.0139512215, 0.0232978407, -0.0229468606, 0.0000000000, 0.0571681485, -0.1614013463, 0.3987891078, 0.7478516698, 0.0000000000, -0.0740769655, 0.0729012638, -0.0464562289, 0.0182522610, 0.0000000000, -0.0064938627, 0.0054914863, -0.0023957258, -0.0005356151, -0.0007630716, 0.0057131811, -0.0139361415, 0.0203715712, -0.0152910165, -0.0122310519, 0.0693885013, -0.1600013375, 0.3258404732, 0.7768620253, 0.0550325289, -0.0980933905, 0.0792422444, -0.0439039879, 0.0131276902, 0.0041435249, -0.0086209681, 0.0060938913, -0.0023626641, -0.0002451667, -0.0013903243, 0.0063002659, -0.0133052040, 0.0167804975, -0.0075258445, -0.0230523963, 0.0776687115, -0.1519452035, 0.2533447146, 0.7945935130, 0.1164389849, -0.1198658869, 0.0823974460, -0.0391003005, 0.0069732964, 0.0084537705, -0.0105420630, 0.0064595463, -0.0021904600 -}; - -const LC3_FLOAT lp_filter_24[240] = { --0.0015380557, 0.0005833744, 0.0043605831, -0.0028510878, -0.0088611282, 0.0084906761, 0.0147980200, -0.0200821534, -0.0213980451, 0.0425874144, 0.0274869073, -0.0921358988, -0.0317978412, 0.3136025667, 0.5337058306, 0.3136025667, -0.0317978412, -0.0921358988, 0.0274869073, 0.0425874144, -0.0213980451, -0.0200821534, 0.0147980200, 0.0084906761, -0.0088611282, -0.0028510878, 0.0043605831, 0.0005833744, -0.0015380557, 0.0000000000, -0.0014123565, 0.0000000000, 0.0043063643, -0.0013860217, -0.0093008140, 0.0056358469, 0.0165835638, -0.0152979074, -0.0260668676, 0.0351761840, 0.0381121002, -0.0799105912, -0.0582402907, 0.2658593953, 0.5297290087, 0.3592533171, 0.0000000000, -0.1012968048, 0.0146532226, 0.0486008413, -0.0153682642, -0.0242963061, 0.0121681746, 0.0111869983, -0.0079515325, -0.0043292418, 0.0042001773, 0.0012191766, -0.0015971506, -0.0001634445, -0.0012363506, -0.0005087144, 0.0040625944, -0.0000000000, -0.0092907613, 0.0027623500, 0.0175088495, -0.0101940110, -0.0292693246, 0.0267864745, 0.0462590009, -0.0653955936, -0.0790469348, 0.2172269821, 0.5179080367, 0.4016346335, 0.0366883539, -0.1066675633, -0.0000000000, 0.0528281629, -0.0081540346, -0.0276978146, 0.0087517938, 0.0135810468, -0.0065735374, -0.0057473122, 0.0038087873, 0.0018793662, -0.0015751094, -0.0003570767, -0.0010269828, -0.0009268829, 0.0036609909, 0.0012507574, -0.0088701360, 0.0000000000, 0.0175974593, -0.0050172298, -0.0309708193, 0.0178490561, 0.0517791398, -0.0493846424, -0.0941233262, 0.1688964665, 0.4985677898, 0.4396336079, 0.0776259899, -0.1076008976, -0.0159718096, 0.0549316332, 0.0000000000, -0.0300640538, 0.0046488643, 0.0155318938, -0.0047521424, -0.0070280419, 0.0031805711, 0.0025310293, -0.0014603067, -0.0005730931, -0.0008008089, -0.0012451154, 0.0031376940, 0.0023216018, -0.0080937156, -0.0025365972, 0.0169086065, -0.0000000000, -0.0312042590, 0.0087873237, 0.0546427406, -0.0326613523, -0.1035559028, 0.1220099851, 0.4722376168, 0.4722376168, 0.1220099851, -0.1035559028, -0.0326613523, 0.0546427406, 0.0087873237, -0.0312042590, -0.0000000000, 0.0169086065, -0.0025365972, -0.0080937156, 0.0023216018, 0.0031376940, -0.0012451154, -0.0008008089, -0.0005730931, -0.0014603067, 0.0025310293, 0.0031805711, -0.0070280419, -0.0047521424, 0.0155318938, 0.0046488643, -0.0300640538, 0.0000000000, 0.0549316332, -0.0159718096, -0.1076008976, 0.0776259899, 0.4396336079, 0.4985677898, 0.1688964665, -0.0941233262, -0.0493846424, 0.0517791398, 0.0178490561, -0.0309708193, -0.0050172298, 0.0175974593, 0.0000000000, -0.0088701360, 0.0012507574, 0.0036609909, -0.0009268829, -0.0010269828, -0.0003570767, -0.0015751094, 0.0018793662, 0.0038087873, -0.0057473122, -0.0065735374, 0.0135810468, 0.0087517938, -0.0276978146, -0.0081540346, 0.0528281629, -0.0000000000, -0.1066675633, 0.0366883539, 0.4016346335, 0.5179080367, 0.2172269821, -0.0790469348, -0.0653955936, 0.0462590009, 0.0267864745, -0.0292693246, -0.0101940110, 0.0175088495, 0.0027623500, -0.0092907613, -0.0000000000, 0.0040625944, -0.0005087144, -0.0012363506, -0.0001634445, -0.0015971506, 0.0012191766, 0.0042001773, -0.0043292418, -0.0079515325, 0.0111869983, 0.0121681746, -0.0242963061, -0.0153682642, 0.0486008413, 0.0146532226, -0.1012968048, 0.0000000000, 0.3592533171, 0.5297290087, 0.2658593953, -0.0582402907, -0.0799105912, 0.0381121002, 0.0351761840, -0.0260668676, -0.0152979074, 0.0165835638, 0.0056358469, -0.0093008140, -0.0013860217, 0.0043063643, 0.0000000000, -0.0014123565 -}; - -const LC3_FLOAT lp_filter_32[240] = { --0.0009272629, -0.0009338366, 0.0014095247, 0.0032704375, -0.0000000000, -0.0060702870, -0.0049301530, 0.0063680070, 0.0131316371, -0.0000000000, -0.0207733605, -0.0160485338, 0.0200898554, 0.0409820564, -0.0000000000, -0.0691019222, -0.0592852011, 0.0915074870, 0.3012259603, 0.4002793729, 0.3012259603, 0.0915074870, -0.0592852011, -0.0691019222, -0.0000000000, 0.0409820564, 0.0200898554, -0.0160485338, -0.0207733605, -0.0000000000, 0.0131316371, 0.0063680070, -0.0049301530, -0.0060702870, -0.0000000000, 0.0032704375, 0.0014095247, -0.0009338366, -0.0009272629, 0.0000000000, -0.0007702371, -0.0010952300, 0.0009143824, 0.0032297731, 0.0009380680, -0.0052710315, -0.0059636496, 0.0042268853, 0.0131980944, 0.0034866482, -0.0182222296, -0.0195501503, 0.0133867916, 0.0411987230, 0.0109899174, -0.0599329434, -0.0705924928, 0.0582194924, 0.2694399953, 0.3972967565, 0.3297252059, 0.1266723573, -0.0436802171, -0.0759726018, -0.0119788572, 0.0388343558, 0.0263821371, -0.0115261981, -0.0225480404, -0.0037629222, 0.0124376733, 0.0083902488, -0.0035641068, -0.0066526020, -0.0010395163, 0.0031501330, 0.0018982720, -0.0006951622, -0.0010592674, -0.0001225834, -0.0006006067, -0.0011813320, 0.0004375308, 0.0030469457, 0.0017412014, -0.0043104840, -0.0066458462, 0.0020717625, 0.0126814544, 0.0065638451, -0.0150616150, -0.0219519939, 0.0065904930, 0.0396211222, 0.0206151810, -0.0490466952, -0.0776669234, 0.0275162645, 0.2352019250, 0.3884310126, 0.3541782200, 0.1629202366, -0.0238483809, -0.0800006688, -0.0244960152, 0.0346942507, 0.0319405608, -0.0061155260, -0.0234031938, -0.0076455083, 0.0110985152, 0.0101857856, -0.0019024479, -0.0069680708, -0.0021383159, 0.0028565906, 0.0023532705, -0.0003815358, -0.0011535417, -0.0002678075, -0.0004298199, -0.0011978629, 0.0000000000, 0.0027457431, 0.0023854284, -0.0032469314, -0.0069756107, 0.0000000000, 0.0116489204, 0.0091261305, -0.0114734303, -0.0232281145, 0.0000000000, 0.0364506319, 0.0285840742, -0.0370384827, -0.0807006732, 0.0000000000, 0.1993945539, 0.3739258349, 0.3739258349, 0.1993945539, 0.0000000000, -0.0807006732, -0.0370384827, 0.0285840742, 0.0364506319, 0.0000000000, -0.0232281145, -0.0114734303, 0.0091261305, 0.0116489204, 0.0000000000, -0.0069756107, -0.0032469314, 0.0023854284, 0.0027457431, 0.0000000000, -0.0011978629, -0.0004298199, -0.0002678075, -0.0011535417, -0.0003815358, 0.0023532705, 0.0028565906, -0.0021383159, -0.0069680708, -0.0019024479, 0.0101857856, 0.0110985152, -0.0076455083, -0.0234031938, -0.0061155260, 0.0319405608, 0.0346942507, -0.0244960152, -0.0800006688, -0.0238483809, 0.1629202366, 0.3541782200, 0.3884310126, 0.2352019250, 0.0275162645, -0.0776669234, -0.0490466952, 0.0206151810, 0.0396211222, 0.0065904930, -0.0219519939, -0.0150616150, 0.0065638451, 0.0126814544, 0.0020717625, -0.0066458462, -0.0043104840, 0.0017412014, 0.0030469457, 0.0004375308, -0.0011813320, -0.0006006067, -0.0001225834, -0.0010592674, -0.0006951622, 0.0018982720, 0.0031501330, -0.0010395163, -0.0066526020, -0.0035641068, 0.0083902488, 0.0124376733, -0.0037629222, -0.0225480404, -0.0115261981, 0.0263821371, 0.0388343558, -0.0119788572, -0.0759726018, -0.0436802171, 0.1266723573, 0.3297252059, 0.3972967565, 0.2694399953, 0.0582194924, -0.0705924928, -0.0599329434, 0.0109899174, 0.0411987230, 0.0133867916, -0.0195501503, -0.0182222296, 0.0034866482, 0.0131980944, 0.0042268853, -0.0059636496, -0.0052710315, 0.0009380680, 0.0032297731, 0.0009143824, -0.0010952300, -0.0007702371 -}; - -const LC3_FLOAT lp_filter_48[240] = { --0.0004004044, -0.0007690279, -0.0006225577, 0.0002916872, 0.0015688470, 0.0021802916, 0.0011608009, -0.0014255439, -0.0040468578, -0.0044305641, -0.0012682986, 0.0042453380, 0.0084543033, 0.0073990100, -0.0000000000, -0.0100410767, -0.0156021295, -0.0106990226, 0.0043936619, 0.0212937072, 0.0273213703, 0.0137434537, -0.0163306762, -0.0460679494, -0.0517779514, -0.0158989206, 0.0610049926, 0.1568012834, 0.2361188084, 0.2668529153, 0.2361188084, 0.1568012834, 0.0610049926, -0.0158989206, -0.0517779514, -0.0460679494, -0.0163306762, 0.0137434537, 0.0273213703, 0.0212937072, 0.0043936619, -0.0106990226, -0.0156021295, -0.0100410767, -0.0000000000, 0.0073990100, 0.0084543033, 0.0042453380, -0.0012682986, -0.0044305641, -0.0040468578, -0.0014255439, 0.0011608009, 0.0021802916, 0.0015688470, 0.0002916872, -0.0006225577, -0.0007690279, -0.0004004044, 0.0000000000, -0.0002865466, -0.0007061783, -0.0007301533, 0.0000000000, 0.0012655146, 0.0021531822, 0.0015902856, -0.0006930109, -0.0035140209, -0.0046504070, -0.0023760712, 0.0028179234, 0.0077659469, 0.0082917819, 0.0023244321, -0.0076489537, -0.0150320269, -0.0130334338, 0.0000000000, 0.0175880920, 0.0274658166, 0.0190560501, -0.0079859048, -0.0399552956, -0.0538004488, -0.0291201454, 0.0388129950, 0.1329296976, 0.2198168039, 0.2648645043, 0.2492838949, 0.1796266586, 0.0844482332, 0.0000000000, -0.0470616631, -0.0506484024, -0.0246923212, 0.0073266113, 0.0258895699, 0.0243004207, 0.0089245280, -0.0076841321, -0.0154854096, -0.0121481530, -0.0025086149, 0.0060840873, 0.0087987296, 0.0055934992, 0.0000000000, -0.0039757662, -0.0044350680, -0.0021646209, 0.0006253787, 0.0021000886, 0.0018304954, 0.0006095883, -0.0004634415, -0.0007985753, -0.0005134914, -0.0000817222, -0.0001785384, -0.0006181753, -0.0007875547, -0.0002543572, 0.0009396831, 0.0020312972, 0.0019043937, -0.0000000000, -0.0028736561, -0.0046453807, -0.0032867687, 0.0013811750, 0.0067905234, 0.0087544248, 0.0043758969, -0.0050970055, -0.0138489073, -0.0146346623, -0.0040770173, 0.0133932373, 0.0264140815, 0.0231295004, -0.0000000000, -0.0326977968, -0.0533337817, -0.0395234674, 0.0183441769, 0.1086134911, 0.2008173168, 0.2589540184, 0.2589540184, 0.2008173168, 0.1086134911, 0.0183441769, -0.0395234674, -0.0533337817, -0.0326977968, -0.0000000000, 0.0231295004, 0.0264140815, 0.0133932373, -0.0040770173, -0.0146346623, -0.0138489073, -0.0050970055, 0.0043758969, 0.0087544248, 0.0067905234, 0.0013811750, -0.0032867687, -0.0046453807, -0.0028736561, -0.0000000000, 0.0019043937, 0.0020312972, 0.0009396831, -0.0002543572, -0.0007875547, -0.0006181753, -0.0001785384, -0.0000817222, -0.0005134914, -0.0007985753, -0.0004634415, 0.0006095883, 0.0018304954, 0.0021000886, 0.0006253787, -0.0021646209, -0.0044350680, -0.0039757662, 0.0000000000, 0.0055934992, 0.0087987296, 0.0060840873, -0.0025086149, -0.0121481530, -0.0154854096, -0.0076841321, 0.0089245280, 0.0243004207, 0.0258895699, 0.0073266113, -0.0246923212, -0.0506484024, -0.0470616631, 0.0000000000, 0.0844482332, 0.1796266586, 0.2492838949, 0.2648645043, 0.2198168039, 0.1329296976, 0.0388129950, -0.0291201454, -0.0538004488, -0.0399552956, -0.0079859048, 0.0190560501, 0.0274658166, 0.0175880920, 0.0000000000, -0.0130334338, -0.0150320269, -0.0076489537, 0.0023244321, 0.0082917819, 0.0077659469, 0.0028179234, -0.0023760712, -0.0046504070, -0.0035140209, -0.0006930109, 0.0015902856, 0.0021531822, 0.0012655146, 0.0000000000, -0.0007301533, -0.0007061783, -0.0002865466 -}; - -const LC3_FLOAT lp_filter_96[240] = { --0.0000892692, -0.0002002022, -0.0003090877, -0.0003845139, -0.0003937774, -0.0003112789, -0.0001271786, 0.0001458436, 0.0004698416, 0.0007844235, 0.0010156486, 0.0010901458, 0.0009521968, 0.0005804005, -0.0000000000, -0.0007127720, -0.0014368281, -0.0020234289, -0.0023226903, -0.0022152821, -0.0016433843, -0.0006341493, 0.0006905875, 0.0021226690, 0.0033952617, 0.0042271516, 0.0043772124, 0.0036995050, 0.0021879484, -0.0000000000, -0.0025485028, -0.0050205383, -0.0069244537, -0.0078010648, -0.0073173312, -0.0053495113, -0.0020385087, 0.0021968309, 0.0066966186, 0.0106468536, 0.0132070407, 0.0136606852, 0.0115647502, 0.0068717268, -0.0000000000, -0.0081653381, -0.0163488984, -0.0230339747, -0.0266668908, -0.0258889757, -0.0197617337, -0.0079494603, 0.0091720885, 0.0305024963, 0.0543067455, 0.0784006417, 0.1004086584, 0.1180594042, 0.1294770092, 0.1334264576, 0.1294770092, 0.1180594042, 0.1004086584, 0.0784006417, 0.0543067455, 0.0305024963, 0.0091720885, -0.0079494603, -0.0197617337, -0.0258889757, -0.0266668908, -0.0230339747, -0.0163488984, -0.0081653381, -0.0000000000, 0.0068717268, 0.0115647502, 0.0136606852, 0.0132070407, 0.0106468536, 0.0066966186, 0.0021968309, -0.0020385087, -0.0053495113, -0.0073173312, -0.0078010648, -0.0069244537, -0.0050205383, -0.0025485028, -0.0000000000, 0.0021879484, 0.0036995050, 0.0043772124, 0.0042271516, 0.0033952617, 0.0021226690, 0.0006905875, -0.0006341493, -0.0016433843, -0.0022152821, -0.0023226903, -0.0020234289, -0.0014368281, -0.0007127720, -0.0000000000, 0.0005804005, 0.0009521968, 0.0010901458, 0.0010156486, 0.0007844235, 0.0004698416, 0.0001458436, -0.0001271786, -0.0003112789, -0.0003937774, -0.0003845139, -0.0003090877, -0.0002002022, -0.0000892692, 0.0000000000, -0.0000408611, -0.0001432733, -0.0002567457, -0.0003530891, -0.0003992876, -0.0003650767, -0.0002317207, 0.0000000000, 0.0003047941, 0.0006327573, 0.0009152477, 0.0010765911, 0.0010500443, 0.0007951428, 0.0003126893, -0.0003465054, -0.0010823105, -0.0017570105, -0.0022175340, -0.0023252035, -0.0019878831, -0.0011880356, 0.0000000000, 0.0014089617, 0.0027967496, 0.0038829735, 0.0043993648, 0.0041458909, 0.0030420437, 0.0011622161, -0.0012543075, -0.0038244769, -0.0060740765, -0.0075160135, -0.0077427048, -0.0065167169, -0.0038420660, 0.0000000000, 0.0044622640, 0.0087940460, 0.0121502103, 0.0137329083, 0.0129447849, 0.0095280251, 0.0036633057, -0.0039929524, -0.0123461606, -0.0199776478, -0.0253242012, -0.0269002244, -0.0235308316, -0.0145600727, 0.0000000000, 0.0194064975, 0.0422241166, 0.0664648488, 0.0898133293, 0.1099084020, 0.1246419474, 0.1324322522, 0.1324322522, 0.1246419474, 0.1099084020, 0.0898133293, 0.0664648488, 0.0422241166, 0.0194064975, 0.0000000000, -0.0145600727, -0.0235308316, -0.0269002244, -0.0253242012, -0.0199776478, -0.0123461606, -0.0039929524, 0.0036633057, 0.0095280251, 0.0129447849, 0.0137329083, 0.0121502103, 0.0087940460, 0.0044622640, 0.0000000000, -0.0038420660, -0.0065167169, -0.0077427048, -0.0075160135, -0.0060740765, -0.0038244769, -0.0012543075, 0.0011622161, 0.0030420437, 0.0041458909, 0.0043993648, 0.0038829735, 0.0027967496, 0.0014089617, 0.0000000000, -0.0011880356, -0.0019878831, -0.0023252035, -0.0022175340, -0.0017570105, -0.0010823105, -0.0003465054, 0.0003126893, 0.0007951428, 0.0010500443, 0.0010765911, 0.0009152477, 0.0006327573, 0.0003047941, 0.0000000000, -0.0002317207, -0.0003650767, -0.0003992876, -0.0003530891, -0.0002567457, -0.0001432733, -0.0000408611 -}; - -const LC3_FLOAT *lp_filter[] = {lp_filter_8, lp_filter_16, lp_filter_24, lp_filter_32, lp_filter_48, lp_filter_96}; - -const LC3_INT up_fac[6] = {24, 12, 8, 6, 4, 2}; - -/* TNS */ -const LC3_INT huff_bits_tns[8][17] = { +RAM_ALIGN const Word32 tnsAcfWindow_lc3plus[MAXLAG] = {0x7FBF61E2, 0x7EFE4B00, 0x7DBF01E8, 0x7C0544D0, + 0x79D636E9, 0x773846E0, 0x74330F61, 0x70CF3251}; +RAM_ALIGN const Word16 tnsQuantPts[TNS_COEF_RES] = {-32628, -31517, -29333, -26149, -22076, -17250, -11837, -6021, 0, + 6021, 11837, 17250, 22076, 26149, 29333, 31517, 32628}; +RAM_ALIGN const Word16 tnsQuantThr[TNS_COEF_RES - 1] = {-32210, -30555, -27860, -24216, -19747, -14606, -8967, -3023, + 3023, 8967, 14606, 19747, 24216, 27860, 30555, 32210}; + +RAM_ALIGN const Word16 ac_tns_order_bits[2][MAXLAG] = {{17234, 13988, 11216, 8694, 6566, 4977, 3961, 3040}, + {12683, 9437, 6874, 5541, 5121, 5170, 5359, 5056}}; +RAM_ALIGN const Word16 ac_tns_order_freq[2][MAXLAG] = {{3, 9, 23, 54, 111, 190, 268, 366}, + {14, 42, 100, 157, 181, 178, 167, 185}}; +RAM_ALIGN const Word16 ac_tns_order_cumfreq[2][MAXLAG] = {{0, 3, 12, 35, 89, 200, 390, 658}, + {0, 14, 56, 156, 313, 494, 672, 839}}; +RAM_ALIGN const Word16 ac_tns_coef_bits[MAXLAG][TNS_COEF_RES] = { {20480, 15725, 12479, 10334, 8694, 7320, 6964, 6335, 5504, 5637, 6566, 6758, 8433, 11348, 15186, 20480, 20480}, {20480, 20480, 20480, 20480, 12902, 9368, 7057, 5901, 5254, 5485, 5598, 6076, 7608, 10742, 15186, 20480, 20480}, {20480, 20480, 20480, 20480, 13988, 9368, 6702, 4841, 4585, 4682, 5859, 7764, 12109, 20480, 20480, 20480, 20480}, @@ -613,5724 +3466,1581 @@ const LC3_INT huff_bits_tns[8][17] = { 20480}, {20480, 20480, 20480, 20480, 20480, 20480, 15725, 3658, 20480, 1201, 10854, 18432, 20480, 20480, 20480, 20480, 20480}}; +RAM_ALIGN const Word16 ac_tns_coef_freq[MAXLAG][TNS_COEF_RES] = { + {1, 5, 15, 31, 54, 86, 97, 120, 159, 152, 111, 104, 59, 22, 6, 1, 1}, + {1, 1, 1, 1, 13, 43, 94, 139, 173, 160, 154, 131, 78, 27, 6, 1, 1}, + {1, 1, 1, 1, 9, 43, 106, 199, 217, 210, 141, 74, 17, 1, 1, 1, 1}, + {1, 1, 1, 1, 2, 11, 49, 204, 285, 297, 120, 39, 9, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 7, 42, 241, 341, 314, 58, 9, 3, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 13, 205, 366, 377, 47, 5, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 13, 281, 330, 371, 17, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 5, 297, 1, 682, 26, 2, 1, 1, 1, 1, 1}}; +RAM_ALIGN const Word16 ac_tns_coef_cumfreq[MAXLAG][TNS_COEF_RES] = { + {0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023}, + {0, 1, 2, 3, 4, 17, 60, 154, 293, 466, 626, 780, 911, 989, 1016, 1022, 1023}, + {0, 1, 2, 3, 4, 13, 56, 162, 361, 578, 788, 929, 1003, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 6, 17, 66, 270, 555, 852, 972, 1011, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 5, 12, 54, 295, 636, 950, 1008, 1017, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 5, 6, 19, 224, 590, 967, 1014, 1019, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 5, 6, 19, 300, 630, 1001, 1018, 1019, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 5, 6, 11, 308, 309, 991, 1017, 1019, 1020, 1021, 1022, 1023}}; + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_8000[64] = { + 0x4000, 0x435c, 0x46e5, 0x4a9e, 0x4e89, 0x52a9, 0x5700, 0x5b91, 0x6060, 0x656f, 0x6ac2, 0x705d, 0x7643, + 0x7c79, 0x4181, 0x44f1, 0x4890, 0x4c5f, 0x5061, 0x549a, 0x590b, 0x5db7, 0x62a3, 0x67d1, 0x6d44, 0x7301, + 0x790a, 0x7f65, 0x430b, 0x4690, 0x4a44, 0x4e2a, 0x5245, 0x5696, 0x5b22, 0x5feb, 0x64f4, 0x6a41, 0x6fd5, + 0x75b4, 0x7be2, 0x4131, 0x449e, 0x4838, 0x4c02, 0x5000, 0x5433, 0x589f, 0x5d46, 0x622c, 0x6753, 0x6cc0, + 0x7275, 0x7878, 0x7ecb, 0x42b9, 0x463a, 0x49ea, 0x4dcb, 0x51e1, 0x562d, 0x5ab4, 0x5f77, 0x647a}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_8000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}; +#else +#define lpc_warp_pre_emphasis_64_8000 NULL +#define lpc_warp_pre_emphasis_64_e_8000 NULL +#endif -const LC3_INT order1_tns[8] = {17234, 13988, 11216, 8694, 6566, 4977, 3961, 3040}; -const LC3_INT order2_tns[8] = {12683, 9437, 6874, 5541, 5121, 5170, 5359, 5056}; - -const LC3_FLOAT lagw_tns[9] = {1, - 0.998028026020383, - 0.992135405511397, - 0.982391584470799, - 0.968910791191297, - 0.951849807369274, - 0.931404933402306, - 0.907808229996959, - 0.881323136669471}; - -const LC3_FLOAT quants_pts_tns[17] = { -0.995727539062500, -0.961822509765625, -0.895172119140625, - -0.798004150390625, -0.673706054687500, -0.526428222656250, - -0.361236572265625, -0.183746337890625, 0.000000000000000, - 0.183746337890625, 0.361236572265625, 0.526428222656250, - 0.673706054687500, 0.798004150390625, 0.895172119140625, - 0.961822509765625, 0.995727539062500}; - -const LC3_FLOAT quants_thr_tns[18] = {-1, - -0.982973099683902, - -0.932472229404356, - -0.850217135729614, - -0.739008917220659, - -0.602634636379256, - -0.445738355776538, - -0.273662990072083, - -0.0922683594633020, - 0.0922683594633020, - 0.273662990072083, - 0.445738355776538, - 0.602634636379256, - 0.739008917220659, - 0.850217135729614, - 0.932472229404356, - 0.982973099683902, - 1}; - -/* SNS */ -const LC3_FLOAT sns_W[6] = {0.0833333333333333, 0.166666666666667, 0.250000000000000, 0.250000000000000, 0.166666666666667, 0.0833333333333333}; - -const LC3_FLOAT sns_preemph_8[64] = {1, 1.05250028527773, 1.10775685050971, 1.16591440117983, 1.22712523985119, 1.29154966501488, 1.35935639087853, 1.43072298919376, 1.50583635427984, 1.58489319246111, 1.66810053720006, 1.75567629127500, 1.84784979742229, 1.94486243893736, 2.04696827180752, 2.15443469003188, 2.26754312587080, 2.38658978685858, 2.51188643150958, 2.64376118574910, 2.78255940220713, 2.92864456462524, 3.08239923974514, 3.24422607917163, 3.41454887383360, 3.59381366380463, 3.78248990638938, 3.98107170553497, 4.19007910578667, 4.41005945417674, 4.64158883361278, 4.88527357151939, 5.14175182768393, 5.41169526546464, 5.69581081073769, 5.99484250318941, 6.30957344480193, 6.64082785063484, 6.98947320727349, 7.35642254459641, 7.74263682681127, 8.14912746902074, 8.57695898590894, 9.02725177948457, 9.50118507318144, 10, 10.5250028527773, 11.0775685050971, 11.6591440117983, 12.2712523985119, 12.9154966501488, 13.5935639087853, 14.3072298919376, 15.0583635427984, 15.8489319246111, 16.6810053720006, 17.5567629127500, 18.4784979742229, 19.4486243893736, 20.4696827180752, 21.5443469003188, 22.6754312587080, 23.8658978685858, 25.1188643150958}; - -const LC3_FLOAT sns_preemph_16[64] = {1, 1.06800043251458, 1.14062492385132, 1.21818791201012, 1.30102521691083, 1.38949549437314, 1.48398178896757, 1.58489319246111, 1.69266661503788, 1.80776867696343, 1.93069772888325, 2.06198600950222, 2.20220194998738, 2.35195263507096, 2.51188643150958, 2.68269579527973, 2.86512026966378, 3.05994968720720, 3.26802758941013, 3.49025487895958, 3.72759372031494, 3.98107170553497, 4.25178630338289, 4.54090961097248, 4.84969342852820, 5.17947467923121, 5.53168119761723, 5.90783791158795, 6.30957344480193, 6.73862716803095, 7.19685673001152, 7.68624610039774, 8.20891415963826, 8.76712387296868, 9.36329208823941, 10, 10.6800043251458, 11.4062492385132, 12.1818791201012, 13.0102521691083, 13.8949549437314, 14.8398178896756, 15.8489319246111, 16.9266661503788, 18.0776867696343, 19.3069772888325, 20.6198600950222, 22.0220194998738, 23.5195263507096, 25.1188643150958, 26.8269579527973, 28.6512026966378, 30.5994968720720, 32.6802758941013, 34.9025487895958, 37.2759372031494, 39.8107170553497, 42.5178630338289, 45.4090961097248, 48.4969342852820, 51.7947467923121, 55.3168119761723, 59.0783791158795, 63.0957344480193}; - -const LC3_FLOAT sns_preemph_24[64] = {1, 1.08372885005949, 1.17446822045126, 1.27280509398106, 1.37937560084995, 1.49486913370923, 1.62003280726413, 1.75567629127500, 1.90267704822016, 2.06198600950222, 2.23463372691659, 2.42173703917547, 2.62450629661210, 2.84425319080132, 3.08239923974514, 3.34048498351325, 3.62017994982380, 3.92329345403096, 4.25178630338289, 4.60778348126382, 4.99358789347315, 5.41169526546464, 5.86481028691437, 6.35586410805477, 6.88803330095657, 7.46476040841712, 8.08977621338348, 8.76712387296868, 9.50118507318144, 10.2967083735613, 11.1588399250775, 12.0931567600021, 13.1057028691062, 14.2030282995578, 15.3922315264422, 16.6810053720006, 18.0776867696343, 19.5913106945915, 21.2316686102078, 23.0093718077846, 24.9359200498416, 27.0237759607902, 29.2864456462524, 31.7385660625428, 34.3959997014966, 37.2759372031494, 40.3970085600588, 43.7794036326358, 47.4450027550866, 51.4175182768393, 55.7226479550717, 60.3882411906196, 65.4444791826252, 70.9240701673285, 76.8624610039774, 83.2980664765827, 90.2725177948458, 97.8309319017829, 106.022203330167, 114.899320495775, 124.519708473503, 134.945600473732, 146.244440421985, 158.489319246111}; - -const LC3_FLOAT sns_preemph_32[64] = {1, 1.09968889964399, 1.20931567600021, 1.32987102506290, 1.46244440421985, 1.60823387766704, 1.76855694330186, 1.94486243893736, 2.13874363543396, 2.35195263507096, 2.58641620527597, 2.84425319080132, 3.12779366170121, 3.43959997014966, 3.78248990638938, 4.15956216307185, 4.57422433810926, 5.03022372910014, 5.53168119761723, 6.08312840938905, 6.68954878691415, 7.35642254459641, 8.08977621338348, 8.89623710246182, 9.78309319017829, 10.7583589854218, 11.8308479546535, 13.0102521691083, 14.3072298919376, 15.7335018968185, 17.3019573884589, 19.0267704822017, 20.9235282953511, 23.0093718077846, 25.3031507648021, 27.8255940220712, 30.5994968720720, 33.6499270449086, 37.0044512451161, 40.6933842716715, 44.7500629725045, 49.2111475092328, 54.1169526546464, 59.5118121168741, 65.4444791826252, 71.9685673001152, 79.1430345832182, 87.0327166153056, 95.7089123677128, 105.250028527773, 115.742288059206, 127.280509398106, 139.968963326130, 153.922315264422, 169.266661503788, 186.140668735512, 204.696827180752, 225.102828643018, 247.543081937190, 272.220379389991, 299.357729472049, 329.200372123041, 362.017994982380, 398.107170553497}; - -const LC3_FLOAT sns_preemph_48[64] = {1, 1.11588399250775, 1.24519708473503, 1.38949549437314, 1.55051577983262, 1.73019573884589, 1.93069772888325, 2.15443469003188, 2.40409918350997, 2.68269579527973, 2.99357729472049, 3.34048498351325, 3.72759372031494, 4.15956216307185, 4.64158883361278, 5.17947467923121, 5.77969288415331, 6.44946677103762, 7.19685673001152, 8.03085722139151, 8.96150501946605, 10, 11.1588399250775, 12.4519708473503, 13.8949549437314, 15.5051577983262, 17.3019573884589, 19.3069772888325, 21.5443469003188, 24.0409918350997, 26.8269579527973, 29.9357729472049, 33.4048498351324, 37.2759372031494, 41.5956216307185, 46.4158883361278, 51.7947467923121, 57.7969288415332, 64.4946677103762, 71.9685673001152, 80.3085722139151, 89.6150501946605, 100, 111.588399250775, 124.519708473503, 138.949549437314, 155.051577983263, 173.019573884589, 193.069772888325, 215.443469003188, 240.409918350997, 268.269579527972, 299.357729472049, 334.048498351324, 372.759372031494, 415.956216307185, 464.158883361278, 517.947467923121, 577.969288415331, 644.946677103762, 719.685673001152, 803.085722139151, 896.150501946605, 1000}; - -const LC3_FLOAT sns_preemph_96[64] = {1, 1.13231759012767, 1.28214312491253, 1.45179321339972, 1.64389099276047, 1.86140668735512, 2.10770353447348, 2.38658978685858, 2.70237759607902, 3.05994968720720, 3.46483485573037, 3.92329345403096, 4.44241418923200, 5.03022372910014, 5.69581081073769, 6.44946677103762, 7.30284467178980, 8.26913947983772, 9.36329208823941, 10.6022203330167, 12.0050805774841, 13.5935639087853, 15.3922315264422, 17.4288945087081, 19.7350438286898, 22.3463372691659, 25.3031507648021, 28.6512026966378, 32.4422607917163, 36.7349425579696, 41.5956216307185, 47.0994540447575, 53.3315403002887, 60.3882411906196, 68.3786677370108, 77.4263682681127, 87.6712387296868, 99.2716857619066, 112.407075989833, 127.280509398106, 144.121959671886, 163.191830060146, 184.784979742229, 209.235282953511, 236.920791363601, 268.269579527972, 303.766363795677, 343.959997014966, 389.471954920307, 441.005945417674, 499.358789347315, 565.432740962822, 640.249438626305, 724.965701425931, 820.891415963825, 929.509789880649, 1052.50028527773, 1191.76458663437, 1349.45600473732, 1528.01277126748, 1730.19573884589, 1959.13106945914, 2218.35857131422, 2511.88643150958}; - -const LC3_FLOAT *sns_preemph_all[6] = {sns_preemph_8, sns_preemph_16, sns_preemph_24, sns_preemph_32, sns_preemph_48, sns_preemph_96}; - -const LC3_FLOAT sns_vq_far_adj_gains_fl[8] = {1.05859375000000, 1.23706054687500, 1.43920898437500, 1.98950195312500, - 2.49877929687500, 3.13110351562500, 4.11816406250000, 4.85400390625000}; - -const LC3_FLOAT sns_vq_near_adj_gains_fl[4] = {1.73315429687500, 2.22949218750000, 2.74731445312500, 3.61523437500000}; - -const LC3_FLOAT sns_vq_reg_lf_adj_gains_fl[4] = {1.52465820312500, 3.67260742187500, 4.36059570312500, - 5.13037109375000}; - -const LC3_FLOAT q_g_sns[6] = {2.17651367187500, 2.94287109375000, 1.52465820312500, - 3.67260742187500, 4.36059570312500, 5.13037109375000}; - -const LC3_FLOAT sns_vq_reg_adj_gains_fl[2] = {2.17651367187500, 2.94287109375000}; - -/* First element in each row is multiplied with norm2 = 1 / sqrt(2) */ -const LC3_FLOAT idct_lookup[M][M] = { - {0.707106781186547, 0.995184726672197, 0.980785280403230, 0.956940335732209, 0.923879532511287, 0.881921264348355, 0.831469612302545, 0.773010453362737, 0.707106781186548, 0.634393284163646, 0.555570233019602, 0.471396736825998, 0.382683432365090, 0.290284677254462, 0.195090322016128, 0.0980171403295608}, - {0.707106781186547, 0.956940335732209, 0.831469612302545, 0.634393284163646, 0.382683432365090, 0.0980171403295608, -0.195090322016128, -0.471396736825998, -0.707106781186548, -0.881921264348355, -0.980785280403230, -0.995184726672197, -0.923879532511287, -0.773010453362737, -0.555570233019602, -0.290284677254462}, - {0.707106781186547, 0.881921264348355, 0.555570233019602, 0.0980171403295608, -0.382683432365090, -0.773010453362737, -0.980785280403230, -0.956940335732209, -0.707106781186548, -0.290284677254462, 0.195090322016128, 0.634393284163646, 0.923879532511287, 0.995184726672197, 0.831469612302546, 0.471396736825998}, - {0.707106781186547, 0.773010453362737, 0.195090322016128, -0.471396736825998, -0.923879532511287, -0.956940335732209, -0.555570233019602, 0.0980171403295601, 0.707106781186547, 0.995184726672197, 0.831469612302546, 0.290284677254463, -0.382683432365090, -0.881921264348355, -0.980785280403231, -0.634393284163645}, - {0.707106781186547, 0.634393284163646, -0.195090322016128, -0.881921264348355, -0.923879532511287, -0.290284677254462, 0.555570233019602, 0.995184726672197, 0.707106781186548, -0.0980171403295600, -0.831469612302545, -0.956940335732209, -0.382683432365091, 0.471396736825997, 0.980785280403230, 0.773010453362738}, - {0.707106781186547, 0.471396736825998, -0.555570233019602, -0.995184726672197, -0.382683432365090, 0.634393284163645, 0.980785280403231, 0.290284677254463, -0.707106781186547, -0.956940335732209, -0.195090322016130, 0.773010453362736, 0.923879532511287, 0.0980171403295626, -0.831469612302544, -0.881921264348356}, - {0.707106781186547, 0.290284677254462, -0.831469612302545, -0.773010453362737, 0.382683432365090, 0.995184726672197, 0.195090322016128, -0.881921264348356, -0.707106781186547, 0.471396736825997, 0.980785280403230, 0.0980171403295591, -0.923879532511287, -0.634393284163646, 0.555570233019604, 0.956940335732208}, - {0.707106781186547, 0.0980171403295608, -0.980785280403230, -0.290284677254463, 0.923879532511287, 0.471396736825998, -0.831469612302544, -0.634393284163647, 0.707106781186547, 0.773010453362738, -0.555570233019602, -0.881921264348356, 0.382683432365086, 0.956940335732209, -0.195090322016125, -0.995184726672197}, - {0.707106781186547, -0.0980171403295607, -0.980785280403230, 0.290284677254463, 0.923879532511287, -0.471396736825998, -0.831469612302545, 0.634393284163646, 0.707106781186547, -0.773010453362737, -0.555570233019603, 0.881921264348356, 0.382683432365088, -0.956940335732209, -0.195090322016127, 0.995184726672197}, - {0.707106781186547, -0.290284677254462, -0.831469612302546, 0.773010453362737, 0.382683432365090, -0.995184726672197, 0.195090322016127, 0.881921264348356, -0.707106781186547, -0.471396736825998, 0.980785280403230, -0.0980171403295577, -0.923879532511288, 0.634393284163644, 0.555570233019606, -0.956940335732208}, - {0.707106781186547, -0.471396736825998, -0.555570233019602, 0.995184726672197, -0.382683432365090, -0.634393284163645, 0.980785280403230, -0.290284677254463, -0.707106781186547, 0.956940335732209, -0.195090322016129, -0.773010453362737, 0.923879532511287, -0.0980171403295610, -0.831469612302545, 0.881921264348355}, - {0.707106781186547, -0.634393284163645, -0.195090322016129, 0.881921264348355, -0.923879532511286, 0.290284677254461, 0.555570233019603, -0.995184726672197, 0.707106781186547, 0.0980171403295628, -0.831469612302547, 0.956940335732208, -0.382683432365089, -0.471396736825999, 0.980785280403231, -0.773010453362733}, - {0.707106781186547, -0.773010453362737, 0.195090322016128, 0.471396736825998, -0.923879532511287, 0.956940335732209, -0.555570233019602, -0.0980171403295592, 0.707106781186548, -0.995184726672197, 0.831469612302546, -0.290284677254462, -0.382683432365091, 0.881921264348355, -0.980785280403231, 0.634393284163644}, - {0.707106781186547, -0.881921264348355, 0.555570233019602, -0.0980171403295600, -0.382683432365091, 0.773010453362738, -0.980785280403231, 0.956940335732208, -0.707106781186546, 0.290284677254462, 0.195090322016130, -0.634393284163649, 0.923879532511288, -0.995184726672197, 0.831469612302542, -0.471396736825993}, - {0.707106781186547, -0.956940335732209, 0.831469612302545, -0.634393284163645, 0.382683432365090, -0.0980171403295615, -0.195090322016130, 0.471396736825998, -0.707106781186548, 0.881921264348355, -0.980785280403230, 0.995184726672197, -0.923879532511285, 0.773010453362735, -0.555570233019601, 0.290284677254462}, - {0.707106781186547, -0.995184726672197, 0.980785280403230, -0.956940335732209, 0.923879532511286, -0.881921264348355, 0.831469612302544, -0.773010453362736, 0.707106781186546, -0.634393284163644, 0.555570233019601, -0.471396736825994, 0.382683432365086, -0.290284677254458, 0.195090322016124, -0.0980171403295567} -}; +#ifdef SUBSET_WB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_16000[64] = { + 0x4000, 0x445a, 0x4900, 0x4df7, 0x5344, 0x58ed, 0x5efa, 0x656f, 0x6c55, 0x73b2, 0x7b91, 0x41fc, 0x4678, + 0x4b43, 0x5061, 0x55d9, 0x5baf, 0x61eb, 0x6894, 0x6fb0, 0x7748, 0x7f65, 0x4407, 0x48a8, 0x4d98, 0x52df, + 0x5882, 0x5e87, 0x64f4, 0x6bd1, 0x7326, 0x7afb, 0x41ac, 0x4623, 0x4ae8, 0x5000, 0x5571, 0x5b40, 0x6174, + 0x6815, 0x6f29, 0x76b8, 0x7ecb, 0x43b5, 0x4850, 0x4d3a, 0x527b, 0x5817, 0x5e14, 0x647a, 0x6b4f, 0x729b, + 0x7a66, 0x415c, 0x45ce, 0x4a8d, 0x4f9f, 0x5509, 0x5ad1, 0x60fe, 0x6797, 0x6ea2, 0x7628, 0x7e31}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_16000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}; +#else +#define lpc_warp_pre_emphasis_64_16000 NULL +#define lpc_warp_pre_emphasis_64_e_16000 NULL +#endif -const LC3_FLOAT sns_dec_gains[4][8] = { - {2.17651367187500, 2.94287109375000, 0, 0, 0, 0, 0, 0}, - {1.52465820312500, 3.67260742187500, 4.36059570312500, 5.13037109375000, 0, 0, 0, 0}, - {1.73315429687500, 2.22949218750000, 2.74731445312500, 3.61523437500000, 0, 0, 0, 0}, - {1.05859375000000, 1.23706054687500, 1.43920898437500, 1.98950195312500, 2.49877929687500, 3.13110351562500, - 4.11816406250000, 4.85400390625000}}; - -/* Global Gain */ -const LC3_INT gg_p1[6] = {80, 230, 380, 530, 680, 830}; -const LC3_INT gg_p2[6] = {500, 1025, 1550, 2075, 2600, 3125}; -const LC3_INT gg_p3[6] = {850, 1700, 2550, 3400, 4250, 5100}; - -const LC3_FLOAT gg_c[6] = {0.00575396825396825, 0.00500524109014675, 0.00473646723646723, - 0.00459816612729234, 0.00451388888888889, 0.004457153231663}; -const LC3_FLOAT gg_d[6] = {1310.34482758621, 3241.36125654450, 5267.66917293233, - 7326.39296187684, 9400.00000000000, 11481.67006109979}; - -/* Olpa */ -const LC3_FLOAT olpa_down2[5] = {0.1236796411180537, 0.2353512128364889, 0.2819382920909148, 0.2353512128364889, - 0.1236796411180537}; - -const LC3_FLOAT olpa_acw[98] = {1.0, - 0.994845360824742, - 0.989690721649485, - 0.984536082474227, - 0.979381443298969, - 0.974226804123711, - 0.969072164948454, - 0.963917525773196, - 0.958762886597938, - 0.953608247422680, - 0.948453608247423, - 0.943298969072165, - 0.938144329896907, - 0.932989690721650, - 0.927835051546392, - 0.922680412371134, - 0.917525773195876, - 0.912371134020619, - 0.907216494845361, - 0.902061855670103, - 0.896907216494845, - 0.891752577319588, - 0.886597938144330, - 0.881443298969072, - 0.876288659793814, - 0.871134020618557, - 0.865979381443299, - 0.860824742268041, - 0.855670103092784, - 0.850515463917526, - 0.845360824742268, - 0.840206185567010, - 0.835051546391753, - 0.829896907216495, - 0.824742268041237, - 0.819587628865979, - 0.814432989690722, - 0.809278350515464, - 0.804123711340206, - 0.798969072164949, - 0.793814432989691, - 0.788659793814433, - 0.783505154639175, - 0.778350515463918, - 0.773195876288660, - 0.768041237113402, - 0.762886597938144, - 0.757731958762887, - 0.752577319587629, - 0.747422680412371, - 0.742268041237113, - 0.737113402061856, - 0.731958762886598, - 0.726804123711340, - 0.721649484536083, - 0.716494845360825, - 0.711340206185567, - 0.706185567010309, - 0.701030927835052, - 0.695876288659794, - 0.690721649484536, - 0.685567010309278, - 0.680412371134021, - 0.675257731958763, - 0.670103092783505, - 0.664948453608247, - 0.659793814432990, - 0.654639175257732, - 0.649484536082474, - 0.644329896907216, - 0.639175257731959, - 0.634020618556701, - 0.628865979381443, - 0.623711340206186, - 0.618556701030928, - 0.613402061855670, - 0.608247422680412, - 0.603092783505155, - 0.597938144329897, - 0.592783505154639, - 0.587628865979382, - 0.582474226804124, - 0.577319587628866, - 0.572164948453608, - 0.567010309278351, - 0.561855670103093, - 0.556701030927835, - 0.551546391752577, - 0.546391752577320, - 0.541237113402062, - 0.536082474226804, - 0.530927835051546, - 0.525773195876289, - 0.520618556701031, - 0.515463917525773, - 0.510309278350515, - 0.505154639175258, - 0.500000000000000}; - -/* LTPF */ -const LC3_FLOAT conf_tilt_filter_16[4][3] = {{6.023618207009578e-01, 4.197609261363617e-01, -1.883424527883687e-02}, - {5.994768582584314e-01, 4.197609261363620e-01, -1.594928283631041e-02}, - {5.967764663733787e-01, 4.197609261363617e-01, -1.324889095125780e-02}, - {5.942410120098895e-01, 4.197609261363618e-01, -1.071343658776831e-02}}; - -const LC3_FLOAT conf_tilt_filter_24[4][5] = {{3.989695588963494e-01, 5.142508607708275e-01, 1.004382966157454e-01, - -1.278893956818042e-02, -1.572280075461383e-03}, - {3.948634911286333e-01, 5.123819208048688e-01, 1.043194926386267e-01, - -1.091999960222166e-02, -1.347408330627317e-03}, - {3.909844475885914e-01, 5.106053522688359e-01, 1.079832524685944e-01, - -9.143431066188848e-03, -1.132124620551895e-03}, - {3.873093888199928e-01, 5.089122083363975e-01, 1.114517380217371e-01, - -7.450287133750717e-03, -9.255514050963111e-04}}; - -const LC3_FLOAT conf_tilt_filter_32[4][7] = { - {2.982379446702096e-01, 4.652809203721290e-01, 2.105997428614279e-01, 3.766780380806063e-02, -1.015696155796564e-02, - -2.535880996101096e-03, -3.182946168719958e-04}, - {2.943834154510240e-01, 4.619294002718798e-01, 2.129465770091844e-01, 4.066175002688857e-02, -8.693272297010050e-03, - -2.178307114679820e-03, -2.742888063983188e-04}, - {2.907439213122688e-01, 4.587461910960279e-01, 2.151456974108970e-01, 4.350104772529774e-02, -7.295495347716925e-03, - -1.834395637237086e-03, -2.316920186482416e-04}, - {2.872975852589158e-01, 4.557148886861379e-01, 2.172126950911401e-01, 4.620088878229615e-02, -5.957463802125952e-03, - -1.502934284345198e-03, -1.903851911308866e-04}}; - -const LC3_FLOAT conf_tilt_filter_48[4][11] = { - {1.981363739883217e-01, 3.524494903964904e-01, 2.513695269649414e-01, 1.424146237314458e-01, 5.704731023952599e-02, - 9.293366241586384e-03, -7.226025368953745e-03, -3.172679890356356e-03, -1.121835963567014e-03, - -2.902957238400140e-04, -4.270815593769240e-05}, - {1.950709426598375e-01, 3.484660408341632e-01, 2.509988459466574e-01, 1.441167412482088e-01, 5.928947317677285e-02, - 1.108923827452231e-02, -6.192908108653504e-03, -2.726705509251737e-03, -9.667125826217151e-04, - -2.508100923165204e-04, -3.699938766131869e-05}, - {1.921810055196015e-01, 3.446945561091513e-01, 2.506220094626024e-01, 1.457102447664837e-01, 6.141132133664525e-02, - 1.279941396562798e-02, -5.203721087886321e-03, -2.297324511109085e-03, -8.165608133217555e-04, - -2.123855748277408e-04, -3.141271330981649e-05}, - {1.894485314175868e-01, 3.411139251108252e-01, 2.502406876894361e-01, 1.472065631098081e-01, 6.342477229539051e-02, - 1.443203434150312e-02, -4.254449144657098e-03, -1.883081472613493e-03, -6.709619060722140e-04, - -1.749363341966872e-04, -2.593864735284285e-05}}; - -const LC3_FLOAT conf_inter_filter_16[4][4] = { - {2.098804630681809e-01, 5.835275754221211e-01, 2.098804630681809e-01, 0.000000000000000e+00}, - {1.069991860896389e-01, 5.500750019177116e-01, 3.356906254147840e-01, 6.698858366939680e-03}, - {3.967114782344967e-02, 4.592209296082350e-01, 4.592209296082350e-01, 3.967114782344967e-02}, - {6.698858366939680e-03, 3.356906254147840e-01, 5.500750019177116e-01, 1.069991860896389e-01}}; - -const LC3_FLOAT conf_inter_filter_24[4][6] = {{6.322231627323796e-02, 2.507309606013235e-01, 3.713909428901578e-01, - 2.507309606013235e-01, 6.322231627323796e-02, 0.000000000000000e+00}, - {3.459272174099855e-02, 1.986515602645028e-01, 3.626411726581452e-01, - 2.986750548992179e-01, 1.013092873505928e-01, 4.263543712369752e-03}, - {1.535746784963907e-02, 1.474344878058222e-01, 3.374259553990717e-01, - 3.374259553990717e-01, 1.474344878058222e-01, 1.535746784963907e-02}, - {4.263543712369752e-03, 1.013092873505928e-01, 2.986750548992179e-01, - 3.626411726581452e-01, 1.986515602645028e-01, 3.459272174099855e-02}}; - -const LC3_FLOAT conf_inter_filter_32[4][8] = { - {2.900401878228730e-02, 1.129857420560927e-01, 2.212024028097570e-01, 2.723909472446145e-01, 2.212024028097570e-01, - 1.129857420560927e-01, 2.900401878228730e-02, 0.000000000000000e+00}, - {1.703153418385261e-02, 8.722503785537784e-02, 1.961407762232199e-01, 2.689237982237257e-01, 2.424999102756389e-01, - 1.405773364650031e-01, 4.474877169485788e-02, 3.127030243100724e-03}, - {8.563673748488349e-03, 6.426222944493845e-02, 1.687676705918012e-01, 2.587445937795505e-01, 2.587445937795505e-01, - 1.687676705918012e-01, 6.426222944493845e-02, 8.563673748488349e-03}, - {3.127030243100724e-03, 4.474877169485788e-02, 1.405773364650031e-01, 2.424999102756389e-01, 2.689237982237257e-01, - 1.961407762232199e-01, 8.722503785537784e-02, 1.703153418385261e-02}}; - -const LC3_FLOAT conf_inter_filter_48[4][12] = { - {1.082359386659387e-02, 3.608969221303979e-02, 7.676401468099964e-02, 1.241530577501703e-01, 1.627596438300696e-01, - 1.776771417779109e-01, 1.627596438300696e-01, 1.241530577501703e-01, 7.676401468099964e-02, 3.608969221303979e-02, - 1.082359386659387e-02, 0.000000000000000e+00}, - {7.041404930459358e-03, 2.819702319820420e-02, 6.547044935127551e-02, 1.124647986743299e-01, 1.548418956489015e-01, - 1.767122381341857e-01, 1.691507213057663e-01, 1.352901577989766e-01, 8.851425011427483e-02, 4.499353848562444e-02, - 1.557613714732002e-02, 2.039721956502016e-03}, - {4.146998467444788e-03, 2.135757310741917e-02, 5.482735584552816e-02, 1.004971444643720e-01, 1.456060342830002e-01, - 1.738439838565869e-01, 1.738439838565869e-01, 1.456060342830002e-01, 1.004971444643720e-01, 5.482735584552816e-02, - 2.135757310741917e-02, 4.146998467444788e-03}, - {2.039721956502016e-03, 1.557613714732002e-02, 4.499353848562444e-02, 8.851425011427483e-02, 1.352901577989766e-01, - 1.691507213057663e-01, 1.767122381341857e-01, 1.548418956489015e-01, 1.124647986743299e-01, 6.547044935127551e-02, - 2.819702319820420e-02, 7.041404930459358e-03}}; - -const LC3_FLOAT inter4_1[33] = {0, - -2.874561161519444e-03, - -3.001251025861499e-03, - +2.745471654059321e-03, - +1.535727698935322e-02, - +2.868234046665657e-02, - +2.950385026557377e-02, - +4.598334491135473e-03, - -4.729632459043440e-02, - -1.058359163062837e-01, - -1.303050213607112e-01, - -7.544046357555201e-02, - +8.357885725250529e-02, - +3.301825710764459e-01, - +6.032970076366158e-01, - +8.174886856243178e-01, - +8.986382851273982e-01, - +8.174886856243178e-01, - +6.032970076366158e-01, - +3.301825710764459e-01, - +8.357885725250529e-02, - -7.544046357555201e-02, - -1.303050213607112e-01, - -1.058359163062837e-01, - -4.729632459043440e-02, - +4.598334491135473e-03, - +2.950385026557377e-02, - +2.868234046665657e-02, - +1.535727698935322e-02, - +2.745471654059321e-03, - -3.001251025861499e-03, - -2.874561161519444e-03, - 0}; - -const LC3_FLOAT enc_inter_filter[4][4] = { - {+2.098804630681809e-01, +5.835275754221211e-01, +2.098804630681809e-01, 0}, - {+1.069991860896389e-01, +5.500750019177116e-01, +3.356906254147840e-01, +6.698858366939680e-03}, - {+3.967114782344967e-02, +4.592209296082350e-01, +4.592209296082350e-01, +3.967114782344967e-02}, - {+6.698858366939680e-03, +3.356906254147840e-01, +5.500750019177116e-01, +1.069991860896389e-01}}; - -/* Bandwidth Detector */ -const LC3_INT threshold_quiet[4] = {20, 10, 10, 10}; -const LC3_INT threshold_brickwall[4] = {15, 23, 20, 20}; -const LC3_INT brickwall_dist[4] = {4, 4, 3, 1}; -const LC3_INT BW_warp_idx_start_16k[4] = {53, 0, 0, 0}; -const LC3_INT BW_warp_idx_stop_16k[4] = {63, 0, 0, 0}; -const LC3_INT BW_warp_idx_start_24k[4] = {47, 59, 0, 0}; -const LC3_INT BW_warp_idx_stop_24k[4] = {56, 63, 0, 0}; -const LC3_INT BW_warp_idx_start_32k[4] = {44, 54, 60, 0}; -const LC3_INT BW_warp_idx_stop_32k[4] = {52, 59, 63, 0}; -const LC3_INT BW_warp_idx_start_48k[4] = {41, 51, 57, 61}; -const LC3_INT BW_warp_idx_stop_48k[4] = {49, 55, 60, 63}; -const LC3_INT* BW_warp_idx_start_all[4] = {BW_warp_idx_start_16k, BW_warp_idx_start_24k, BW_warp_idx_start_32k, - BW_warp_idx_start_48k}; -const LC3_INT* BW_warp_idx_stop_all[4] = {BW_warp_idx_stop_16k, BW_warp_idx_stop_24k, BW_warp_idx_stop_32k, - BW_warp_idx_stop_48k}; - -const LC3_INT BW_warp_idx_start_16k_2_5ms[4] = {24, 0, 0, 0}; -const LC3_INT BW_warp_idx_stop_16k_2_5ms[4] = {34, 0, 0, 0}; -const LC3_INT BW_warp_idx_start_24k_2_5ms[4] = {24, 35, 0, 0}; -const LC3_INT BW_warp_idx_stop_24k_2_5ms[4] = {32, 39, 0, 0}; -const LC3_INT BW_warp_idx_start_32k_2_5ms[4] = {24, 33, 39, 0}; -const LC3_INT BW_warp_idx_stop_32k_2_5ms[4] = {31, 38, 42, 0}; -const LC3_INT BW_warp_idx_start_48k_2_5ms[4] = {22, 31, 37, 41}; -const LC3_INT BW_warp_idx_stop_48k_2_5ms[4] = {29, 35, 40, 43}; - -const LC3_INT* BW_warp_idx_start_all_2_5ms[4] = {BW_warp_idx_start_16k_2_5ms, BW_warp_idx_start_24k_2_5ms, - BW_warp_idx_start_32k_2_5ms, BW_warp_idx_start_48k_2_5ms}; -const LC3_INT* BW_warp_idx_stop_all_2_5ms[4] = {BW_warp_idx_stop_16k_2_5ms, BW_warp_idx_stop_24k_2_5ms, - BW_warp_idx_stop_32k_2_5ms, BW_warp_idx_stop_48k_2_5ms}; - -const LC3_INT bands_number_2_5ms_HR[6] = {20, 35, 40, 43, 45, 49}; - -const LC3_INT bands_number_2_5ms[5] = {20, 35, 40, 43, 44}; - - -const LC3_INT BW_warp_idx_start_16k_5ms[4] = {39, 0, 0, 0}; -const LC3_INT BW_warp_idx_stop_16k_5ms[4] = {49, 0, 0, 0}; -const LC3_INT BW_warp_idx_start_24k_5ms[4] = {35, 47, 0, 0}; -const LC3_INT BW_warp_idx_stop_24k_5ms[4] = {44, 51, 0, 0}; -const LC3_INT BW_warp_idx_start_32k_5ms[4] = {34, 44, 50, 0}; -const LC3_INT BW_warp_idx_stop_32k_5ms[4] = {42, 49, 53, 0}; -const LC3_INT BW_warp_idx_start_48k_5ms[4] = {32, 42, 48, 52}; -const LC3_INT BW_warp_idx_stop_48k_5ms[4] = {40, 46, 51, 54}; - -const LC3_INT* BW_warp_idx_start_all_5ms[4] = {BW_warp_idx_start_16k_5ms, BW_warp_idx_start_24k_5ms, - BW_warp_idx_start_32k_5ms, BW_warp_idx_start_48k_5ms}; -const LC3_INT* BW_warp_idx_stop_all_5ms[4] = {BW_warp_idx_stop_16k_5ms, BW_warp_idx_stop_24k_5ms, - BW_warp_idx_stop_32k_5ms, BW_warp_idx_stop_48k_5ms}; - -const LC3_INT bands_number_5ms[6] = {39, 50, 52, 54, 55, 58}; - - -const LC3_INT BW_cutoff_bin_all[MAX_BW_BANDS_NUMBER] = {80, 160, 240, 320, 400, 400}; -const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER] = {0, 1, 2, 2, 3, 0}; - -const LC3_INT BW_cutoff_bin_all_5ms[MAX_BW_BANDS_NUMBER] = {40, 80, 120, 160, 200, 200}; -const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER] = {20, 40, 60, 80, 100, 100}; +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_24000[64] = { + 0x4000, 0x455c, 0x4b2a, 0x5176, 0x5848, 0x5fac, 0x67af, 0x705d, 0x79c5, 0x41fc, 0x4782, 0x4d7f, 0x53fc, + 0x5b04, 0x62a3, 0x6ae5, 0x73d9, 0x7d8c, 0x4407, 0x49b9, 0x4fe6, 0x5696, 0x5dd6, 0x65b2, 0x6e35, 0x7770, + 0x40b8, 0x4623, 0x4c02, 0x5260, 0x5945, 0x60bf, 0x68d8, 0x71a0, 0x7b23, 0x42b9, 0x4850, 0x4e5e, 0x54ed, + 0x5c0a, 0x63be, 0x6c18, 0x7525, 0x7ef4, 0x44cb, 0x4a8d, 0x50cb, 0x578f, 0x5ee4, 0x66d6, 0x6f72, 0x78c7, + 0x4172, 0x46ed, 0x4cdd, 0x534c, 0x5a46, 0x61d5, 0x6a06, 0x72e6, 0x7c85, 0x4379, 0x491f, 0x4f3f}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_24000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08}; +#else +#define lpc_warp_pre_emphasis_64_24000 NULL +#define lpc_warp_pre_emphasis_64_e_24000 NULL +#endif -#ifdef CR8_G_ADD_75MS -const LC3_INT BW_cutoff_bin_all_7_5ms[] = {60, 120, 180, 240, 300, 300}; -const LC3_INT bands_number_7_5ms_HR [] = {60, 64, 64, 64, 64, 64}; -const LC3_INT bands_number_7_5ms [] = {60, 64, 64, 64, 64}; +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_32000[64] = { + 0x4000, 0x4661, 0x4d65, 0x551d, 0x5d99, 0x66ed, 0x7130, 0x7c79, 0x4471, 0x4b43, 0x52c4, 0x5b04, 0x6417, + 0x6e11, 0x790a, 0x428e, 0x4930, 0x507c, 0x5882, 0x6154, 0x6b08, 0x75b4, 0x40b8, 0x472b, 0x4e44, 0x5611, + 0x5ea6, 0x6815, 0x7275, 0x7dde, 0x4535, 0x4c1b, 0x53b2, 0x5c0a, 0x6536, 0x6f4d, 0x7a66, 0x434d, 0x4a02, + 0x5163, 0x5980, 0x626c, 0x6c3c, 0x7706, 0x4172, 0x47f8, 0x4f25, 0x5708, 0x5fb5, 0x6940, 0x73be, 0x7f48, + 0x45fc, 0x4cf6, 0x54a2, 0x5d12, 0x6659, 0x708d, 0x7bc6, 0x440e, 0x4ad7, 0x524d, 0x5a81, 0x6387}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_32000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09}; +#else +#define lpc_warp_pre_emphasis_64_32000 NULL +#define lpc_warp_pre_emphasis_64_e_32000 NULL +#endif -const LC3_INT BW_warp_idx_start_16k_7_5ms[4] = {51, 0, 0, 0}; -const LC3_INT BW_warp_idx_stop_16k_7_5ms[4] = {63, 0, 0, 0}; +#ifdef SUBSET_FB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_48000[64] = { + 0x4000, 0x476b, 0x4fb1, 0x58ed, 0x633c, 0x6ebc, 0x7b91, 0x44f1, 0x4cee, 0x55d9, 0x5fcb, 0x6ae5, 0x7748, + 0x428e, 0x4a44, 0x52df, 0x5c7a, 0x6731, 0x7326, 0x403f, 0x47b1, 0x5000, 0x5945, 0x639e, 0x6f29, 0x7c0b, + 0x4535, 0x4d3a, 0x562d, 0x602a, 0x6b4f, 0x77be, 0x42cf, 0x4a8d, 0x5331, 0x5cd5, 0x6797, 0x7398, 0x407f, + 0x47f8, 0x504f, 0x599d, 0x6400, 0x6f97, 0x7c85, 0x457a, 0x4d87, 0x5683, 0x6089, 0x6bb9, 0x7834, 0x4311, + 0x4ad7, 0x5383, 0x5d31, 0x67fd, 0x740a, 0x40be, 0x483f, 0x509e, 0x59f6, 0x6463, 0x7005, 0x7d00}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_48000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}; +#else +#define lpc_warp_pre_emphasis_64_48000 NULL +#define lpc_warp_pre_emphasis_64_e_48000 NULL +#endif -const LC3_INT BW_warp_idx_start_24k_7_5ms[4] = {45, 58, 0, 0}; -const LC3_INT BW_warp_idx_stop_24k_7_5ms[4] = {55, 63, 0, 0}; +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_96000[64] = { + 0x4000, 0x4878, 0x520f, 0x5cea, 0x6936, 0x7721, 0x4372, 0x4c5f, 0x567a, 0x61eb, 0x6ee0, 0x7d8c, 0x4714, + 0x507c, 0x5b22, 0x6731, 0x74d8, 0x4227, 0x4ae8, 0x54d1, 0x600a, 0x6cc0, 0x7b23, 0x45b7, 0x4ef1, 0x5963, + 0x6536, 0x729b, 0x40e2, 0x4978, 0x5331, 0x5e33, 0x6aaa, 0x78c7, 0x4461, 0x4d6d, 0x57ac, 0x6346, 0x7068, + 0x7f48, 0x4810, 0x5199, 0x5c64, 0x689e, 0x7676, 0x4311, 0x4bf1, 0x55fd, 0x615e, 0x6e40, 0x7cd7, 0x46ae, + 0x5008, 0x5a9f, 0x669d, 0x7430, 0x41c8, 0x4a7c, 0x5457, 0x5f80, 0x6c23, 0x7a72, 0x4553, 0x4e7f}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_96000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c}; +#else +# define lpc_warp_pre_emphasis_64_96000 NULL +# define lpc_warp_pre_emphasis_64_e_96000 NULL +#endif -const LC3_INT BW_warp_idx_start_32k_7_5ms[4] = {42, 53, 60, 0}; -const LC3_INT BW_warp_idx_stop_32k_7_5ms[4] = {51, 58, 63, 0}; +RAM_ALIGN const Word16 *const lpc_pre_emphasis[NUM_SAMP_FREQ] = {lpc_warp_pre_emphasis_64_8000, + lpc_warp_pre_emphasis_64_16000, + lpc_warp_pre_emphasis_64_24000, + lpc_warp_pre_emphasis_64_32000, + lpc_warp_pre_emphasis_64_48000, + lpc_warp_pre_emphasis_64_96000 +}; -const LC3_INT BW_warp_idx_start_48k_7_5ms[4] = {40, 51, 57, 61}; -const LC3_INT BW_warp_idx_stop_48k_7_5ms[4] = {48, 55, 60, 63}; +RAM_ALIGN const Word16 *const lpc_pre_emphasis_e[NUM_SAMP_FREQ] = {lpc_warp_pre_emphasis_64_e_8000, + lpc_warp_pre_emphasis_64_e_16000, + lpc_warp_pre_emphasis_64_e_24000, + lpc_warp_pre_emphasis_64_e_32000, + lpc_warp_pre_emphasis_64_e_48000, + lpc_warp_pre_emphasis_64_e_96000 +}; -const LC3_INT brickwall_dist_7_5ms[4] = {4, 4, 3, 2}; +#ifdef SUBSET_NB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_20_8000[20] = {0x4be4, 0x5b79, 0x7a43, 0x53bf, 0x7106, 0x4a1f, 0x5e46, + 0x7477, 0x4613, 0x5260, 0x5ed4, 0x6b21, 0x76f9, 0x4109, + 0x4612, 0x4a79, 0x4e22, 0x50f6, 0x52e2, 0x53dc}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_20_e_8000[20] = { + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_8000[40] = { + 0x4a6c, 0x4e55, 0x5622, 0x61c5, 0x712d, 0x4220, 0x4d71, 0x5a77, 0x691e, 0x794e, 0x4577, 0x4ef1, 0x5906, 0x63a6, + 0x6ec1, 0x7a44, 0x430f, 0x491f, 0x4f46, 0x557c, 0x5bb8, 0x61ee, 0x6815, 0x6e25, 0x7412, 0x79d4, 0x7f61, 0x4259, + 0x44de, 0x473c, 0x4970, 0x4b76, 0x4d4b, 0x4eec, 0x5056, 0x5187, 0x527e, 0x5338, 0x53b5, 0x53f3}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_8000[40] = { + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_8000[80] = { + 0x4a0e, 0x4b09, 0x4cfd, 0x4fec, 0x53d2, 0x58af, 0x5e81, 0x6545, 0x6cf9, 0x759a, 0x7f25, 0x44ca, 0x4a73, 0x508a, + 0x570e, 0x5dfa, 0x654e, 0x6d06, 0x751e, 0x7d94, 0x4332, 0x47c6, 0x4c83, 0x5168, 0x5673, 0x5ba2, 0x60f2, 0x6662, + 0x6bf0, 0x7199, 0x775b, 0x7d34, 0x4191, 0x4490, 0x4798, 0x4aa7, 0x4dba, 0x50d3, 0x53ee, 0x570b, 0x5a29, 0x5d46, + 0x6061, 0x637a, 0x668e, 0x699c, 0x6ca4, 0x6fa3, 0x729a, 0x7587, 0x7868, 0x7b3c, 0x7e03, 0x405e, 0x41b2, 0x42fd, + 0x4440, 0x4579, 0x46a9, 0x47cd, 0x48e7, 0x49f6, 0x4af9, 0x4bf0, 0x4cdb, 0x4db8, 0x4e89, 0x4f4c, 0x5001, 0x50a8, + 0x5140, 0x51ca, 0x5246, 0x52b2, 0x530f, 0x535d, 0x539b, 0x53ca, 0x53e9, 0x53f9}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_8000[80] = { + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_20_8000 NULL +#define lpc_lin_pre_emphasis_20_e_8000 NULL +#define lpc_lin_pre_emphasis_40_8000 NULL +#define lpc_lin_pre_emphasis_40_e_8000 NULL +#define lpc_lin_pre_emphasis_80_8000 NULL +#define lpc_lin_pre_emphasis_80_e_8000 NULL +#endif -const LC3_INT* BW_warp_idx_start_all_7_5ms[4] = {BW_warp_idx_start_16k_7_5ms, BW_warp_idx_start_24k_7_5ms, - BW_warp_idx_start_32k_7_5ms, BW_warp_idx_start_48k_7_5ms}; -const LC3_INT* BW_warp_idx_stop_all_7_5ms[4] = {BW_warp_idx_stop_16k_7_5ms, BW_warp_idx_stop_24k_7_5ms, - BW_warp_idx_stop_32k_7_5ms, BW_warp_idx_stop_48k_7_5ms}; +#ifdef SUBSET_WB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_16000[40] = { + 0x516b, 0x5a81, 0x6c9d, 0x43d2, 0x55b6, 0x6bdd, 0x4313, 0x5233, 0x6336, 0x7602, 0x453d, 0x503e, 0x5bf4, 0x684b, + 0x7530, 0x4148, 0x4829, 0x4f33, 0x5658, 0x5d8f, 0x64cc, 0x6c03, 0x7328, 0x7a32, 0x408a, 0x43e1, 0x471b, 0x4a31, + 0x4d1e, 0x4fde, 0x526d, 0x54c7, 0x56e7, 0x58cb, 0x5a70, 0x5bd2, 0x5cf0, 0x5dc9, 0x5e59, 0x5ea2}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_16000[40] = { + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_16000[80] = { + 0x5091, 0x52d7, 0x5762, 0x5e30, 0x673f, 0x728b, 0x4008, 0x47e3, 0x50d6, 0x5adb, 0x65ef, 0x720e, 0x7f33, 0x46ac, + 0x4e3c, 0x5647, 0x5ec9, 0x67bf, 0x7126, 0x7afa, 0x429b, 0x47ec, 0x4d6d, 0x531c, 0x58f7, 0x5efb, 0x6527, 0x6b78, + 0x71eb, 0x787d, 0x7f2d, 0x42fc, 0x466d, 0x49e8, 0x4d6d, 0x50fa, 0x548d, 0x5825, 0x5bc1, 0x5f5e, 0x62fd, 0x669a, + 0x6a36, 0x6dce, 0x7161, 0x74ee, 0x7872, 0x7bee, 0x7f5f, 0x4162, 0x430e, 0x44b3, 0x4650, 0x47e4, 0x496f, 0x4af0, + 0x4c67, 0x4dd2, 0x4f33, 0x5087, 0x51ce, 0x5309, 0x5436, 0x5554, 0x5665, 0x5766, 0x5858, 0x593a, 0x5a0d, 0x5acf, + 0x5b80, 0x5c20, 0x5caf, 0x5d2d, 0x5d99, 0x5df4, 0x5e3c, 0x5e72, 0x5e97, 0x5ea9}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_16000[80] = { + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_40_16000 NULL +#define lpc_lin_pre_emphasis_40_e_16000 NULL +#define lpc_lin_pre_emphasis_80_16000 NULL +#define lpc_lin_pre_emphasis_80_e_16000 NULL #endif -/* Arithmetic coding */ -const LC3_INT tns_cf[8][18] = {{0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 17, 60, 154, 293, 466, 626, 780, 911, 989, 1016, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 13, 56, 162, 361, 578, 788, 929, 1003, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 6, 17, 66, 270, 555, 852, 972, 1011, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 5, 12, 54, 295, 636, 950, 1008, 1017, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 5, 6, 19, 224, 590, 967, 1014, 1019, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 5, 6, 19, 300, 630, 1001, 1018, 1019, 1020, 1021, 1022, 1023, 1024}, - {0, 1, 2, 3, 4, 5, 6, 11, 308, 309, 991, 1017, 1019, 1020, 1021, 1022, 1023, 1024}}; +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_24000[40] = { + 0x44f2, 0x59a3, 0x4172, 0x603b, 0x447d, 0x5db8, 0x7ba7, 0x4f0d, 0x626d, 0x77d6, 0x4793, 0x541b, 0x6171, 0x6f7f, + 0x7e2f, 0x46b5, 0x4e8b, 0x568f, 0x5eb2, 0x66ea, 0x6f28, 0x775f, 0x7f83, 0x43c3, 0x47ae, 0x4b7d, 0x4f29, 0x52ac, + 0x5602, 0x5924, 0x5c0e, 0x5ebb, 0x6127, 0x634e, 0x652d, 0x66c1, 0x6807, 0x68fd, 0x69a2, 0x69f5}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_24000[40] = { + (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_24000[60] = { + 0x4382, 0x4cb6, 0x5f17, 0x7a99, 0x4f94, 0x6656, 0x40c0, 0x5081, 0x6263, 0x7658, 0x4629, 0x5222, + 0x5f0e, 0x6ce3, 0x7b98, 0x4591, 0x4dbc, 0x5647, 0x5f2b, 0x6862, 0x71e7, 0x7bb2, 0x42de, 0x47ff, + 0x4d39, 0x5288, 0x57e8, 0x5d55, 0x62cc, 0x6849, 0x6dc8, 0x7345, 0x78bc, 0x7e29, 0x41c5, 0x446c, + 0x4709, 0x499a, 0x4c1c, 0x4e8f, 0x50f0, 0x533e, 0x5577, 0x579a, 0x59a4, 0x5b96, 0x5d6c, 0x5f27, + 0x60c4, 0x6243, 0x63a3, 0x64e2, 0x6601, 0x66fd, 0x67d6, 0x688c, 0x691e, 0x698c, 0x69d6, 0x69fb}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_24000[60] = { + (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_24000[80] = { + 0x4301, 0x482e, 0x5287, 0x6208, 0x76a9, 0x4832, 0x5797, 0x697e, 0x7dde, 0x4a59, 0x56f7, 0x64c5, 0x73bd, 0x41ed, + 0x4a8a, 0x53b2, 0x5d63, 0x6798, 0x724d, 0x7d7e, 0x4493, 0x4aa1, 0x50e5, 0x575e, 0x5e0a, 0x64e4, 0x6beb, 0x731d, + 0x7a75, 0x40f9, 0x44c7, 0x48a5, 0x4c91, 0x5088, 0x548a, 0x5895, 0x5ca7, 0x60bf, 0x64db, 0x68f9, 0x6d18, 0x7136, + 0x7552, 0x796a, 0x7d7c, 0x40c4, 0x42c4, 0x44c0, 0x46b6, 0x48a5, 0x4a8c, 0x4c6b, 0x4e41, 0x500e, 0x51d0, 0x5386, + 0x5531, 0x56cf, 0x5860, 0x59e4, 0x5b59, 0x5cbf, 0x5e16, 0x5f5c, 0x6092, 0x61b7, 0x62cb, 0x63cd, 0x64bc, 0x6599, + 0x6663, 0x671a, 0x67bd, 0x684c, 0x68c7, 0x692e, 0x6980, 0x69be, 0x69e8, 0x69fd}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_24000[80] = { + (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_60_24000 NULL +#define lpc_lin_pre_emphasis_60_e_24000 NULL +#define lpc_lin_pre_emphasis_40_24000 NULL +#define lpc_lin_pre_emphasis_40_e_24000 NULL +#define lpc_lin_pre_emphasis_80_24000 NULL +#define lpc_lin_pre_emphasis_80_e_24000 NULL +#endif -const LC3_INT tns_freq_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, {0, 14, 56, 156, 313, 494, 672, 839, 1024}}; +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_32000[80] = { + 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c, + 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51, + 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a, + 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0, + 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108, + 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_32000[80] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_80_32000 NULL +#define lpc_lin_pre_emphasis_80_e_32000 NULL +#endif -/* MDCT Windows */ +#ifdef SUBSET_FB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_48000[60] = { + 0x7330, 0x62e5, 0x5ab1, 0x4c35, 0x753a, 0x5425, 0x72a0, 0x4afd, 0x5f0d, 0x7571, 0x470d, 0x547b, + 0x62fa, 0x727f, 0x4180, 0x4a38, 0x5362, 0x5cf7, 0x66f0, 0x7148, 0x7bf5, 0x4379, 0x491b, 0x4edc, + 0x54b9, 0x5aae, 0x60b6, 0x66cd, 0x6cee, 0x7316, 0x7941, 0x7f69, 0x42c5, 0x45d1, 0x48d4, 0x4bcf, + 0x4ebd, 0x519e, 0x546f, 0x572e, 0x59d9, 0x5c6f, 0x5eee, 0x6153, 0x639d, 0x65cb, 0x67dc, 0x69cc, + 0x6b9c, 0x6d4a, 0x6ed4, 0x703b, 0x717c, 0x7296, 0x738a, 0x7457, 0x74fb, 0x7576, 0x75c9, 0x75f2}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_48000[60] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_48000[80] = { + 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c, + 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51, + 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a, + 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0, + 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108, + 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_48000[80] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_60_48000 NULL +#define lpc_lin_pre_emphasis_60_e_48000 NULL +#define lpc_lin_pre_emphasis_80_48000 NULL +#define lpc_lin_pre_emphasis_80_e_48000 NULL +#endif +# if defined(SUBSET_SWB) || defined(SUBSET_FB) +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_0_92[80] = { + 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c, + 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51, + 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a, + 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0, + 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108, + 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_0_92[80] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +# else +# define lpc_lin_pre_emphasis_80_0_92 NULL +# define lpc_lin_pre_emphasis_80_e_0_92 NULL +# endif + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis[NUM_SAMP_FREQ] = {lpc_lin_pre_emphasis_80_8000, lpc_lin_pre_emphasis_80_16000, + lpc_lin_pre_emphasis_80_24000, lpc_lin_pre_emphasis_80_32000, + lpc_lin_pre_emphasis_80_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_0_92 +#endif + }; -#ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_80_e_8000, lpc_lin_pre_emphasis_80_e_16000, lpc_lin_pre_emphasis_80_e_24000, + lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_80_e_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_e_0_92 +#endif +}; -const LC3_FLOAT MDCT_HRA_WINDOW_480_7_5ms[720] = { - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 6.809599915345237e-08, 2.716186708704376e-07, 6.424371293934969e-07, - 1.260808101892957e-06, 2.229378921489615e-06, 3.679074029772919e-06, 5.774505277720125e-06, 8.719889849723028e-06, - 1.276556063788606e-05, 1.821508881356302e-05, 2.543302196376427e-05, 3.485323086760931e-05, 4.698784831976895e-05, - 6.243677337396717e-05, 8.189770380196378e-05, 1.061766484618177e-04, 1.361988597286949e-04, 1.730201142776986e-04, - 2.178382584565609e-04, 2.720049223973359e-04, 3.370372950540977e-04, 4.146298406925523e-04, 5.066658261806472e-04, - 6.152285179265661e-04, 7.426118976760646e-04, 8.913307378108167e-04, 1.064129869478226e-03, 1.263992471022180e-03, - 1.494147199957892e-03, 1.758073989316892e-03, 2.059508328742228e-03, 2.402443852384859e-03, 2.791133059566779e-03, - 3.230086000439834e-03, 3.724066767561293e-03, 4.278087645481125e-03, 4.897400784114414e-03, 5.587487277846723e-03, - 6.354043550947961e-03, 7.202964970873775e-03, 8.140326634299601e-03, 9.172361296110928e-03, 1.030543443887801e-02, - 1.154601650935216e-02, 1.290065237897715e-02, 1.437592811702264e-02, 1.597843519739845e-02, 1.771473229314812e-02, - 1.959130484567766e-02, 2.161452262855616e-02, 2.379059555782150e-02, 2.612552803171593e-02, 2.862507211224012e-02, - 3.129467988842215e-02, 3.413945538633399e-02, 3.716410641324389e-02, 4.037289674248027e-02, 4.376959906123697e-02, - 4.735744911533900e-02, 5.113910149261011e-02, 5.511658748968899e-02, 5.929127550571237e-02, 6.366383440006920e-02, - 6.823420024032127e-02, 7.300154685033973e-02, 7.796426054773728e-02, 8.311991943385708e-02, 8.846527756905853e-02, - 9.399625433100661e-02, 9.970792921440458e-02, 1.055945422874181e-01, 1.116495004733158e-01, 1.178654910777398e-01, - 1.242343970754217e-01, 1.307472697698447e-01, 1.373944835632858e-01, 1.441657329773458e-01, 1.510500827600614e-01, - 1.580360226424669e-01, 1.651115279124688e-01, 1.722641255794418e-01, 1.794809657536407e-01, 1.867488977915941e-01, - 1.940545506994020e-01, 2.013844172328433e-01, 2.087249410855671e-01, 2.160626065146083e-01, 2.233840297164879e-01, - 2.306760512375861e-01, 2.379258286796330e-01, 2.451209289452065e-01, 2.522494192591140e-01, 2.592999561994307e-01, - 2.662618719765588e-01, 2.731252572097561e-01, 2.798810394677779e-01, 2.865210568632502e-01, 2.930381260187334e-01, - 2.994261037557683e-01, 3.056799418961772e-01, 3.117957346072421e-01, 3.177707577688937e-01, 3.236034998916132e-01, - 3.292936841683654e-01, 3.348422813026286e-01, 3.402515128176158e-01, 3.455248446193337e-01, 3.506669706583936e-01, - 3.556837866127393e-01, 3.605823535957678e-01, 3.653708519817664e-01, 3.700585255329578e-01, 3.746556161093967e-01, - 3.791732893437698e-01, 3.836235517669143e-01, 3.880191599752360e-01, 3.923735225365686e-01, 3.967005954344419e-01, - 4.010147719499705e-01, 4.053307679732117e-01, 4.096635038192941e-01, 4.140279836962412e-01, 4.184391740286457e-01, - 4.229118818818259e-01, 4.274606347526876e-01, 4.320995629945984e-01, 4.368422861229869e-01, 4.417018042055877e-01, - 4.466903954763946e-01, 4.518195212263102e-01, 4.570997389177666e-01, 4.625406243474134e-01, 4.681507035432432e-01, - 4.739373949335071e-01, 4.799069621682588e-01, 4.860644778142650e-01, 4.924137979843949e-01, 4.989575478073994e-01, - 5.056971174969224e-01, 5.126326686429926e-01, 5.197631502279640e-01, 5.270863237641458e-01, 5.345987968637925e-01, - 5.422960644846202e-01, 5.501725570458306e-01, 5.582216945803693e-01, 5.664359460778171e-01, 5.748068931775395e-01, - 5.833252973915712e-01, 5.919811700691291e-01, 6.007638443572958e-01, 6.096620484629849e-01, 6.186639795774059e-01, - 6.277573778837434e-01, 6.369296001295948e-01, 6.461676923061090e-01, 6.554584610342162e-01, 6.647885433136285e-01, - 6.741444743414929e-01, 6.835127531540456e-01, 6.928799058859592e-01, 7.022325464781733e-01, 7.115574346958600e-01, - 7.208415313440352e-01, 7.300720505895358e-01, 7.392365093150189e-01, 7.483227734438597e-01, 7.573191011847887e-01, - 7.662141831523945e-01, 7.749971793247219e-01, 7.836577528026495e-01, 7.921861003379914e-01, 8.005729795988183e-01, - 8.088097331417404e-01, 8.168883090622450e-01, 8.248012782960292e-01, 8.325418485469714e-01, 8.401038748212752e-01, - 8.474818665528070e-01, 8.546709913119690e-01, 8.616670751000000e-01, 8.684665992426276e-01, 8.750666939117441e-01, - 8.814651283214563e-01, 8.876602976655703e-01, 8.936512068873075e-01, 8.994374513987017e-01, 9.050191948964271e-01, - 9.103971444522861e-01, 9.155725230896603e-01, 9.205470400910444e-01, 9.253228593153561e-01, 9.299025658359243e-01, - 9.342891312395554e-01, 9.384858779525852e-01, 9.424964429799174e-01, 9.463247414564011e-01, 9.499749304154305e-01, - 9.534513731762839e-01, 9.567586047388893e-01, 9.599012985520849e-01, 9.628842349891718e-01, 9.657122718232282e-01, - 9.683903169452684e-01, 9.709233035123621e-01, 9.733161676521148e-01, 9.755738287865520e-01, 9.777011725747500e-01, - 9.797030364119408e-01, 9.815841973655319e-01, 9.833493623777330e-01, 9.850031605220572e-01, 9.865501370683191e-01, - 9.879947490888552e-01, 9.893413623279752e-01, 9.905942490570202e-01, 9.917575866483249e-01, 9.928354566216883e-01, - 9.938318439453252e-01, 9.947506364078684e-01, 9.955956239169538e-01, 9.963704976211798e-01, 9.970788487938620e-01, - 9.977241674570765e-01, 9.983098407613983e-01, 9.988391511690631e-01, 9.993152745149454e-01, 9.997412780400421e-01, - 1.000120118505655e+00, 1.000454640503141e+00, 1.000747575074179e+00, 1.001001538750552e+00, 1.001219033111063e+00, - 1.001402444937498e+00, 1.001554047032278e+00, 1.001675999738891e+00, 1.001770353183267e+00, 1.001839050231077e+00, - 1.001883930133431e+00, 1.001906732812431e+00, 1.001909103719272e+00, 1.001892599181639e+00, 1.001858692144366e+00, - 1.001808778198111e+00, 1.001744181785080e+00, 1.001666162468790e+00, 1.001575921156133e+00, 1.001474606164513e+00, - 1.001363319034069e+00, 1.001243119994661e+00, 1.001115033008877e+00, 1.000980050325283e+00, 1.000839136490102e+00, - 1.000693231779806e+00, 1.000543255031507e+00, 1.000390105861922e+00, 1.000234666278804e+00, 1.000077801700791e+00, - 9.999203614123487e-01, 9.997631784897281e-01, 9.996070692418051e-01, 9.994528322168238e-01, 9.993012468388005e-01, - 9.991530718675707e-01, 9.990090391528494e-01, 9.988698631596843e-01, 9.987362319429512e-01, 9.986087958497237e-01, - 9.984881744259831e-01, 9.983749534239558e-01, 9.982696819855041e-01, 9.981728700145615e-01, 9.980849857504854e-01, - 9.980064535530436e-01, 9.979376519085494e-01, 9.978789116654476e-01, 9.978305145064250e-01, 9.977926916628833e-01, - 9.977656228763698e-01, 9.977494356103552e-01, 9.977442045145120e-01, 9.977499511424820e-01, 9.977666439229387e-01, - 9.977941983826280e-01, 9.978324776189644e-01, 9.978812930187096e-01, 9.979404052182159e-01, 9.980095252997591e-01, - 9.980883162175314e-01, 9.981763944459758e-01, 9.982733318422902e-01, 9.983786577141155e-01, 9.984918610826710e-01, - 9.986123931308583e-01, 9.987396698251857e-01, 9.988730746997222e-01, 9.990119617896823e-01, 9.991556587016854e-01, - 9.993034698072086e-01, 9.994546795452566e-01, 9.996085558198406e-01, 9.997643534774231e-01, 9.999213178491362e-01, - 1.000078688342232e+00, 1.000235702064949e+00, 1.000391597468710e+00, 1.000545617991395e+00, 1.000697015685261e+00, - 1.000845054812993e+00, 1.000989015395319e+00, 1.001128196693676e+00, 1.001261920611439e+00, 1.001389534997449e+00, - 1.001510416835741e+00, 1.001623975305719e+00, 1.001729654697400e+00, 1.001826937166789e+00, 1.001915345317049e+00, - 1.001994444591742e+00, 1.002063845467139e+00, 1.002123205431461e+00, 1.002172230739781e+00, 1.002210677934335e+00, - 1.002238355121073e+00, 1.002255122994435e+00, 1.002260895603584e+00, 1.002255640854628e+00, 1.002239380744737e+00, - 1.002212191325473e+00, 1.002174202394129e+00, 1.002125596913369e+00, 1.002066610160972e+00, 1.001997528613025e+00, - 1.001918688565458e+00, 1.001830474500286e+00, 1.001733317204479e+00, 1.001627691650788e+00, 1.001514114651268e+00, - 1.001393142295620e+00, 1.001265367187681e+00, 1.001131415494648e+00, 1.000991943824643e+00, 1.000847635949292e+00, - 1.000699199388794e+00, 1.000547361877802e+00, 1.000392867731002e+00, 1.000236474127865e+00, 1.000078947336370e+00, - 9.999210588958194e-01, 9.997635817789274e-01, 9.996072865534386e-01, 9.994529375633210e-01, 9.993012891494056e-01, - 9.991530819289113e-01, 9.990090391528497e-01, 9.988698631596844e-01, 9.987362319429512e-01, 9.986087958497240e-01, - 9.984881744259831e-01, 9.983749534239558e-01, 9.982696819855044e-01, 9.981728700145615e-01, 9.980849857504854e-01, - 9.980064535530438e-01, 9.979376519085497e-01, 9.978789116654476e-01, 9.978305145064252e-01, 9.977926916628833e-01, - 9.977656228763698e-01, 9.977494356103552e-01, 9.977442045145120e-01, 9.977499511424820e-01, 9.977666439229387e-01, - 9.977941983826278e-01, 9.978324776189643e-01, 9.978812930187095e-01, 9.979404052182158e-01, 9.980095252997588e-01, - 9.980883162175312e-01, 9.981763944459756e-01, 9.982733318422901e-01, 9.983786577141153e-01, 9.984918610826709e-01, - 9.986123931308580e-01, 9.987396698251855e-01, 9.988730746997220e-01, 9.990119617896820e-01, 9.991556587016851e-01, - 9.993034698072083e-01, 9.994546795452562e-01, 9.996085558198403e-01, 9.997643534774228e-01, 9.999213178491358e-01, - 1.000078688342232e+00, 1.000235702064949e+00, 1.000391597468709e+00, 1.000545617991395e+00, 1.000697015685261e+00, - 1.000845054812992e+00, 1.000989015395319e+00, 1.001128196693676e+00, 1.001261920611439e+00, 1.001389534997449e+00, - 1.001510416835740e+00, 1.001623975305719e+00, 1.001729654697400e+00, 1.001826937166789e+00, 1.001915345317049e+00, - 1.001994444591742e+00, 1.002063845467139e+00, 1.002123205431461e+00, 1.002172230739781e+00, 1.002210677934335e+00, - 1.002238355121073e+00, 1.002255122994435e+00, 1.002260895603584e+00, 1.002255640854628e+00, 1.002239380744737e+00, - 1.002212191325473e+00, 1.002174202394129e+00, 1.002125596913369e+00, 1.002066610160972e+00, 1.001997528613026e+00, - 1.001918688565458e+00, 1.001830474500286e+00, 1.001733317204480e+00, 1.001627691650788e+00, 1.001514114651269e+00, - 1.001393142295620e+00, 1.001265367187681e+00, 1.001131415494648e+00, 1.000991943824644e+00, 1.000847625870882e+00, - 1.000699157018909e+00, 1.000547256415431e+00, 1.000392650246594e+00, 1.000236070641674e+00, 1.000078249725773e+00, - 9.999199133992033e-01, 9.997617746889341e-01, 9.996045266479927e-01, 9.994488347910435e-01, 9.992953290608048e-01, - 9.991445953265840e-01, 9.989971664237720e-01, 9.988535127515954e-01, 9.987140324557005e-01, 9.985790412319091e-01, - 9.984487617975299e-01, 9.983233130864525e-01, 9.982026992336113e-01, 9.980867984227458e-01, 9.979753516783147e-01, - 9.978679516874593e-01, 9.977640317406775e-01, 9.976628548799390e-01, 9.975635033400763e-01, 9.974648683632181e-01, - 9.973656404566504e-01, 9.972643001519088e-01, 9.971591093072504e-01, 9.970481029773169e-01, 9.969290818533281e-01, - 9.967996052552075e-01, 9.966569846345418e-01, 9.964982775252248e-01, 9.963202818581681e-01, 9.961195305388424e-01, - 9.958922861728758e-01, 9.956345358167873e-01, 9.953419856293327e-01, 9.950100553049441e-01, 9.946338721852209e-01, - 9.942082649678485e-01, 9.937277569649872e-01, 9.931865589047922e-01, 9.925785613196768e-01, 9.918973266220812e-01, - 9.911360810312226e-01, 9.902877065805247e-01, 9.893447335026750e-01, 9.882993333547356e-01, 9.871433133064559e-01, - 9.858681120677728e-01, 9.844647979734713e-01, 9.829240697712801e-01, 9.812362606719703e-01, 9.793913462143841e-01, - 9.773789564736696e-01, 9.751883930968924e-01, 9.728086515871036e-01, 9.702284491761823e-01, 9.674362585304656e-01, - 9.644203474241703e-01, 9.611688243973939e-01, 9.576696902919403e-01, 9.539108954335166e-01, 9.498804021071905e-01, - 9.455662518583811e-01, 9.409566370477763e-01, 9.360399759985500e-01, 9.308049910005284e-01, 9.252407883802984e-01, - 9.193369398095318e-01, 9.130835640061534e-01, 9.064714079838252e-01, 8.994919270231900e-01, 8.921373625716933e-01, - 8.844008173252615e-01, 8.762763268021769e-01, 8.677589267845028e-01, 8.588447160727389e-01, 8.495309140724763e-01, - 8.398159128053756e-01, 8.296993230087498e-01, 8.191820140566964e-01, 8.082661474997362e-01, 7.969552040782567e-01, - 7.852540041171052e-01, 7.731687212540459e-01, 7.607068894934714e-01, 7.478774036088883e-01, 7.346905129436833e-01, - 7.211578086800342e-01, 7.072922046612431e-01, 6.931079118639383e-01, 6.786204066243602e-01, 6.638463927281081e-01, - 6.488037574761728e-01, 6.335115218426407e-01, 6.179897848420400e-01, 6.022596622277155e-01, 5.863432196477422e-01, - 5.702634003925362e-01, 5.540439478792599e-01, 5.377093230331162e-01, 5.212846167453395e-01, 5.047954576127168e-01, - 4.882679151942771e-01, 4.717283990576996e-01, 4.552035539311637e-01, 4.387201513257116e-01, 4.223049780484175e-01, - 4.059847220871455e-01, 3.897858564125437e-01, 3.737345213109408e-01, 3.578564059314520e-01, 3.421766298000327e-01, - 3.267196251203117e-01, 3.115090207434621e-01, 2.965675287446095e-01, 2.819168345887702e-01, 2.675774919024606e-01, - 2.535688228855250e-01, 2.399088253991666e-01, 2.266140877488131e-01, 2.136997121429473e-01, 2.011792477505556e-01, - 1.890646342002475e-01, 1.773661562639070e-01, 1.660924103481652e-01, 1.552502832800154e-01, 1.448449437210769e-01, - 1.348798463815727e-01, 1.253567490336474e-01, 1.162757421482153e-01, 1.076352908043133e-01, 9.943228834915691e-02, - 9.166212112492260e-02, 8.431874342855604e-02, 7.739476173713079e-02, 7.088152711641457e-02, 6.476923463670382e-02, - 5.904702854937628e-02, 5.370311193097759e-02, 4.872485947931735e-02, 4.409893214762228e-02, 3.981139232728093e-02, - 3.584781833555012e-02, 3.219341702973252e-02, 2.883313345136149e-02, 2.575175650013100e-02, 2.293401974481060e-02, - 2.036469659423059e-02, 1.802868917267256e-02, 1.591111036782373e-02, 1.399735864319379e-02, 1.227318532813230e-02, - 1.072475421518567e-02, 9.338693404676062e-03, 8.102139438575821e-03, 7.002773858835369e-03, 6.028852408470130e-03, - 5.169227166401885e-03, 4.413361969047579e-03, 3.751341522971312e-03, 3.173874653799314e-03, 2.672292167462025e-03, - 2.238539821235712e-03, 1.865166914682179e-03, 1.545311015180633e-03, 1.272679330109336e-03, 1.041527228687644e-03, - 8.466344018536364e-04, 6.832791291344422e-04, 5.472110980420254e-04, 4.346231948339177e-04, 3.421226562082296e-04, - 2.667019402979896e-04, 2.057096427837635e-04, 1.568217505967225e-04, 1.180134920282553e-04, 8.753200853960576e-05, - 6.387004057159679e-05, 4.574078753977487e-05, 3.205407126647298e-05, 2.189390259660641e-05, 1.449752303895666e-05, - 9.235966977587421e-06, 5.596164823995474e-06, 3.164580913106852e-06, 1.612338255148207e-06, 6.816185333295410e-07, - 1.708705677347936e-07, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00 +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_40_8000, lpc_lin_pre_emphasis_80_16000, lpc_lin_pre_emphasis_40_24000, + lpc_lin_pre_emphasis_80_32000, lpc_lin_pre_emphasis_80_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_0_92 +#endif }; -const LC3_FLOAT MDCT_HRA_WINDOW_960_7_5ms[1440] = { - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 4.814997152662380e-08, - 1.190718835543930e-07, 2.207853347953071e-07, 3.606855997228003e-07, 5.473208818980691e-07, 7.905197136719171e-07, - 1.101521714920831e-06, 1.493116418344220e-06, 1.979790786588690e-06, 2.577885657879143e-06, 3.305761290579034e-06, - 4.183972154098288e-06, 5.235451095160501e-06, 6.485702988281604e-06, 7.963007956558409e-06, 9.698634223646832e-06, - 1.172706063036777e-05, 1.408620881991443e-05, 1.681768506430009e-05, 1.996703167159834e-05, 2.358398787878628e-05, - 2.772276009869224e-05, 3.244230135176009e-05, 3.780659967415316e-05, 4.388497525322647e-05, 5.075238599968363e-05, - 5.848974122290910e-05, 6.718422303212972e-05, 7.692961504132544e-05, 8.782663791029826e-05, 9.998329120814524e-05, - 1.135152010387006e-04, 1.285459728204526e-04, 1.452075485661517e-04, 1.636405679599540e-04, 1.839947324826567e-04, - 2.064291717885308e-04, 2.311128114906271e-04, 2.582247414653769e-04, 2.879545837420285e-04, 3.205028589981173e-04, - 3.560813506389657e-04, 3.949134653973109e-04, 4.372345893487853e-04, 4.832924382002834e-04, 5.333474006714636e-04, - 5.876728737549225e-04, 6.465555886081460e-04, 7.102959258003701e-04, 7.792082186101814e-04, 8.536210430451991e-04, - 9.338774932337428e-04, 1.020335440820132e-03, 1.113367776980400e-03, 1.213362635663867e-03, 1.320723596658401e-03, - 1.435869867073428e-03, 1.559236439835012e-03, 1.691274227791697e-03, 1.832450172038491e-03, 1.983247323079433e-03, - 2.144164893466752e-03, 2.315718280576775e-03, 2.498439058209637e-03, 2.692874935731413e-03, 2.899589683513746e-03, - 3.119163023467312e-03, 3.352190483511667e-03, 3.599283214875066e-03, 3.861067771173851e-03, 4.138185848281871e-03, - 4.431293984066133e-03, 4.741063217135362e-03, 5.068178703823501e-03, 5.413339292709984e-03, 5.777257056063160e-03, - 6.160656777682084e-03, 6.564275396705108e-03, 6.988861407050997e-03, 7.435174212259442e-03, 7.903983435603223e-03, - 8.396068185452360e-03, 8.912216275983018e-03, 9.453223403438580e-03, 1.001989227826831e-02, 1.061303171358943e-02, - 1.123345567054105e-02, 1.188198226122286e-02, 1.255943271003813e-02, 1.326663027438758e-02, 1.400439912578959e-02, - 1.477356319263120e-02, 1.557494496588335e-02, 1.640936426924359e-02, 1.727763699529732e-02, 1.818057380941704e-02, - 1.911897882324480e-02, 2.009364823972783e-02, 2.110536897180007e-02, 2.215491723692114e-02, 2.324305712980262e-02, - 2.437053917576323e-02, 2.553809886726559e-02, 2.674645518629135e-02, 2.799630911531313e-02, 2.928834213971679e-02, - 3.062321474461790e-02, 3.200156490910068e-02, 3.342400660098604e-02, 3.489112827530663e-02, 3.640349137973180e-02, - 3.796162887024292e-02, 3.956604374040874e-02, 4.121720756765420e-02, 4.291555907994722e-02, 4.466150274635713e-02, - 4.645540739495172e-02, 4.829760486151040e-02, 5.018838867252923e-02, 5.212801276598264e-02, 5.411669025328793e-02, - 5.615459222588953e-02, 5.824184660984119e-02, 6.037853707171543e-02, 6.256470197911304e-02, 6.480033341897713e-02, - 6.708537627683842e-02, 6.941972738003349e-02, 7.180323470784016e-02, 7.423569667136878e-02, 7.671686146593476e-02, - 7.924642649851196e-02, 8.182403789273630e-02, 8.444929007378586e-02, 8.712172543531613e-02, 8.984083409047044e-02, - 9.260605370882179e-02, 9.541676944092861e-02, 9.827231393200973e-02, 1.011719674260564e-01, 1.041149579615082e-01, - 1.071004616594233e-01, 1.101276031048689e-01, 1.131954558220525e-01, 1.163031145055895e-01, 1.194495144788202e-01, - 1.226335917234308e-01, 1.258542330378917e-01, 1.291102796186627e-01, 1.324005282765081e-01, 1.357237327475410e-01, - 1.390786051045917e-01, 1.424638172681925e-01, 1.458780026156580e-01, 1.493197576864202e-01, 1.527876439815144e-01, - 1.562801898548664e-01, 1.597958924937929e-01, 1.633332199858745e-01, 1.668906134691307e-01, 1.704664893621876e-01, - 1.740592416709001e-01, 1.776672443676665e-01, 1.812888538394568e-01, 1.849224114003725e-01, 1.885662458643452e-01, - 1.922186761734047e-01, 1.958780140767561e-01, 1.995425668557404e-01, 2.032106400895931e-01, 2.068805404567710e-01, - 2.105505785664793e-01, 2.142190718149099e-01, 2.178843472605934e-01, 2.215447445131696e-01, 2.251986186298022e-01, - 2.288443430133839e-01, 2.324803123066372e-01, 2.361049452761597e-01, 2.397166876804412e-01, 2.433140151158676e-01, - 2.468954358347107e-01, 2.504594935291377e-01, 2.540047700752680e-01, 2.575298882313734e-01, 2.610335142843411e-01, - 2.645143606385947e-01, 2.679711883417369e-01, 2.714028095412598e-01, 2.748080898667649e-01, 2.781859507322435e-01, - 2.815353715530788e-01, 2.848553918725547e-01, 2.881451133928004e-01, 2.914037019052332e-01, 2.946303891157192e-01, - 2.978244743598311e-01, 3.009853262037530e-01, 3.041123839265586e-01, 3.072051588797733e-01, 3.102632357203233e-01, - 3.132862735131834e-01, 3.162740067002296e-01, 3.192262459320352e-01, 3.221428787595638e-01, 3.250238701829489e-01, - 3.278692630547906e-01, 3.306791783356554e-01, 3.334538151997121e-01, 3.361934509887193e-01, 3.388984410128472e-01, - 3.415692181971050e-01, 3.442062925724498e-01, 3.468102506109446e-01, 3.493817544046665e-01, 3.519215406883794e-01, - 3.544304197063321e-01, 3.569092739238819e-01, 3.593590565850064e-01, 3.617807901171322e-01, 3.641755643850764e-01, - 3.665445347962969e-01, 3.688889202600189e-01, 3.712100010032212e-01, 3.735091162468620e-01, 3.757876617461321e-01, - 3.780470871989401e-01, 3.802888935272475e-01, 3.825146300362834e-01, 3.847258914570857e-01, 3.869243148782224e-01, - 3.891115765729500e-01, 3.912893887284619e-01, 3.934594960842652e-01, 3.956236724870978e-01, 3.977837173701507e-01, - 3.999414521646988e-01, 4.020987166525755e-01, 4.042573652681952e-01, 4.064192633591230e-01, 4.085862834144205e-01, - 4.107603012702034e-01, 4.129431923020324e-01, 4.151368276138986e-01, 4.173430702336651e-01, 4.195637713248997e-01, - 4.218007664250568e-01, 4.240558717199467e-01, 4.263308803643829e-01, 4.286275588587793e-01, 4.309476434913423e-01, - 4.332928368553010e-01, 4.356648044503836e-01, 4.380651713774884e-01, 4.404955191351588e-01, 4.429573825261284e-01, - 4.454522466818012e-01, 4.479815442120949e-01, 4.505466524876126e-01, 4.531488910606020e-01, 4.557895192306389e-01, - 4.584697337604117e-01, 4.611906667464130e-01, 4.639533836487439e-01, 4.667588814836276e-01, 4.696080871816153e-01, - 4.725018561138271e-01, 4.754409707879499e-01, 4.784261397150824e-01, 4.814579964478883e-01, 4.845370987899071e-01, - 4.876639281752684e-01, 4.908388892174636e-01, 4.940623094252686e-01, 4.973344390833572e-01, 5.006554512946366e-01, - 5.040254421808312e-01, 5.074444312373949e-01, 5.109123618383964e-01, 5.144291018866259e-01, 5.179944446038284e-01, - 5.216081094556281e-01, 5.252697432054461e-01, 5.289789210914528e-01, 5.327351481204011e-01, 5.365378604720108e-01, - 5.403864270074484e-01, 5.442801508753474e-01, 5.482182712087564e-01, 5.521999649063806e-01, 5.562243484914785e-01, - 5.602904800418288e-01, 5.643973611842344e-01, 5.685439391471354e-01, 5.727291088650085e-01, 5.769517151283868e-01, - 5.812105547734755e-01, 5.855043789055335e-01, 5.898318951503732e-01, 5.941917699285435e-01, 5.985826307469763e-01, - 6.030030685030957e-01, 6.074516397966441e-01, 6.119268692446796e-01, 6.164272517954765e-01, 6.209512550372698e-01, - 6.254973214980470e-01, 6.300638709328106e-01, 6.346493025949689e-01, 6.392519974887557e-01, 6.438703205997779e-01, - 6.485026231010093e-01, 6.531472445317767e-01, 6.578025149474425e-01, 6.624667570377041e-01, 6.671382882115985e-01, - 6.718154226474637e-01, 6.764964733062689e-01, 6.811797539068755e-01, 6.858635808619125e-01, 6.905462751730997e-01, - 6.952261642849390e-01, 6.999015838958201e-01, 7.045708797256799e-01, 7.092324092394289e-01, 7.138845433254541e-01, - 7.185256679285629e-01, 7.231541856368034e-01, 7.277685172216439e-01, 7.323671031310492e-01, 7.369484049350288e-01, - 7.415109067232617e-01, 7.460531164544494e-01, 7.505735672570528e-01, 7.550708186811053e-01, 7.595434579008099e-01, - 7.639901008676322e-01, 7.684093934136257e-01, 7.728000123047261e-01, 7.771606662437623e-01, 7.814900968229372e-01, - 7.857870794255352e-01, 7.900504240766176e-01, 7.942789762424746e-01, 7.984716175785987e-01, 8.026272666259650e-01, - 8.067448794553850e-01, 8.108234502597368e-01, 8.148620118938579e-01, 8.188596363619152e-01, 8.228154352520715e-01, - 8.267285601182841e-01, 8.305982028090957e-01, 8.344235957432927e-01, 8.382040121323370e-01, 8.419387661495058e-01, - 8.456272130457134e-01, 8.492687492120119e-01, 8.528628121888369e-01, 8.564088806220885e-01, 8.599064741662098e-01, - 8.633551533344737e-01, 8.667545192967644e-01, 8.701042136252025e-01, 8.734039179880492e-01, 8.766533537923937e-01, - 8.798522817762424e-01, 8.830005015507004e-01, 8.860978510930465e-01, 8.891442061916122e-01, 8.921394798434883e-01, - 8.950836216061893e-01, 8.979766169045416e-01, 9.008184862941767e-01, 9.036092846831453e-01, 9.063491005132949e-01, - 9.090380549031886e-01, 9.116763007544754e-01, 9.142640218237603e-01, 9.168014317621422e-01, 9.192887731247262e-01, - 9.217263163525492e-01, 9.241143587294502e-01, 9.264532233165643e-01, 9.287432578672022e-01, 9.309848337249814e-01, - 9.331783447081556e-01, 9.353242059831766e-01, 9.374228529305666e-01, 9.394747400062335e-01, 9.414803396013999e-01, - 9.434401409043077e-01, 9.453546487668929e-01, 9.472243825795639e-01, 9.490498751572118e-01, 9.508316716394957e-01, - 9.525703284083868e-01, 9.542664120258422e-01, 9.559204981943715e-01, 9.575331707431241e-01, 9.591050206419620e-01, - 9.606366450458275e-01, 9.621286463715110e-01, 9.635816314087369e-01, 9.649962104672655e-01, 9.663729965614801e-01, - 9.677126046337026e-01, 9.690156508172226e-01, 9.702827517397986e-01, 9.715145238681151e-01, 9.727115828934468e-01, - 9.738745431585201e-01, 9.750040171253210e-01, 9.761006148833546e-01, 9.771649436976386e-01, 9.781976075954760e-01, - 9.791992069908698e-01, 9.801703383452239e-01, 9.811115938628175e-01, 9.820235612193683e-01, 9.829068233218750e-01, - 9.837619580977977e-01, 9.845895383115438e-01, 9.853901314061559e-01, 9.861642993680373e-01, 9.869125986125210e-01, - 9.876355798880896e-01, 9.883337881970466e-01, 9.890077627304957e-01, 9.896580368155167e-01, 9.902851378725152e-01, - 9.908895873808024e-01, 9.914719008505681e-01, 9.920325877995377e-01, 9.925721517327187e-01, 9.930910901238019e-01, - 9.935898943969245e-01, 9.940690499076552e-01, 9.945290359222332e-01, 9.949703255942541e-01, 9.953933859381526e-01, - 9.957986777990047e-01, 9.961866558183331e-01, 9.965577683957455e-01, 9.969124576463969e-01, 9.972511593543985e-01, - 9.975743029224325e-01, 9.978823113179629e-01, 9.981756010165178e-01, 9.984545819426528e-01, 9.987196574092618e-01, - 9.989712240559885e-01, 9.992096717875499e-01, 9.994353837128311e-01, 9.996487360856312e-01, 9.998500982479841e-01, - 1.000039832576952e+00, 1.000218294435816e+00, 1.000385832130536e+00, 1.000542786872366e+00, 1.000689492747415e+00, - 1.000826276693953e+00, 1.000953458488153e+00, 1.001071350738924e+00, 1.001180258892415e+00, 1.001280481246664e+00, - 1.001372308976828e+00, 1.001456026171296e+00, 1.001531909878933e+00, 1.001600230167594e+00, 1.001661250193955e+00, - 1.001715226284630e+00, 1.001762408028438e+00, 1.001803038379606e+00, 1.001837353771603e+00, 1.001865584241233e+00, - 1.001887953562516e+00, 1.001904679389828e+00, 1.001915973409726e+00, 1.001922041500763e+00, 1.001923083900631e+00, - 1.001919295379834e+00, 1.001910865421132e+00, 1.001897978403901e+00, 1.001880813792572e+00, 1.001859546328272e+00, - 1.001834346222781e+00, 1.001805379353926e+00, 1.001772807461511e+00, 1.001736788342922e+00, 1.001697476047539e+00, - 1.001655021069100e+00, 1.001609570535228e+00, 1.001561268393305e+00, 1.001510255591984e+00, 1.001456670257582e+00, - 1.001400647864737e+00, 1.001342321400680e+00, 1.001281821522569e+00, 1.001219276707368e+00, 1.001154813393807e+00, - 1.001088556116027e+00, 1.001020627628542e+00, 1.000951149022254e+00, 1.000880239831253e+00, 1.000808018130249e+00, - 1.000734600622500e+00, 1.000660102718162e+00, 1.000584638603047e+00, 1.000508321297830e+00, 1.000431262707766e+00, - 1.000353573663063e+00, 1.000275363950073e+00, 1.000196742333506e+00, 1.000117816569928e+00, 1.000038693412811e+00, - 9.999594786094657e-01, 9.998802768901784e-01, 9.998011919499361e-01, 9.997223264231200e-01, 9.996437818515729e-01, - 9.995656586464663e-01, 9.994880560443949e-01, 9.994110720581462e-01, 9.993348034225887e-01, 9.992593455361456e-01, - 9.991847923983630e-01, 9.991112365446738e-01, 9.990387692132843e-01, 9.989674755310745e-01, 9.988974493950561e-01, - 9.988287760995599e-01, 9.987615392519850e-01, 9.986958206712464e-01, 9.986317002885794e-01, 9.985692560508309e-01, - 9.985085638263473e-01, 9.984496973135677e-01, 9.983927279524338e-01, 9.983377248387103e-01, 9.982847546413267e-01, - 9.982338815228151e-01, 9.981851670629547e-01, 9.981386701856864e-01, 9.980944470893998e-01, 9.980525511806362e-01, - 9.980130330113137e-01, 9.979759402195160e-01, 9.979413174739102e-01, 9.979092064218532e-01, 9.978796456412409e-01, - 9.978526705961338e-01, 9.978283135962164e-01, 9.978066037601111e-01, 9.977875669825975e-01, 9.977712259057413e-01, - 9.977575998939762e-01, 9.977467050131418e-01, 9.977385540135004e-01, 9.977331563167335e-01, 9.977305180069234e-01, - 9.977306418255271e-01, 9.977335271703227e-01, 9.977391700983312e-01, 9.977475633326937e-01, 9.977586962734870e-01, - 9.977725550124530e-01, 9.977891223516203e-01, 9.978083778257809e-01, 9.978302977287913e-01, 9.978548551436590e-01, - 9.978820199763681e-01, 9.979117589934062e-01, 9.979440358629286e-01, 9.979788111995230e-01, 9.980160426125044e-01, - 9.980556847576850e-01, 9.980976893925572e-01, 9.981420054348167e-01, 9.981885790241626e-01, 9.982373535872919e-01, - 9.982882699060266e-01, 9.983412661884745e-01, 9.983962781431597e-01, 9.984532390560278e-01, 9.985120798702389e-01, - 9.985727292686638e-01, 9.986351137589832e-01, 9.986991577612992e-01, 9.987647836981626e-01, 9.988319120869124e-01, - 9.989004616342260e-01, 9.989703493327806e-01, 9.990414905599119e-01, 9.991137991781697e-01, 9.991871876376540e-01, - 9.992615670800187e-01, 9.993368474440421e-01, 9.994129375726286e-01, 9.994897453211379e-01, 9.995671776669227e-01, - 9.996451408199485e-01, 9.997235403343790e-01, 9.998022812210010e-01, 9.998812680603694e-01, 9.999604051165407e-01, - 1.000039596451276e+00, 1.000118746038578e+00, 1.000197757879446e+00, 1.000276536116704e+00, 1.000354985149791e+00, - 1.000433009749368e+00, 1.000510515171617e+00, 1.000587407272111e+00, 1.000663592619100e+00, 1.000738978606112e+00, - 1.000813473563716e+00, 1.000886986870324e+00, 1.000959429061901e+00, 1.001030711940457e+00, 1.001100748681180e+00, - 1.001169453938098e+00, 1.001236743948124e+00, 1.001302536633371e+00, 1.001366751701609e+00, 1.001429310744728e+00, - 1.001490137335098e+00, 1.001549157119701e+00, 1.001606297911910e+00, 1.001661489780803e+00, 1.001714665137891e+00, - 1.001765758821160e+00, 1.001814708176293e+00, 1.001861453134992e+00, 1.001905936290265e+00, 1.001948102968611e+00, - 1.001987901298963e+00, 1.002025282278336e+00, 1.002060199834045e+00, 1.002092610882449e+00, 1.002122475384096e+00, - 1.002149756395215e+00, 1.002174420115472e+00, 1.002196435931912e+00, 1.002215776459027e+00, 1.002232417574884e+00, - 1.002246338453259e+00, 1.002257521591717e+00, 1.002265952835595e+00, 1.002271621397855e+00, 1.002274519874744e+00, - 1.002274644257259e+00, 1.002271993938374e+00, 1.002266571716010e+00, 1.002258383791734e+00, 1.002247439765192e+00, - 1.002233752624241e+00, 1.002217338730821e+00, 1.002198217802551e+00, 1.002176412890066e+00, 1.002151950350129e+00, - 1.002124859814529e+00, 1.002095174154815e+00, 1.002062929442886e+00, 1.002028164907501e+00, 1.001990922886739e+00, - 1.001951248776490e+00, 1.001909190975020e+00, 1.001864800823684e+00, 1.001818132543870e+00, 1.001769243170239e+00, - 1.001718192480350e+00, 1.001665042920779e+00, 1.001609859529789e+00, 1.001552709856694e+00, 1.001493663877992e+00, - 1.001432793910387e+00, 1.001370174520822e+00, 1.001305882433629e+00, 1.001239996434927e+00, 1.001172597274394e+00, - 1.001103767564540e+00, 1.001033591677623e+00, 1.000962155640339e+00, 1.000889547026422e+00, 1.000815854847318e+00, - 1.000741169441052e+00, 1.000665582359457e+00, 1.000589186253905e+00, 1.000512074759701e+00, 1.000434342379282e+00, - 1.000356084364390e+00, 1.000277396597363e+00, 1.000198375471716e+00, 1.000119117772151e+00, 1.000039720554179e+00, - 9.999602810234808e-01, 9.998808964152024e-01, 9.998016638733073e-01, 9.997226803301702e-01, 9.996440423865509e-01, - 9.995658461921156e-01, 9.994881873266507e-01, 9.994111606821270e-01, 9.993348603457636e-01, 9.992593794842417e-01, - 9.991848102292076e-01, 9.991112435642227e-01, 9.990387692132843e-01, 9.989674755310747e-01, 9.988974493950561e-01, - 9.988287760995599e-01, 9.987615392519850e-01, 9.986958206712466e-01, 9.986317002885796e-01, 9.985692560508309e-01, - 9.985085638263473e-01, 9.984496973135679e-01, 9.983927279524338e-01, 9.983377248387103e-01, 9.982847546413269e-01, - 9.982338815228151e-01, 9.981851670629547e-01, 9.981386701856864e-01, 9.980944470893998e-01, 9.980525511806362e-01, - 9.980130330113137e-01, 9.979759402195162e-01, 9.979413174739102e-01, 9.979092064218532e-01, 9.978796456412409e-01, - 9.978526705961338e-01, 9.978283135962164e-01, 9.978066037601111e-01, 9.977875669825975e-01, 9.977712259057413e-01, - 9.977575998939762e-01, 9.977467050131418e-01, 9.977385540135004e-01, 9.977331563167335e-01, 9.977305180069234e-01, - 9.977306418255271e-01, 9.977335271703227e-01, 9.977391700983312e-01, 9.977475633326937e-01, 9.977586962734870e-01, - 9.977725550124529e-01, 9.977891223516203e-01, 9.978083778257809e-01, 9.978302977287912e-01, 9.978548551436589e-01, - 9.978820199763679e-01, 9.979117589934061e-01, 9.979440358629285e-01, 9.979788111995229e-01, 9.980160426125043e-01, - 9.980556847576849e-01, 9.980976893925571e-01, 9.981420054348165e-01, 9.981885790241625e-01, 9.982373535872917e-01, - 9.982882699060264e-01, 9.983412661884743e-01, 9.983962781431595e-01, 9.984532390560276e-01, 9.985120798702387e-01, - 9.985727292686636e-01, 9.986351137589830e-01, 9.986991577612990e-01, 9.987647836981624e-01, 9.988319120869121e-01, - 9.989004616342257e-01, 9.989703493327803e-01, 9.990414905599115e-01, 9.991137991781693e-01, 9.991871876376537e-01, - 9.992615670800183e-01, 9.993368474440417e-01, 9.994129375726283e-01, 9.994897453211377e-01, 9.995671776669224e-01, - 9.996451408199482e-01, 9.997235403343787e-01, 9.998022812210007e-01, 9.998812680603690e-01, 9.999604051165404e-01, - 1.000039596451276e+00, 1.000118746038578e+00, 1.000197757879445e+00, 1.000276536116703e+00, 1.000354985149791e+00, - 1.000433009749367e+00, 1.000510515171617e+00, 1.000587407272111e+00, 1.000663592619099e+00, 1.000738978606111e+00, - 1.000813473563715e+00, 1.000886986870324e+00, 1.000959429061901e+00, 1.001030711940456e+00, 1.001100748681180e+00, - 1.001169453938098e+00, 1.001236743948123e+00, 1.001302536633371e+00, 1.001366751701609e+00, 1.001429310744728e+00, - 1.001490137335098e+00, 1.001549157119701e+00, 1.001606297911910e+00, 1.001661489780802e+00, 1.001714665137891e+00, - 1.001765758821160e+00, 1.001814708176293e+00, 1.001861453134991e+00, 1.001905936290265e+00, 1.001948102968610e+00, - 1.001987901298963e+00, 1.002025282278336e+00, 1.002060199834045e+00, 1.002092610882449e+00, 1.002122475384096e+00, - 1.002149756395215e+00, 1.002174420115472e+00, 1.002196435931912e+00, 1.002215776459027e+00, 1.002232417574884e+00, - 1.002246338453259e+00, 1.002257521591717e+00, 1.002265952835595e+00, 1.002271621397855e+00, 1.002274519874744e+00, - 1.002274644257259e+00, 1.002271993938374e+00, 1.002266571716010e+00, 1.002258383791734e+00, 1.002247439765192e+00, - 1.002233752624241e+00, 1.002217338730821e+00, 1.002198217802551e+00, 1.002176412890066e+00, 1.002151950350129e+00, - 1.002124859814529e+00, 1.002095174154815e+00, 1.002062929442886e+00, 1.002028164907501e+00, 1.001990922886739e+00, - 1.001951248776490e+00, 1.001909190975020e+00, 1.001864800823684e+00, 1.001818132543870e+00, 1.001769243170239e+00, - 1.001718192480350e+00, 1.001665042920779e+00, 1.001609859529789e+00, 1.001552709856694e+00, 1.001493663877992e+00, - 1.001432793910387e+00, 1.001370174520822e+00, 1.001305882433629e+00, 1.001239996434927e+00, 1.001172597274394e+00, - 1.001103767564540e+00, 1.001033591677624e+00, 1.000962155640339e+00, 1.000889539994377e+00, 1.000815836987349e+00, - 1.000741135442554e+00, 1.000665525360320e+00, 1.000589097525086e+00, 1.000511943342175e+00, 1.000434154669159e+00, - 1.000355823641039e+00, 1.000277042489024e+00, 1.000197903352750e+00, 1.000118498085805e+00, 1.000038918054429e+00, - 9.999592539292592e-01, 9.998795954700279e-01, 9.998000313030908e-01, 9.997206486917303e-01, 9.996415332991556e-01, - 9.995627689441696e-01, 9.994844373494816e-01, 9.994066178826749e-01, 9.993293872898719e-01, 9.992528194221602e-01, - 9.991769849548788e-01, 9.991019510999088e-01, 9.990277813111228e-01, 9.989545349832153e-01, 9.988822671441485e-01, - 9.988110281415057e-01, 9.987408633230653e-01, 9.986718127119733e-01, 9.986039106768975e-01, 9.985371855976206e-01, - 9.984716595265433e-01, 9.984073478466060e-01, 9.983442589261942e-01, 9.982823937715852e-01, 9.982217456775688e-01, - 9.981622998768528e-01, 9.981040331889378e-01, 9.980469136691089e-01, 9.979909002582600e-01, 9.979359424342189e-01, - 9.978819798653003e-01, 9.978289420667763e-01, 9.977767480609429e-01, 9.977253060414770e-01, 9.976745130427335e-01, - 9.976242546146024e-01, 9.975744045035392e-01, 9.975248243403034e-01, 9.974753633349420e-01, 9.974258579794437e-01, - 9.973761317584910e-01, 9.973259948686257e-01, 9.972752439461025e-01, 9.972236618036201e-01, 9.971710171760355e-01, - 9.971170644751025e-01, 9.970615435531658e-01, 9.970041794756773e-01, 9.969446823022998e-01, 9.968827468762742e-01, - 9.968180526216487e-01, 9.967502633478675e-01, 9.966790270611490e-01, 9.966039757819899e-01, 9.965247253680732e-01, - 9.964408753417748e-01, 9.963520087214246e-01, 9.962576918554058e-01, 9.961574742581648e-01, 9.960508884471466e-01, - 9.959374497796830e-01, 9.958166562888472e-01, 9.956879885173003e-01, 9.955509093482032e-01, 9.954048638322855e-01, - 9.952492790102677e-01, 9.950835637298708e-01, 9.949071084567831e-01, 9.947192850790569e-01, 9.945194467045426e-01, - 9.943069274511299e-01, 9.940810422297355e-01, 9.938410865201561e-01, 9.935863361401250e-01, 9.933160470081145e-01, - 9.930294549006624e-01, 9.927257752052461e-01, 9.924042026699723e-01, 9.920639111516145e-01, 9.917040533637881e-01, - 9.913237606273204e-01, 9.909221426251413e-01, 9.904982871642726e-01, 9.900512599477517e-01, 9.895801043595820e-01, - 9.890838412660165e-01, 9.885614688367104e-01, 9.880119623894829e-01, 9.874342742625883e-01, 9.868273337185698e-01, - 9.861900468838825e-01, 9.855212967285775e-01, 9.848199430904010e-01, 9.840848227476926e-01, 9.833147495454723e-01, - 9.825085145790535e-01, 9.816648864394526e-01, 9.807826115247470e-01, 9.798604144213754e-01, 9.788969983591844e-01, - 9.778910457438047e-01, 9.768412187696544e-01, 9.757461601165864e-01, 9.746044937328510e-01, 9.734148257066850e-01, - 9.721757452284399e-01, 9.708858256447525e-01, 9.695436256058197e-01, 9.681476903063706e-01, 9.666965528204767e-01, - 9.651887355298391e-01, 9.636227516447159e-01, 9.619971068161570e-01, 9.603103008377231e-01, 9.585608294343847e-01, - 9.567471861358257e-01, 9.548678642309127e-01, 9.529213587996556e-01, 9.509061688185575e-01, 9.488207993348687e-01, - 9.466637637048801e-01, 9.444335858910574e-01, 9.421288028125191e-01, 9.397479667430725e-01, 9.372896477508165e-01, - 9.347524361730808e-01, 9.321349451203507e-01, 9.294358130026688e-01, 9.266537060719486e-01, 9.237873209735582e-01, - 9.208353873005455e-01, 9.177966701438771e-01, 9.146699726321402e-01, 9.114541384542267e-01, 9.081480543586499e-01, - 9.047506526232865e-01, 9.012609134895138e-01, 8.976778675548984e-01, 8.940005981188177e-01, 8.902282434756291e-01, - 8.863599991502473e-01, 8.823951200712559e-01, 8.783329226769567e-01, 8.741727869500308e-01, 8.699141583767795e-01, - 8.655565498272043e-01, 8.610995433524644e-01, 8.565427918965455e-01, 8.518860209192624e-01, 8.471290299279841e-01, - 8.422716939157602e-01, 8.373139647037767e-01, 8.322558721863335e-01, 8.270975254767841e-01, 8.218391139531005e-01, - 8.164809082019563e-01, 8.110232608604324e-01, 8.054666073546400e-01, 7.998114665347398e-01, 7.940584412060114e-01, - 7.882082185557775e-01, 7.822615704761332e-01, 7.762193537825687e-01, 7.700825103286711e-01, 7.638520670172276e-01, - 7.575291357081170e-01, 7.511149130234813e-01, 7.446106800507299e-01, 7.380178019439980e-01, 7.313377274247339e-01, - 7.245719881821328e-01, 7.177221981741801e-01, 7.107900528300912e-01, 7.037773281549656e-01, 6.966858797374927e-01, - 6.895176416615646e-01, 6.822746253226608e-01, 6.749589181498854e-01, 6.675726822345424e-01, 6.601181528661474e-01, - 6.525976369767750e-01, 6.450135114946609e-01, 6.373682216079785e-01, 6.296642789397278e-01, 6.219042596346939e-01, - 6.140908023594462e-01, 6.062266062163840e-01, 5.983144285728536e-01, 5.903570828064187e-01, 5.823574359673894e-01, - 5.743184063597853e-01, 5.662429610419641e-01, 5.581341132482169e-01, 5.499949197327134e-01, 5.418284780372742e-01, - 5.336379236845493e-01, 5.254264272982935e-01, 5.171971916525543e-01, 5.089534486517354e-01, 5.006984562436330e-01, - 4.924354952677195e-01, 4.841678662411154e-01, 4.758988860848792e-01, 4.676318847934465e-01, 4.593702020502552e-01, - 4.511171837928217e-01, 4.428761787307617e-01, 4.346505348204885e-01, 4.264435957005810e-01, 4.182586970920628e-01, - 4.100991631681045e-01, 4.019683028979270e-01, 3.938694063699639e-01, 3.858057410996029e-01, 3.777805483271167e-01, - 3.697970393116528e-01, 3.618583916274267e-01, 3.539677454685226e-01, 3.461281999689568e-01, 3.383428095449016e-01, - 3.306145802661934e-01, 3.229464662644602e-01, 3.153413661853912e-01, 3.078021196928487e-01, 3.003315040326600e-01, - 2.929322306640503e-01, 2.856069419667691e-01, 2.783582080320176e-01, 2.711885235453130e-01, 2.641003047694161e-01, - 2.570958866354019e-01, 2.501775199498664e-01, 2.433473687261406e-01, 2.366075076472159e-01, 2.299599196678819e-01, - 2.234064937633224e-01, 2.169490228311333e-01, 2.105892017533920e-01, 2.043286256250337e-01, 1.981687881543829e-01, - 1.921110802412354e-01, 1.861567887374030e-01, 1.803070953941089e-01, 1.745630760000725e-01, 1.689256997135387e-01, - 1.633958285908989e-01, 1.579742173139196e-01, 1.526615131169428e-01, 1.474582559147575e-01, 1.423648786311610e-01, - 1.373817077275422e-01, 1.325089639301291e-01, 1.277467631538520e-01, 1.230951176200877e-01, 1.185539371648735e-01, - 1.141230307335134e-01, 1.098021080568559e-01, 1.055907815038885e-01, 1.014885681047006e-01, 9.749489173728383e-02, - 9.360908547110176e-02, 8.983039405984916e-02, 8.615797657535108e-02, 8.259090917411954e-02, 7.912818798769637e-02, - 7.576873212756439e-02, 7.251138679510837e-02, 6.935492648685226e-02, 6.629805828499362e-02, 6.333942522309385e-02, - 6.047760971667378e-02, 5.771113704839873e-02, 5.503847889751997e-02, 5.245805690326935e-02, 4.996824625197753e-02, - 4.756737927780486e-02, 4.525374906713279e-02, 4.302561305686507e-02, 4.088119661712488e-02, 3.881869660910822e-02, - 3.683628490916042e-02, 3.493211189048053e-02, 3.310430985422298e-02, 3.135099640215624e-02, 2.967027774345144e-02, - 2.806025192860465e-02, 2.651901200394490e-02, 2.504464908064207e-02, 2.363525531259980e-02, 2.228892677809941e-02, - 2.100376626054477e-02, 1.977788592414561e-02, 1.860940988086348e-02, 1.749647664542867e-02, 1.643724147571549e-02, - 1.542987859623567e-02, 1.447258330297169e-02, 1.356357394822445e-02, 1.270109380458789e-02, 1.188341280758823e-02, - 1.110882917693435e-02, 1.037567091671765e-02, 9.682297195274189e-03, 9.027099605776615e-03, 8.408503308959755e-03, - 7.824968059698375e-03, 7.274989119451309e-03, 6.757098056859764e-03, 6.269863439040749e-03, 5.811891416348594e-03, - 5.381826203588412e-03, 4.978350460855568e-03, 4.600185577345007e-03, 4.246091861623697e-03, 3.914868641989499e-03, - 3.605354280650456e-03, 3.316426105550754e-03, 3.047000263743920e-03, 2.796031500270941e-03, 2.562512866541615e-03, - 2.345475362242355e-03, 2.143987514803593e-03, 1.957154900455791e-03, 1.784119610885449e-03, 1.624059669472490e-03, - 1.476188401048562e-03, 1.339753759063066e-03, 1.214037613980937e-03, 1.098355006663937e-03, 9.920533704065749e-04, - 8.945117252091245e-04, 8.051398477746440e-04, 7.233774206148687e-04, 6.486931635421752e-04, 5.805839507121312e-04, - 5.185739162640836e-04, 4.622135514864277e-04, 4.110787963092279e-04, 3.647701278002823e-04, 3.229116482121258e-04, - 2.851501749972799e-04, 2.511543350778764e-04, 2.206136655240024e-04, 1.932377226631928e-04, 1.687552015118974e-04, - 1.469130672888079e-04, 1.274757006400757e-04, 1.102240580780130e-04, 9.495484900818888e-05, 8.147973059522124e-05, - 6.962452159532738e-05, 5.922843616409273e-05, 5.014333853121625e-05, 4.223301932042882e-05, 3.537249418257647e-05, - 2.944732530322636e-05, 2.435296624327736e-05, 1.999413047212912e-05, 1.628418385815330e-05, 1.314456129070047e-05, - 1.050420752185282e-05, 8.299042234809909e-06, 6.471449269445341e-06, 4.969789864549787e-06, 3.747939711067031e-06, - 2.764849551822885e-06, 1.984129011158285e-06, 1.373653290393152e-06, 9.051923062411747e-07, 5.540616821452014e-07, - 2.987940262820261e-07, 1.208186781658135e-07, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00 +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_40_e_8000, lpc_lin_pre_emphasis_80_e_16000, lpc_lin_pre_emphasis_40_e_24000, + lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_80_e_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_e_0_92 +#endif }; -const LC3_FLOAT MDCT_WINDOW_80_7_5ms[120] = {0.00295060859318731, - 0.00717541131643851, - 0.0137695373537175, - 0.0230953556487727, - 0.0354036229832600, - 0.0508289303571015, - 0.0694696292595147, - 0.0913884277813343, - 0.116604574829623, - 0.145073545983920, - 0.176711174053461, - 0.211342952955480, - 0.248768614459915, - 0.288701101746986, - 0.330823871149994, - 0.374814544406725, - 0.420308013047231, - 0.466904917964874, - 0.514185341357833, - 0.561710040666941, - 0.609026346152434, - 0.655671016213410, - 0.701218384229819, - 0.745240678762236, - 0.787369206048433, - 0.827223833436804, - 0.864513675018828, - 0.898977414612621, - 0.930407517984552, - 0.958599937397485, - 0.983447719378423, - 1.00488283328902, - 1.02285380727854, - 1.03740494796704, - 1.04859791420260, - 1.05656184342744, - 1.06149370624356, - 1.06362578371698, - 1.06325972797388, - 1.06074504835117, - 1.05643589789450, - 1.05069500101126, - 1.04392434506884, - 1.03647724602858, - 1.02872867366600, - 1.02106485991803, - 1.01400658226217, - 1.00727455010293, - 1.00172249743714, - 0.997309591666583, - 0.993985158260167, - 0.991683334808959, - 0.990325325024913, - 0.989822612537615, - 0.990074733989367, - 0.990975314368959, - 0.992412851225652, - 0.994273149357862, - 0.996439157431590, - 0.998791615753409, - 1.00120984620569, - 1.00357356747961, - 1.00575983636472, - 1.00764515369282, - 1.00910687229055, - 1.01002476446464, - 1.01028203168272, - 1.00976918870054, - 1.00838641217324, - 1.00605123898466, - 1.00269766615693, - 0.998280464458421, - 0.992777986793980, - 0.986186892168957, - 0.977634164392255, - 0.967447269570116, - 0.955129725416117, - 0.940389877411592, - 0.922959279964298, - 0.902607349937268, - 0.879202688562948, - 0.852641749726566, - 0.822881271616311, - 0.789971715171577, - 0.754030327670636, - 0.715255741732847, - 0.673936911240907, - 0.630414716229245, - 0.585078857908467, - 0.538398518296620, - 0.490833753173281, - 0.442885823257372, - 0.395091024053755, - 0.348004343198510, - 0.302196710240947, - 0.258227430580528, - 0.216641416438901, - 0.177922121520115, - 0.142480547128767, - 0.110652194335372, - 0.0826995966952829, - 0.0588334516201313, - 0.0392030848454565, - 0.0238629107447942, - 0.0126976223424625, - 0.00535665361021599, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}; - -const LC3_FLOAT MDCT_WINDOW_160_7_5ms[240] = {0.00220824874304665, - 0.00381014419509035, - 0.00591552473428981, - 0.00858361456803004, - 0.0118759722608345, - 0.0158335301409709, - 0.0204918651551601, - 0.0258883592892154, - 0.0320415894481754, - 0.0389616721239547, - 0.0466742169139349, - 0.0551849337276135, - 0.0645038384438376, - 0.0746411071480673, - 0.0856000161887899, - 0.0973846702504817, - 0.109993602538973, - 0.123419277472281, - 0.137655456547628, - 0.152690437463956, - 0.168513362640497, - 0.185093104613143, - 0.202410419487986, - 0.220450365133188, - 0.239167940620308, - 0.258526168288333, - 0.278498538773636, - 0.299038431599591, - 0.320104862365552, - 0.341658622243036, - 0.363660034025212, - 0.386062695189504, - 0.408815272459443, - 0.431871045845866, - 0.455176987704814, - 0.478676592635263, - 0.502324813138104, - 0.526060916224847, - 0.549831282885023, - 0.573576882777006, - 0.597241338441034, - 0.620770242419397, - 0.644099662433612, - 0.667176381676395, - 0.689958853765865, - 0.712379980093130, - 0.734396371869479, - 0.755966688050532, - 0.777036981101517, - 0.797558113689794, - 0.817490855531114, - 0.836796949640853, - 0.855447309567916, - 0.873400798399116, - 0.890635718969808, - 0.907128770123878, - 0.922848783570288, - 0.937763322534182, - 0.951860206252747, - 0.965130600153629, - 0.977556540546725, - 0.989126208677996, - 0.999846919168316, - 1.00970072970387, - 1.01868228690835, - 1.02681455085919, - 1.03408981275172, - 1.04051195662940, - 1.04610836852236, - 1.05088564953428, - 1.05486288757866, - 1.05807220584955, - 1.06053413867011, - 1.06227661751764, - 1.06333815026019, - 1.06375556676696, - 1.06356632061806, - 1.06282155753012, - 1.06155995891758, - 1.05981709158148, - 1.05765876038451, - 1.05512005736540, - 1.05223985071955, - 1.04908778571338, - 1.04569859514623, - 1.04210830682439, - 1.03838098558867, - 1.03455276253936, - 1.03067199718128, - 1.02679166694268, - 1.02295558402234, - 1.01920733213785, - 1.01587288719722, - 1.01221017459353, - 1.00884559103696, - 1.00577851248622, - 1.00300261849896, - 1.00051460180915, - 0.998309228756053, - 0.996378601374572, - 0.994718132279737, - 0.993316215711850, - 0.992166956964939, - 0.991258602708851, - 0.990581103872326, - 0.990123118186375, - 0.989873711994700, - 0.989818706664725, - 0.989946800178719, - 0.990243175367708, - 0.990695563551443, - 0.991288540103593, - 0.992009469063567, - 0.992842692750141, - 0.993775066630664, - 0.994790397982872, - 0.995875533622126, - 0.997014367015673, - 0.998192870684212, - 0.999394506476233, - 1.00060586036830, - 1.00181040094441, - 1.00299457368229, - 1.00414154805357, - 1.00523688409909, - 1.00626392589064, - 1.00720890358777, - 1.00805489381465, - 1.00878801634839, - 1.00939182206005, - 1.00985295821773, - 1.01015529301117, - 1.01028601830489, - 1.01022987870331, - 1.00997540773688, - 1.00950845528029, - 1.00881848315592, - 1.00789488400120, - 1.00672875785417, - 1.00530991398353, - 1.00363456081898, - 1.00169363479295, - 0.999485662869670, - 0.997006370229165, - 0.994254686877395, - 0.991231967393677, - 0.987937115334337, - 0.984375124686103, - 0.979890963312768, - 0.975269878842859, - 0.970180498004025, - 0.964580026820328, - 0.958425533515528, - 0.951684013845583, - 0.944320232231505, - 0.936290624169877, - 0.927580506944232, - 0.918153413723035, - 0.907976524013806, - 0.897050058479312, - 0.885351360384818, - 0.872857926504400, - 0.859579818650462, - 0.845502615038655, - 0.830619943301480, - 0.814946648157534, - 0.798489377529441, - 0.781262449660145, - 0.763291769255088, - 0.744590843420388, - 0.725199287080917, - 0.705153668360855, - 0.684490544603819, - 0.663245209931378, - 0.641477161661819, - 0.619235333635541, - 0.596559132542786, - 0.573519989364814, - 0.550173851023454, - 0.526568538230013, - 0.502781158663802, - 0.478860889056198, - 0.454877894349081, - 0.430898122898976, - 0.406993964205627, - 0.383234030582781, - 0.359680098334456, - 0.336408100091304, - 0.313496418152647, - 0.291010565493871, - 0.269019585108746, - 0.247584347561867, - 0.226788433385199, - 0.206677770653849, - 0.187310343238419, - 0.168739644125069, - 0.151012382058898, - 0.134171842279709, - 0.118254662325635, - 0.103290733977460, - 0.0893117360272552, - 0.0763429786604178, - 0.0644077291458590, - 0.0535243714739393, - 0.0437084452819923, - 0.0349667099153409, - 0.0272984629264830, - 0.0206895808034878, - 0.0151125125235276, - 0.0105228753811890, - 0.00685547314312078, - 0.00402351119094097, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}; - -const LC3_FLOAT MDCT_WINDOW_240_7_5ms[360] = {0.00197084907651299, - 0.00295060859318731, - 0.00412447721346795, - 0.00552688663943736, - 0.00717541131643851, - 0.00908757730429167, - 0.0112819105170366, - 0.0137695373537175, - 0.0165600266160529, - 0.0196650894549232, - 0.0230953556487727, - 0.0268612893898298, - 0.0309632559743172, - 0.0354036229832600, - 0.0401915610110090, - 0.0453331403333732, - 0.0508289303571015, - 0.0566815447853484, - 0.0628935304464015, - 0.0694696292595147, - 0.0764106313680933, - 0.0837160015651998, - 0.0913884277813343, - 0.0994294007679240, - 0.107834724972307, - 0.116604574829623, - 0.125736502786435, - 0.135226811339595, - 0.145073545983920, - 0.155273818664872, - 0.165822194234144, - 0.176711174053461, - 0.187928775884881, - 0.199473179818881, - 0.211342952955480, - 0.223524554031808, - 0.236003099651800, - 0.248768614459915, - 0.261813810748989, - 0.275129160854431, - 0.288701101746986, - 0.302514033630995, - 0.316558805236645, - 0.330823871149994, - 0.345295566673095, - 0.359963991566213, - 0.374814544406725, - 0.389831816553239, - 0.405001009601585, - 0.420308013047231, - 0.435739515285996, - 0.451277817354750, - 0.466904917964874, - 0.482609040567348, - 0.498375466266412, - 0.514185341357833, - 0.530021478313683, - 0.545869351788699, - 0.561710040666941, - 0.577528151441720, - 0.593304696426258, - 0.609026346152434, - 0.624674188938691, - 0.640227554714632, - 0.655671016213410, - 0.670995934643907, - 0.686184558797250, - 0.701218384229819, - 0.716078448562218, - 0.730756084155059, - 0.745240678762236, - 0.759515121573879, - 0.773561955408612, - 0.787369206048433, - 0.800923137730798, - 0.814211386313193, - 0.827223833436804, - 0.839952374193807, - 0.852386102361013, - 0.864513675018828, - 0.876324078835538, - 0.887814288392476, - 0.898977414612621, - 0.909803318928109, - 0.920284311925309, - 0.930407517984552, - 0.940169652216635, - 0.949567794930265, - 0.958599937397485, - 0.967260260011783, - 0.975545165941725, - 0.983447719378423, - 0.990971957260661, - 0.998119268644039, - 1.00488283328902, - 1.01125773114014, - 1.01724436218938, - 1.02285380727854, - 1.02808733870912, - 1.03293706325880, - 1.03740494796704, - 1.04150164119898, - 1.04523235573095, - 1.04859791420260, - 1.05160339500287, - 1.05425505026848, - 1.05656184342744, - 1.05853400282251, - 1.06017413540787, - 1.06149370624356, - 1.06249943033024, - 1.06320577147234, - 1.06362578371698, - 1.06376486534444, - 1.06363777833448, - 1.06325972797388, - 1.06264695324506, - 1.06180496269951, - 1.06074504835117, - 1.05948491573959, - 1.05804533277758, - 1.05643589789450, - 1.05466217871738, - 1.05274047445925, - 1.05069500101126, - 1.04853893535431, - 1.04627898264892, - 1.04392434506884, - 1.04149539738413, - 1.03901002688052, - 1.03647724602858, - 1.03390792836167, - 1.03131989375422, - 1.02872867366600, - 1.02614831936266, - 1.02358988084027, - 1.02106485991803, - 1.01856261937655, - 1.01655770337597, - 1.01400658226217, - 1.01162952586308, - 1.00938590180064, - 1.00727455010293, - 1.00529616458224, - 1.00344525988730, - 1.00172249743714, - 1.00012792446354, - 0.998657533466906, - 0.997309591666583, - 0.996083571092922, - 0.994976568981429, - 0.993985158260167, - 0.993107530052222, - 0.992341305231054, - 0.991683334808959, - 0.991130069631426, - 0.990678325164172, - 0.990325325024913, - 0.990067562181601, - 0.989901281872290, - 0.989822612537615, - 0.989827845401607, - 0.989913241125937, - 0.990074733989367, - 0.990308255838731, - 0.990609851788114, - 0.990975314368959, - 0.991400330446183, - 0.991880966170107, - 0.992412851225652, - 0.992991779075812, - 0.993613381385812, - 0.994273149357862, - 0.994966957785808, - 0.995690370111366, - 0.996439157431590, - 0.997208572194836, - 0.997994274967679, - 0.998791615753409, - 0.999596061975986, - 1.00040410125588, - 1.00120984620569, - 1.00200975605034, - 1.00279924168624, - 1.00357356747961, - 1.00432828318722, - 1.00505850186763, - 1.00575983636472, - 1.00642766968907, - 1.00705768272393, - 1.00764515369282, - 1.00818549211731, - 1.00867426536962, - 1.00910687229055, - 1.00947915891906, - 1.00978659331994, - 1.01002476446464, - 1.01018953828983, - 1.01027669068480, - 1.01028203168272, - 1.01020174265116, - 1.01003208083751, - 1.00976918870054, - 1.00940938607321, - 1.00894931012624, - 1.00838641217324, - 1.00771780306692, - 1.00694030579691, - 1.00605123898466, - 1.00504879328336, - 1.00393182763047, - 1.00269766615693, - 1.00134427117215, - 0.999872091899038, - 0.998280464458421, - 0.996566569174198, - 0.994731737005642, - 0.992777986793980, - 0.990701374188107, - 0.988504165244528, - 0.986186892168957, - 0.983711988683984, - 0.980584643109501, - 0.977634164392255, - 0.974455033150736, - 0.971062915561309, - 0.967447269570116, - 0.963593926287407, - 0.959491398347322, - 0.955129725416117, - 0.950501325912076, - 0.945592810314402, - 0.940389877411592, - 0.934886760414132, - 0.929080558710635, - 0.922959279964298, - 0.916509579192867, - 0.909724456073370, - 0.902607349937268, - 0.895155083757719, - 0.887356154208250, - 0.879202688562948, - 0.870699697841629, - 0.861847424457935, - 0.852641749726566, - 0.843077833241503, - 0.833154904680532, - 0.822881271616311, - 0.812257596919709, - 0.801285439243471, - 0.789971715171577, - 0.778318177172464, - 0.766337710411639, - 0.754030327670636, - 0.741407990945757, - 0.728477500803539, - 0.715255741732847, - 0.701751739457159, - 0.687975631811811, - 0.673936911240907, - 0.659652573201310, - 0.645139489066839, - 0.630414716229245, - 0.615483621927165, - 0.600365851941398, - 0.585078857908467, - 0.569649536456405, - 0.554084809831234, - 0.538398518296620, - 0.522614737753751, - 0.506756804966295, - 0.490833753173273, - 0.474866032652527, - 0.458876565810813, - 0.442885823257372, - 0.426906539230033, - 0.410970973391487, - 0.395091024053754, - 0.379291327017083, - 0.363587416985863, - 0.348004343198509, - 0.332563200617546, - 0.317287484882341, - 0.302196710240947, - 0.287309402575471, - 0.272643991600386, - 0.258227430580528, - 0.244072856174013, - 0.230208977382347, - 0.216641416438901, - 0.203398480689705, - 0.190486161546394, - 0.177922121520115, - 0.165726674483589, - 0.153906396679985, - 0.142480547128767, - 0.131453980101158, - 0.120841778238095, - 0.110652194335372, - 0.100891734193622, - 0.0915718850864754, - 0.0826995966952829, - 0.0742815528886268, - 0.0663242381533172, - 0.0588334516201312, - 0.0518140676237795, - 0.0452698345565108, - 0.0392030848454564, - 0.0336144159421411, - 0.0285023308156286, - 0.0238629107447942, - 0.0196894226553178, - 0.0159720527024086, - 0.0126976223424625, - 0.00984937739446455, - 0.00740724463299836, - 0.00535665361021599, - 0.00383226551874691, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}; - -const LC3_FLOAT MDCT_WINDOW_320_7_5ms[480] = {0.00184833037060189, - 0.00256481839443054, - 0.00336762117525576, - 0.00428736617294702, - 0.00533830142913148, - 0.00652679222980445, - 0.00786112587274496, - 0.00934628179329417, - 0.0109916867707302, - 0.0128011172432759, - 0.0147805910526259, - 0.0169307043075075, - 0.0192592307040902, - 0.0217696937210109, - 0.0244685982614465, - 0.0273556542738590, - 0.0304319230257638, - 0.0336980463900663, - 0.0371583577255157, - 0.0408148179520755, - 0.0446708068423474, - 0.0487262995262562, - 0.0529820632544155, - 0.0574382469666485, - 0.0620968579875224, - 0.0669609766608529, - 0.0720298363678982, - 0.0773039146477137, - 0.0827825574095362, - 0.0884682101593173, - 0.0943607566451845, - 0.100460272003600, - 0.106763823750452, - 0.113273679440610, - 0.119986420273010, - 0.126903520680586, - 0.134020853127777, - 0.141339556870128, - 0.148857211288972, - 0.156573685338126, - 0.164484622056357, - 0.172589076538143, - 0.180879089820471, - 0.189354319600685, - 0.198012243528402, - 0.206854140994642, - 0.215875318757054, - 0.225068672370813, - 0.234427407249969, - 0.243948313710515, - 0.253627992837806, - 0.263464060987933, - 0.273450494478137, - 0.283582188986510, - 0.293853469478657, - 0.304257373461563, - 0.314790914011331, - 0.325449123426950, - 0.336227409661803, - 0.347118760290707, - 0.358120176960450, - 0.369224663378337, - 0.380427792871280, - 0.391720022741618, - 0.403097022154837, - 0.414551955216869, - 0.426081718612424, - 0.437676318481682, - 0.449330195657235, - 0.461034855039307, - 0.472786043282829, - 0.484576777178737, - 0.496401706766520, - 0.508252457556495, - 0.520122078483965, - 0.532002077000542, - 0.543888089744156, - 0.555771601181136, - 0.567645738774683, - 0.579502786315012, - 0.591335034592786, - 0.603138367473440, - 0.614904171685981, - 0.626623941105601, - 0.638288834425202, - 0.649893374776772, - 0.661432360150173, - 0.672902513906348, - 0.684293749833449, - 0.695600459535883, - 0.706811783648976, - 0.717923424519233, - 0.728931385727289, - 0.739832772797360, - 0.750618982371933, - 0.761284053417755, - 0.771818918701624, - 0.782220991963992, - 0.792481330455120, - 0.802599447723046, - 0.812565229501908, - 0.822377128920089, - 0.832030518374920, - 0.841523207674513, - 0.850848312948314, - 0.860002411781952, - 0.868979880825105, - 0.877778346729487, - 0.886395903955835, - 0.894829420791081, - 0.903077625660289, - 0.911132652155618, - 0.918993585364937, - 0.926652936933657, - 0.934111420416517, - 0.941364344292899, - 0.948412967370989, - 0.955255629597394, - 0.961892013137868, - 0.968316362908677, - 0.974530156362119, - 0.980528338141726, - 0.986313927767294, - 0.991886048619893, - 0.997246344766401, - 1.00239189664458, - 1.00731946437583, - 1.01202707343585, - 1.01651654151239, - 1.02079430268870, - 1.02486081579449, - 1.02871470580975, - 1.03235170271917, - 1.03577375047282, - 1.03898431507401, - 1.04198785539891, - 1.04478564357336, - 1.04737818412200, - 1.04976743149521, - 1.05195404554314, - 1.05394289856216, - 1.05573463147380, - 1.05734176732398, - 1.05875726493872, - 1.05998674447371, - 1.06103671687069, - 1.06190651084450, - 1.06260369490638, - 1.06313289329257, - 1.06350237394105, - 1.06370980806189, - 1.06376322346189, - 1.06366764604617, - 1.06343011818702, - 1.06305656438567, - 1.06255421036890, - 1.06192234666436, - 1.06116701778323, - 1.06029468923457, - 1.05931468949374, - 1.05823464730377, - 1.05705890752753, - 1.05578948247366, - 1.05442978686656, - 1.05298792590271, - 1.05147505164534, - 1.04989930053323, - 1.04826212949578, - 1.04656690601558, - 1.04481699264239, - 1.04302124919620, - 1.04118768090749, - 1.03932339102548, - 1.03743168416508, - 1.03551757331127, - 1.03358510598971, - 1.03164370854303, - 1.02969954597728, - 1.02775943851786, - 1.02582718703711, - 1.02390791088663, - 1.02200805068553, - 1.02013910120702, - 1.01826310081338, - 1.01687901084998, - 1.01492194818759, - 1.01309662336946, - 1.01134205244082, - 1.00965912296053, - 1.00805036388672, - 1.00651754025099, - 1.00505799251731, - 1.00366956090429, - 1.00235327309256, - 1.00110980844711, - 0.999937523064020, - 0.998834523778354, - 0.997800605926859, - 0.996835755847371, - 0.995938881156864, - 0.995108458955550, - 0.994343411090332, - 0.993642921198198, - 0.993005832427090, - 0.992430983777039, - 0.991917492640328, - 0.991463898014730, - 0.991068213957297, - 0.990729218448801, - 0.990446224564421, - 0.990217818551850, - 0.990041963066712, - 0.989917085260000, - 0.989841974698949, - 0.989815048293785, - 0.989834329137160, - 0.989898210724722, - 0.990005403060575, - 0.990154189263867, - 0.990342426919530, - 0.990568458991084, - 0.990830952741348, - 0.991128037927190, - 0.991457565684290, - 0.991817880927468, - 0.992207558971979, - 0.992624757299280, - 0.993067358412365, - 0.993533398279548, - 0.994021410066004, - 0.994529685133772, - 0.995055963618118, - 0.995598350543474, - 0.996155580104219, - 0.996725626776922, - 0.997306092208332, - 0.997895213854288, - 0.998491440631921, - 0.999092889987779, - 0.999697062575683, - 1.00030302922321, - 1.00090793360789, - 1.00151083855774, - 1.00210922561456, - 1.00270118453373, - 1.00328512996467, - 1.00385925649825, - 1.00442110963133, - 1.00496860132761, - 1.00550040380694, - 1.00601454845283, - 1.00650869083178, - 1.00698103862634, - 1.00743004105679, - 1.00785364005500, - 1.00824961843285, - 1.00861603623935, - 1.00895137836214, - 1.00925389667459, - 1.00952134193584, - 1.00975175133162, - 1.00994371466878, - 1.01009549736651, - 1.01020487679019, - 1.01027007304515, - 1.01028975233683, - 1.01026226969627, - 1.01018561543197, - 1.01005819682879, - 1.00987881783672, - 1.00964593048934, - 1.00935753319733, - 1.00901228181564, - 1.00860959436079, - 1.00814836659263, - 1.00762674316571, - 1.00704343050616, - 1.00639774980144, - 1.00568876793126, - 1.00491558583432, - 1.00407767878127, - 1.00317428837606, - 1.00220424207009, - 1.00116683614142, - 1.00006248083959, - 0.998891421862267, - 0.997652251800105, - 0.996343855540476, - 0.994967462022130, - 0.993524663018428, - 0.992013926907702, - 0.990433283134003, - 0.988785147009912, - 0.987072680860489, - 0.985297442611976, - 0.983401161131380, - 0.980949417765551, - 0.978782729044635, - 0.976468238349044, - 0.974042850200711, - 0.971498848279787, - 0.968829967901758, - 0.966030973927894, - 0.963095103865114, - 0.960018197689881, - 0.956795738404679, - 0.953426266696235, - 0.949903482303963, - 0.946222115168414, - 0.942375819502639, - 0.938361701514345, - 0.934177797863119, - 0.929823123908876, - 0.925292319504672, - 0.920580120066111, - 0.915679792968200, - 0.910590604293827, - 0.905315030158709, - 0.899852756107195, - 0.894199497118493, - 0.888350152427933, - 0.882301631337498, - 0.876054874152525, - 0.869612384940706, - 0.862972799329697, - 0.856135197574920, - 0.849098178607312, - 0.841857024342112, - 0.834414055019111, - 0.826774616875239, - 0.818939244026861, - 0.810904891487294, - 0.802675318450619, - 0.794253750525830, - 0.785641661592052, - 0.776838608661742, - 0.767853193256071, - 0.758685180670574, - 0.749330657713362, - 0.739809171155050, - 0.730109944357775, - 0.720247780620101, - 0.710224160990164, - 0.700044325846151, - 0.689711889540493, - 0.679231154104663, - 0.668608178924739, - 0.657850996784250, - 0.646965718233652, - 0.635959616622744, - 0.624840335899161, - 0.613603502679100, - 0.602265090642188, - 0.590829083373282, - 0.579309407943056, - 0.567711124002091, - 0.556037415675143, - 0.544293664349262, - 0.532489768053648, - 0.520636084113626, - 0.508743272768040, - 0.496811166041365, - 0.484849880708936, - 0.472868107365031, - 0.460875918379489, - 0.448881080632702, - 0.436891038772751, - 0.424912022350783, - 0.412960603164169, - 0.401035896287704, - 0.389157866744938, - 0.377322198811674, - 0.365543766863001, - 0.353832356425067, - 0.342196115433984, - 0.330644820108683, - 0.319187558989871, - 0.307833309339190, - 0.296588181651645, - 0.285463716536022, - 0.274462408857763, - 0.263609584476890, - 0.252883101143323, - 0.242323488971182, - 0.231925746284170, - 0.221690837369583, - 0.211638057695031, - 0.201766920294530, - 0.192082235818342, - 0.182589160013263, - 0.173305996740759, - 0.164229200045030, - 0.155362654247925, - 0.146717078597741, - 0.138299391415146, - 0.130105078076731, - 0.122145309929155, - 0.114423458192169, - 0.106941075992303, - 0.0997025893446062, - 0.0927124283374869, - 0.0859737427062027, - 0.0794893311195214, - 0.0732616579460535, - 0.0672934102310889, - 0.0615874081007633, - 0.0561458002593222, - 0.0509700747035652, - 0.0460617047145777, - 0.0414220116926541, - 0.0370514188750623, - 0.0329494666227939, - 0.0291153326941312, - 0.0255476401323823, - 0.0222437711282860, - 0.0192000658979791, - 0.0164122204526698, - 0.0138747611120131, - 0.0115806352990988, - 0.00952213664221592, - 0.00769137379581469, - 0.00607207833119310, - 0.00462581216874268, - 0.00360685164162597, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}; - -const LC3_FLOAT MDCT_WINDOW_480_7_5ms[720] = {0.00172152668161197, - 0.00220824874304665, - 0.00268901752259534, - 0.00322613341770658, - 0.00381014419509035, - 0.00445371931718418, - 0.00515369239968132, - 0.00591552473428981, - 0.00673869158441088, - 0.00762861840690755, - 0.00858361456803004, - 0.00960938437461376, - 0.0107060753216012, - 0.0118759722608345, - 0.0131190129731594, - 0.0144390107858867, - 0.0158335301409709, - 0.0173063081075865, - 0.0188584711217331, - 0.0204918651551601, - 0.0222061476414017, - 0.0240057166241995, - 0.0258883592892154, - 0.0278552325915007, - 0.0299059145401639, - 0.0320415894481754, - 0.0342610013298592, - 0.0365680972732117, - 0.0389616721239547, - 0.0414435823556703, - 0.0440140795515652, - 0.0466742169139349, - 0.0494214624989609, - 0.0522588488991433, - 0.0551849337276135, - 0.0582005142844991, - 0.0613059844876918, - 0.0645038384438376, - 0.0677913922780715, - 0.0711707832894713, - 0.0746411071480673, - 0.0782028053093391, - 0.0818549520793733, - 0.0856000161887899, - 0.0894357617466231, - 0.0933642589167916, - 0.0973846702504817, - 0.101496717842215, - 0.105698760137915, - 0.109993602538973, - 0.114378287000688, - 0.118853507644691, - 0.123419277472281, - 0.128075996686182, - 0.132820580592162, - 0.137655456547628, - 0.142578647864983, - 0.147590521689500, - 0.152690437463956, - 0.157878852729327, - 0.163152528516638, - 0.168513362640497, - 0.173957968965553, - 0.179484736541084, - 0.185093104613143, - 0.190784835080141, - 0.196556497277956, - 0.202410419487986, - 0.208345433427595, - 0.214359824832231, - 0.220450365133188, - 0.226617296379634, - 0.232856279279332, - 0.239167940620308, - 0.245550641734726, - 0.252003950801656, - 0.258526168288333, - 0.265118407626359, - 0.271775911320379, - 0.278498538773636, - 0.285284606228892, - 0.292132459126393, - 0.299038431599591, - 0.306004255968647, - 0.313026529044311, - 0.320104862365552, - 0.327237324371911, - 0.334423209544169, - 0.341658622243036, - 0.348944976164519, - 0.356279251911600, - 0.363660034025212, - 0.371085146360032, - 0.378554326716481, - 0.386062695189504, - 0.393610553614044, - 0.401195224753282, - 0.408815272459443, - 0.416468460349459, - 0.424155411395509, - 0.431871045845866, - 0.439614743914448, - 0.447384019490353, - 0.455176987704814, - 0.462990137501968, - 0.470824618788539, - 0.478676592635263, - 0.486545433113577, - 0.494428714400322, - 0.502324813138104, - 0.510229471464589, - 0.518142926555815, - 0.526060916224847, - 0.533982817654487, - 0.541906816785495, - 0.549831282885023, - 0.557751233747995, - 0.565667636233856, - 0.573576882777006, - 0.581476665547768, - 0.589364661090802, - 0.597241338441034, - 0.605102013194533, - 0.612946170296527, - 0.620770242419397, - 0.628572093800007, - 0.636348526182129, - 0.644099662433612, - 0.651820973301216, - 0.659513821705787, - 0.667176381676395, - 0.674806795170392, - 0.682400710845902, - 0.689958853765865, - 0.697475722348889, - 0.704950144755303, - 0.712379980093130, - 0.719765434054233, - 0.727103832924324, - 0.734396371869479, - 0.741638560666120, - 0.748829639427782, - 0.755966688050532, - 0.763049259441822, - 0.770072273456679, - 0.777036981101517, - 0.783941107955561, - 0.790781256570410, - 0.797558113689794, - 0.804271380965317, - 0.810914900592988, - 0.817490855531114, - 0.823997093771197, - 0.830432785018494, - 0.836796949640853, - 0.843089297972628, - 0.849305847142233, - 0.855447309567916, - 0.861511036513329, - 0.867496280683677, - 0.873400798399116, - 0.879227518344298, - 0.884972438304695, - 0.890635718969808, - 0.896217172709751, - 0.901716413868111, - 0.907128770123878, - 0.912456578161017, - 0.917697260839682, - 0.922848783570288, - 0.927909917257080, - 0.932882596476862, - 0.937763322534182, - 0.942553355949148, - 0.947252428176398, - 0.951860206252747, - 0.956376059930715, - 0.960800601653643, - 0.965130600153629, - 0.969366688856792, - 0.973508812191284, - 0.977556540546725, - 0.981507226076202, - 0.985364580290061, - 0.989126208677996, - 0.992794200680601, - 0.996367545084978, - 0.999846919168316, - 1.00322812484515, - 1.00651341182191, - 1.00970072970387, - 1.01279028960634, - 1.01578293436089, - 1.01868228690835, - 1.02148657041020, - 1.02419771842881, - 1.02681455085919, - 1.02933598109997, - 1.03176042993634, - 1.03408981275172, - 1.03632325851578, - 1.03846360765363, - 1.04051195662940, - 1.04246831469554, - 1.04433331015458, - 1.04610836852236, - 1.04779018315657, - 1.04938333555913, - 1.05088564953428, - 1.05229923461622, - 1.05362521849064, - 1.05486288757866, - 1.05601520650228, - 1.05708745929907, - 1.05807220584955, - 1.05897524171920, - 1.05979446723066, - 1.06053413867011, - 1.06119411863264, - 1.06177365556482, - 1.06227661751764, - 1.06270323725515, - 1.06305568550874, - 1.06333815026019, - 1.06354799718407, - 1.06368606790043, - 1.06375556676696, - 1.06375743495314, - 1.06369358352060, - 1.06356632061806, - 1.06337707389149, - 1.06312781969919, - 1.06282155753012, - 1.06245781539243, - 1.06203634281998, - 1.06155995891758, - 1.06102951018466, - 1.06044796508355, - 1.05981709158148, - 1.05914162811841, - 1.05842135887536, - 1.05765876038451, - 1.05685377407703, - 1.05600761436100, - 1.05512005736540, - 1.05419504543825, - 1.05323345555133, - 1.05223985071955, - 1.05121667551754, - 1.05016636928704, - 1.04908778571338, - 1.04798366418119, - 1.04685333764799, - 1.04569859514623, - 1.04452056473031, - 1.04332348168164, - 1.04210830682439, - 1.04087907347658, - 1.03963603298779, - 1.03838098558867, - 1.03711402960368, - 1.03583813453316, - 1.03455276253936, - 1.03326200062149, - 1.03196749756726, - 1.03067199718128, - 1.02937563931250, - 1.02808243736505, - 1.02679166694268, - 1.02550635249346, - 1.02422655030626, - 1.02295558402234, - 1.02169298956325, - 1.02044474846015, - 1.01920733213785, - 1.01799991915642, - 1.01716021719396, - 1.01587288719722, - 1.01461782929950, - 1.01339738080134, - 1.01221017459353, - 1.01105651618772, - 1.00993443649479, - 1.00884559103696, - 1.00778955760958, - 1.00676790147273, - 1.00577851248622, - 1.00482173369676, - 1.00389592016124, - 1.00300261849896, - 1.00214090725866, - 1.00131212703156, - 1.00051460180915, - 0.999748987566388, - 0.999013486065174, - 0.998309228756053, - 0.997634933573802, - 0.996991885118110, - 0.996378601374572, - 0.995795982324256, - 0.995242217431553, - 0.994718132279737, - 0.994222121603521, - 0.993755313270097, - 0.993316215711850, - 0.992905809264804, - 0.992522421568056, - 0.992166956964939, - 0.991837703847481, - 0.991535508409853, - 0.991258602708851, - 0.991007878425042, - 0.990781722666477, - 0.990581103872326, - 0.990404336010644, - 0.990252266515061, - 0.990123118186375, - 0.990017725942080, - 0.989934325251675, - 0.989873711994700, - 0.989834110063609, - 0.989816358516333, - 0.989818706664725, - 0.989841997633560, - 0.989884437608375, - 0.989946800178719, - 0.990027287179467, - 0.990126680433027, - 0.990243175367708, - 0.990377593567359, - 0.990528133732004, - 0.990695563551443, - 0.990878043253865, - 0.991076301696221, - 0.991288540103593, - 0.991515601979036, - 0.991755665863857, - 0.992009469063567, - 0.992275155432533, - 0.992553486464066, - 0.992842692750141, - 0.993143533338714, - 0.993454079661184, - 0.993775066630664, - 0.994104689071308, - 0.994443741563539, - 0.994790397982872, - 0.995145361143570, - 0.995506799575831, - 0.995875533622126, - 0.996249681496846, - 0.996629918576519, - 0.997014367015673, - 0.997403799406302, - 0.997796404470102, - 0.998192870684212, - 0.998591285561368, - 0.998992436297826, - 0.999394506476233, - 0.999798247074188, - 1.00020179363827, - 1.00060586036830, - 1.00100857991068, - 1.00141070171451, - 1.00181040094441, - 1.00220846208708, - 1.00260295839583, - 1.00299457368229, - 1.00338147727724, - 1.00376443633841, - 1.00414154805357, - 1.00451348039620, - 1.00487832134478, - 1.00523688409909, - 1.00558730293553, - 1.00593027172440, - 1.00626392589064, - 1.00658905174666, - 1.00690380235195, - 1.00720890358777, - 1.00750238011098, - 1.00778498234605, - 1.00805489381465, - 1.00831286819921, - 1.00855699900640, - 1.00878801634839, - 1.00900404770905, - 1.00920593286756, - 1.00939182206005, - 1.00956244042490, - 1.00971589673993, - 1.00985295821773, - 1.00997177407911, - 1.01007316964863, - 1.01015529301117, - 1.01021893264234, - 1.01026224628852, - 1.01028601830489, - 1.01028841501360, - 1.01027029664166, - 1.01022987870331, - 1.01016802275824, - 1.01008292457433, - 1.00997540773688, - 1.00984368712353, - 1.00968863285475, - 1.00950845528029, - 1.00930404459694, - 1.00907371350998, - 1.00881848315592, - 1.00853675084589, - 1.00822946750346, - 1.00789488400120, - 1.00753391386376, - 1.00714487786153, - 1.00672875785417, - 1.00628392789102, - 1.00581145628420, - 1.00530991398353, - 1.00478052727780, - 1.00422176605486, - 1.00363456081898, - 1.00301719093886, - 1.00237067322585, - 1.00169363479295, - 1.00098748810560, - 1.00025107545667, - 0.999485662869670, - 0.998689592389690, - 0.997863666433377, - 0.997006370229165, - 0.996119199129118, - 0.995201403855962, - 0.994254686877395, - 0.993277595101281, - 0.992270650602836, - 0.991231967393677, - 0.990163285718553, - 0.989064393522322, - 0.987937115334337, - 0.986779736108308, - 0.985592773084236, - 0.984375124686103, - 0.983129287890062, - 0.981348462911328, - 0.979890963312768, - 0.978400458984906, - 0.976860435411572, - 0.975269878842859, - 0.973627353241612, - 0.971931340983223, - 0.970180498004025, - 0.968372651965257, - 0.966506952259707, - 0.964580026820328, - 0.962592317588312, - 0.960540986343273, - 0.958425533515528, - 0.956244393275019, - 0.953998415902893, - 0.951684013845583, - 0.949301185363779, - 0.946846884329832, - 0.944320232231505, - 0.941718404323327, - 0.939042579646710, - 0.936290624169877, - 0.933464049736310, - 0.930560853876881, - 0.927580506944232, - 0.924519591719516, - 0.921378471441385, - 0.918153413723035, - 0.914844695613022, - 0.911451651601712, - 0.907976524013806, - 0.904417545083186, - 0.900776307727862, - 0.897050058479312, - 0.893238397854931, - 0.889338680564778, - 0.885351360384818, - 0.881274022956677, - 0.877109637913966, - 0.872857926504400, - 0.868519505092655, - 0.864092796449043, - 0.859579818650462, - 0.854976006559576, - 0.850285220126345, - 0.845502615038655, - 0.840630470320405, - 0.835667925492783, - 0.830619943301480, - 0.825482006990559, - 0.820258908705916, - 0.814946648157534, - 0.809546695921391, - 0.804059977858176, - 0.798489377529441, - 0.792831417318078, - 0.787090668112010, - 0.781262449660145, - 0.775353946896531, - 0.769363612973808, - 0.763291769255088, - 0.757139016438538, - 0.750901711179744, - 0.744590843420388, - 0.738205135983222, - 0.731738075019976, - 0.725199287080917, - 0.718588225289593, - 0.711905686689260, - 0.705153668360855, - 0.698332634155137, - 0.691444101223867, - 0.684490544603819, - 0.677470119276872, - 0.670388375375255, - 0.663245209931378, - 0.656045780075394, - 0.648788626910908, - 0.641477161661819, - 0.634114322697443, - 0.626702000288600, - 0.619235333635541, - 0.611720595766813, - 0.604161612008372, - 0.596559132542786, - 0.588914400742527, - 0.581234783414194, - 0.573519989364814, - 0.565770615838341, - 0.557988067156798, - 0.550173851023454, - 0.542330193938633, - 0.534460798055783, - 0.526568538230013, - 0.518656324106017, - 0.510728812610530, - 0.502781158663802, - 0.494819490990687, - 0.486845139248642, - 0.478860889056187, - 0.470869928237011, - 0.462875144056541, - 0.454877894349081, - 0.446882512027806, - 0.438889324991181, - 0.430898122898976, - 0.422918322377786, - 0.414950877976117, - 0.406993964205624, - 0.399052648395750, - 0.391134613511556, - 0.383234030582781, - 0.375354652658444, - 0.367502059648862, - 0.359680098334456, - 0.351887311977221, - 0.344130165828257, - 0.336408100091303, - 0.328728966167385, - 0.321090505163296, - 0.313496418152647, - 0.305951564939720, - 0.298454318724068, - 0.291010565493870, - 0.283621109377504, - 0.276285415057373, - 0.269019585108745, - 0.261812445205796, - 0.254659232371968, - 0.247584347561867, - 0.240578694191260, - 0.233647008666278, - 0.226788433385199, - 0.220001991767835, - 0.213301325170393, - 0.206677770653848, - 0.200140409104345, - 0.193683630277597, - 0.187310343238419, - 0.181027383883625, - 0.174839476062309, - 0.168739644125069, - 0.162737273481917, - 0.156825277050683, - 0.151012382058898, - 0.145298229536747, - 0.139687469382981, - 0.134171842279709, - 0.128762544136019, - 0.123455562073148, - 0.118254662325635, - 0.113159676766305, - 0.108171439273590, - 0.103290733977459, - 0.0985202977906343, - 0.0938600022604814, - 0.0893117360272552, - 0.0848752102882993, - 0.0805523737322188, - 0.0763429786604177, - 0.0722489245608881, - 0.0682699119548786, - 0.0644077291458590, - 0.0606620002841447, - 0.0570343711147243, - 0.0535243714739393, - 0.0501334689685108, - 0.0468610789607730, - 0.0437084452819923, - 0.0406748365259497, - 0.0377612269065632, - 0.0349667099153408, - 0.0322919274833124, - 0.0297357668703102, - 0.0272984629264830, - 0.0249787185611126, - 0.0227762541832071, - 0.0206895808034878, - 0.0187178169347065, - 0.0168593417528780, - 0.0151125125235276, - 0.0134757094495118, - 0.0119462709121848, - 0.0105228753811890, - 0.00920130941284003, - 0.00798124316373271, - 0.00685547314312078, - 0.00582657334385164, - 0.00487838525422656, - 0.00402351119094097, - 0.00315418662758696, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}; -#endif /* #ifdef CR8_G_ADD_75MS */ +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_2_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_20_8000, lpc_lin_pre_emphasis_40_16000, lpc_lin_pre_emphasis_60_24000, + lpc_lin_pre_emphasis_80_32000, lpc_lin_pre_emphasis_60_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_0_92 +#endif +}; -const LC3_FLOAT MDCT_WINDOW_80_2_5ms[40] = { - 6.737914289329320e-03, 2.732289618100209e-02, 6.163560962361236e-02, 1.119125037883055e-01, 1.787053464784875e-01, - 2.607525136824537e-01, 3.549776504187033e-01, 4.567696724165073e-01, 5.605239559005871e-01, 6.603665285212146e-01, - 7.509434386216048e-01, 8.281382099997300e-01, 8.895849967038094e-01, 9.348747871791264e-01, 9.654056798094166e-01, - 9.839026370225886e-01, 9.937180643904148e-01, 9.980987183772584e-01, 9.996266599807562e-01, 9.999772999978698e-01, - 9.999772999978698e-01, 9.996266599807562e-01, 9.980987183772584e-01, 9.937180643904148e-01, 9.839026370225886e-01, - 9.654056798094166e-01, 9.348747871791264e-01, 8.895849967038094e-01, 8.281382099997300e-01, 7.509434386216048e-01, - 6.603665285212146e-01, 5.605239559005871e-01, 4.567696724165073e-01, 3.549776504187033e-01, 2.607525136824537e-01, - 1.787053464784875e-01, 1.119125037883055e-01, 6.163560962361236e-02, 2.732289618100209e-02, 6.737914289329320e-03}; - -const LC3_FLOAT MDCT_WINDOW_160_2_5ms[80] = { - 4.764416154578566e-03, 1.204636278996989e-02, 2.226396539371650e-02, 3.580223111285056e-02, 5.299054649961241e-02, - 7.408518398076024e-02, 9.925385917916330e-02, 1.285631180041137e-01, 1.619692437449073e-01, 1.993132407013812e-01, - 2.403202823615340e-01, 2.846038181323611e-01, 3.316743228466244e-01, 3.809524578920635e-01, 4.317862022264749e-01, - 4.834713159013930e-01, 5.352743274612082e-01, 5.864570980113353e-01, 6.363019156559162e-01, 6.841360194558924e-01, - 7.293544453028629e-01, 7.714401286766273e-01, 8.099802912368443e-01, 8.446782786131956e-01, 8.753602039735273e-01, - 9.019759839191052e-01, 9.245946272967390e-01, 9.433939492938426e-01, 9.586452246292587e-01, 9.706936498636800e-01, - 9.799358305935717e-01, 9.867958066797319e-01, 9.917013283691115e-01, 9.950621445106043e-01, 9.972519167765670e-01, - 9.985950139980033e-01, 9.993588946156141e-01, 9.997521272020117e-01, 9.999274399392850e-01, 9.999886501049429e-01, - 9.999886501049429e-01, 9.999274399392850e-01, 9.997521272020117e-01, 9.993588946156141e-01, 9.985950139980033e-01, - 9.972519167765670e-01, 9.950621445106043e-01, 9.917013283691115e-01, 9.867958066797319e-01, 9.799358305935717e-01, - 9.706936498636800e-01, 9.586452246292587e-01, 9.433939492938426e-01, 9.245946272967390e-01, 9.019759839191052e-01, - 8.753602039735273e-01, 8.446782786131956e-01, 8.099802912368443e-01, 7.714401286766273e-01, 7.293544453028629e-01, - 6.841360194558924e-01, 6.363019156559162e-01, 5.864570980113353e-01, 5.352743274612082e-01, 4.834713159013930e-01, - 4.317862022264749e-01, 3.809524578920635e-01, 3.316743228466244e-01, 2.846038181323611e-01, 2.403202823615340e-01, - 1.993132407013812e-01, 1.619692437449073e-01, 1.285631180041137e-01, 9.925385917916330e-02, 7.408518398076024e-02, - 5.299054649961241e-02, 3.580223111285056e-02, 2.226396539371650e-02, 1.204636278996989e-02, 4.764416154578566e-03}; - -const LC3_FLOAT MDCT_WINDOW_240_2_5ms[120] = { - 3.890134207235998e-03, 8.202595078385781e-03, 1.370235555340779e-02, 2.052968531182845e-02, 2.880307728389693e-02, - 3.862785141889536e-02, 5.009569719921809e-02, 6.328296540190831e-02, 7.824881086160715e-02, 9.503346510857243e-02, - 1.136567491769230e-01, 1.341168883357315e-01, 1.563896708020576e-01, 1.804279808512455e-01, 2.061617274373514e-01, - 2.334981807379911e-01, 2.623227204239969e-01, 2.924999908279060e-01, 3.238754496100354e-01, 3.562772881250116e-01, - 3.895186936283779e-01, 4.234004158919065e-01, 4.577135938730904e-01, 4.922427919542673e-01, 5.267691900603833e-01, - 5.610738677940736e-01, 5.949411196851041e-01, 6.281617368097510e-01, 6.605361894447956e-01, 6.918776461105686e-01, - 7.220147663396499e-01, 7.507942077785026e-01, 7.780827927721814e-01, 8.037692853722609e-01, 8.277657367145603e-01, - 8.500083649018569e-01, 8.704579448595252e-01, 8.890996940634835e-01, 9.059426515086708e-01, 9.210185597011833e-01, - 9.343802726761132e-01, 9.460997268469628e-01, 9.562655255553633e-01, 9.649802020504638e-01, 9.723572386690237e-01, - 9.785179314351103e-01, 9.835881982445411e-01, 9.876954342642392e-01, 9.909655192099981e-01, 9.935200769821082e-01, - 9.954740782709803e-01, 9.969338611957889e-01, 9.979956243841658e-01, 9.987444223234112e-01, 9.992536660401901e-01, - 9.995851053006831e-01, 9.997892438014110e-01, 9.999061183192590e-01, 9.999663581511030e-01, 9.999924333992981e-01, - 9.999924333992981e-01, 9.999663581511030e-01, 9.999061183192590e-01, 9.997892438014110e-01, 9.995851053006831e-01, - 9.992536660401901e-01, 9.987444223234112e-01, 9.979956243841658e-01, 9.969338611957889e-01, 9.954740782709803e-01, - 9.935200769821082e-01, 9.909655192099981e-01, 9.876954342642392e-01, 9.835881982445411e-01, 9.785179314351103e-01, - 9.723572386690237e-01, 9.649802020504638e-01, 9.562655255553633e-01, 9.460997268469628e-01, 9.343802726761132e-01, - 9.210185597011833e-01, 9.059426515086708e-01, 8.890996940634835e-01, 8.704579448595252e-01, 8.500083649018569e-01, - 8.277657367145603e-01, 8.037692853722609e-01, 7.780827927721814e-01, 7.507942077785026e-01, 7.220147663396499e-01, - 6.918776461105686e-01, 6.605361894447956e-01, 6.281617368097510e-01, 5.949411196851041e-01, 5.610738677940736e-01, - 5.267691900603833e-01, 4.922427919542673e-01, 4.577135938730904e-01, 4.234004158919065e-01, 3.895186936283779e-01, - 3.562772881250116e-01, 3.238754496100354e-01, 2.924999908279060e-01, 2.623227204239969e-01, 2.334981807379911e-01, - 2.061617274373514e-01, 1.804279808512455e-01, 1.563896708020576e-01, 1.341168883357315e-01, 1.136567491769230e-01, - 9.503346510857243e-02, 7.824881086160715e-02, 6.328296540190831e-02, 5.009569719921809e-02, 3.862785141889536e-02, - 2.880307728389693e-02, 2.052968531182845e-02, 1.370235555340779e-02, 8.202595078385781e-03, 3.890134207235998e-03}; - -const LC3_FLOAT MDCT_WINDOW_320_2_5ms[160] = { - 3.368958353152859e-03, 6.455557414799749e-03, 1.014308076237845e-02, 1.452126850237346e-02, 1.965076732239952e-02, - 2.558352795411825e-02, 3.236628529621430e-02, 4.004117865352276e-02, 4.864564178753818e-02, 5.821207082124419e-02, - 6.876742903793599e-02, 8.033284980531531e-02, 9.292326595333501e-02, 1.065470811378728e-01, 1.212058930254449e-01, - 1.368942751980506e-01, 1.535996228917228e-01, 1.713020663983868e-01, 1.899744548998832e-01, 2.095824125414741e-01, - 2.300844676343023e-01, 2.514322549787097e-01, 2.735707904154788e-01, 2.964388158404272e-01, 3.199692120640840e-01, - 3.440894760693133e-01, 3.687222584236977e-01, 3.937859558486231e-01, 4.191953532416662e-01, 4.448623088011174e-01, - 4.706964753188311e-01, 4.966060501969578e-01, 5.224985463116437e-01, 5.482815754977786e-01, 5.738636361677886e-01, - 5.991548964078475e-01, 6.240679638193776e-01, 6.485186333941402e-01, 6.724266048285701e-01, 6.957161608975563e-01, - 7.183167988192716e-01, 7.401638069500036e-01, 7.611987796499656e-01, 7.813700637561797e-01, 8.006331307849442e-01, - 8.189508697622124e-01, 8.362937964433754e-01, 8.526401756322647e-01, 8.679760543400818e-01, 8.822952046352904e-01, - 8.955989762210201e-01, 9.078960600314304e-01, 9.192021654545784e-01, 9.295396151552272e-01, 9.389368628711653e-01, - 9.474279409702298e-01, 9.550518459555614e-01, 9.618518714601797e-01, 9.678748995383242e-01, 9.731706621931426e-01, - 9.777909860257944e-01, 9.817890335940264e-01, 9.852185554726640e-01, 9.881331670617683e-01, 9.905856638463937e-01, - 9.926273880444285e-01, 9.943076583739057e-01, 9.956732730391862e-01, 9.967680940129237e-01, 9.976327183405286e-01, - 9.983042396036903e-01, 9.988160999578843e-01, 9.991980304284215e-01, 9.994760745391177e-01, 9.996726879821318e-01, - 9.998069050289865e-01, 9.998945608218308e-01, 9.999485576331654e-01, 9.999791626721350e-01, 9.999943250437048e-01, - 9.999943250437048e-01, 9.999791626721350e-01, 9.999485576331654e-01, 9.998945608218308e-01, 9.998069050289865e-01, - 9.996726879821318e-01, 9.994760745391177e-01, 9.991980304284215e-01, 9.988160999578843e-01, 9.983042396036903e-01, - 9.976327183405286e-01, 9.967680940129237e-01, 9.956732730391862e-01, 9.943076583739057e-01, 9.926273880444285e-01, - 9.905856638463937e-01, 9.881331670617683e-01, 9.852185554726640e-01, 9.817890335940264e-01, 9.777909860257944e-01, - 9.731706621931426e-01, 9.678748995383242e-01, 9.618518714601797e-01, 9.550518459555614e-01, 9.474279409702298e-01, - 9.389368628711653e-01, 9.295396151552272e-01, 9.192021654545784e-01, 9.078960600314304e-01, 8.955989762210201e-01, - 8.822952046352904e-01, 8.679760543400818e-01, 8.526401756322647e-01, 8.362937964433754e-01, 8.189508697622124e-01, - 8.006331307849442e-01, 7.813700637561797e-01, 7.611987796499656e-01, 7.401638069500036e-01, 7.183167988192716e-01, - 6.957161608975563e-01, 6.724266048285701e-01, 6.485186333941402e-01, 6.240679638193776e-01, 5.991548964078475e-01, - 5.738636361677886e-01, 5.482815754977786e-01, 5.224985463116437e-01, 4.966060501969578e-01, 4.706964753188311e-01, - 4.448623088011174e-01, 4.191953532416662e-01, 3.937859558486231e-01, 3.687222584236977e-01, 3.440894760693133e-01, - 3.199692120640840e-01, 2.964388158404272e-01, 2.735707904154788e-01, 2.514322549787097e-01, 2.300844676343023e-01, - 2.095824125414741e-01, 1.899744548998832e-01, 1.713020663983868e-01, 1.535996228917228e-01, 1.368942751980506e-01, - 1.212058930254449e-01, 1.065470811378728e-01, 9.292326595333501e-02, 8.033284980531531e-02, 6.876742903793599e-02, - 5.821207082124419e-02, 4.864564178753818e-02, 4.004117865352276e-02, 3.236628529621430e-02, 2.558352795411825e-02, - 1.965076732239952e-02, 1.452126850237346e-02, 1.014308076237845e-02, 6.455557414799749e-03, 3.368958353152859e-03}; - -const LC3_FLOAT MDCT_WINDOW_480_2_5ms[240] = { - 2.750746382614873e-03, 4.775245154322467e-03, 6.991265476184880e-03, 9.470118155887091e-03, 1.224415763156159e-02, - 1.533559472880042e-02, 1.876266772162453e-02, 2.254154337372088e-02, 2.668701415521377e-02, 3.121277069249126e-02, - 3.613150075407039e-02, 4.145491000214293e-02, 4.719370517091751e-02, 5.335755875796826e-02, 5.995506493224793e-02, - 6.699369195627566e-02, 7.447973421347953e-02, 8.241826576309315e-02, 9.081309669365416e-02, 9.966673316465058e-02, - 1.089803417907089e-01, 1.187537188695662e-01, 1.289852648491186e-01, 1.396719643506733e-01, 1.508093720039881e-01, - 1.623916042982366e-01, 1.744113376077630e-01, 1.868598125100347e-01, 1.997268444741311e-01, 2.130008409605561e-01, - 2.266688249366323e-01, 2.407164647759538e-01, 2.551281104752023e-01, 2.698868360870567e-01, 2.849744882339612e-01, - 3.003717405342550e-01, 3.160581537396951e-01, 3.320122413518523e-01, 3.482115404543554e-01, 3.646326874686314e-01, - 3.812514985127824e-01, 3.980430540166849e-01, 4.149817872214252e-01, 4.320415761679195e-01, 4.491958387581356e-01, - 4.664176304528364e-01, 4.836797441523142e-01, 5.009548117912680e-01, 5.182154071658814e-01, 5.354341495003542e-01, - 5.525838072516958e-01, 5.696374016455559e-01, 5.865683094322820e-01, 6.033503643513004e-01, 6.199579567933325e-01, - 6.363661311538971e-01, 6.525506803780192e-01, 6.684882372050696e-01, 6.841563616341746e-01, 6.995336241446708e-01, - 7.145996842225878e-01, 7.293353637631239e-01, 7.437227149404935e-01, 7.577450821603423e-01, 7.713871577361272e-01, - 7.846350309593857e-01, 7.974762302646725e-01, 8.098997582230498e-01, 8.218961191333729e-01, 8.334573390181531e-01, - 8.445769778704795e-01, 8.552501340402698e-01, 8.654734406919574e-01, 8.752450543115063e-01, 8.845646352883213e-01, - 8.934333206470277e-01, 9.018536890551258e-01, 9.098297182849719e-01, 9.173667353621834e-01, 9.244713596871228e-01, - 9.311514394712620e-01, 9.374159818855259e-01, 9.432750773727245e-01, 9.487398186303003e-01, 9.538222148222497e-01, - 9.585351016294561e-01, 9.628920477950361e-01, 9.669072588647543e-01, 9.705954788611818e-01, 9.739718906630962e-01, - 9.770520158876372e-01, 9.798516150909821e-01, 9.823865891128170e-01, 9.846728823898172e-01, 9.867263890529354e-01, - 9.885628626019504e-01, 9.901978299180545e-01, 9.916465103310770e-01, 9.929237404023775e-01, 9.940439050178721e-01, - 9.950208753087979e-01, 9.958679538316859e-01, 9.965978273449145e-01, 9.972225274187749e-01, 9.977533990110320e-01, - 9.982010770325636e-01, 9.985754708200026e-01, 9.988857563266385e-01, 9.991403757414241e-01, 9.993470441509588e-01, - 9.995127627727911e-01, 9.996438382121301e-01, 9.997459071295719e-01, 9.998239656559388e-01, 9.998824028526124e-01, - 9.999250374922579e-01, 9.999551574256286e-01, 9.999755608048836e-01, 9.999885984518604e-01, 9.999962166900126e-01, - 9.999962166900126e-01, 9.999885984518604e-01, 9.999755608048836e-01, 9.999551574256286e-01, 9.999250374922579e-01, - 9.998824028526124e-01, 9.998239656559388e-01, 9.997459071295719e-01, 9.996438382121301e-01, 9.995127627727911e-01, - 9.993470441509588e-01, 9.991403757414241e-01, 9.988857563266385e-01, 9.985754708200026e-01, 9.982010770325636e-01, - 9.977533990110320e-01, 9.972225274187749e-01, 9.965978273449145e-01, 9.958679538316859e-01, 9.950208753087979e-01, - 9.940439050178721e-01, 9.929237404023775e-01, 9.916465103310770e-01, 9.901978299180545e-01, 9.885628626019504e-01, - 9.867263890529354e-01, 9.846728823898172e-01, 9.823865891128170e-01, 9.798516150909821e-01, 9.770520158876372e-01, - 9.739718906630962e-01, 9.705954788611818e-01, 9.669072588647543e-01, 9.628920477950361e-01, 9.585351016294561e-01, - 9.538222148222497e-01, 9.487398186303003e-01, 9.432750773727245e-01, 9.374159818855259e-01, 9.311514394712620e-01, - 9.244713596871228e-01, 9.173667353621834e-01, 9.098297182849719e-01, 9.018536890551258e-01, 8.934333206470277e-01, - 8.845646352883213e-01, 8.752450543115063e-01, 8.654734406919574e-01, 8.552501340402698e-01, 8.445769778704795e-01, - 8.334573390181531e-01, 8.218961191333729e-01, 8.098997582230498e-01, 7.974762302646725e-01, 7.846350309593857e-01, - 7.713871577361272e-01, 7.577450821603423e-01, 7.437227149404935e-01, 7.293353637631239e-01, 7.145996842225878e-01, - 6.995336241446708e-01, 6.841563616341746e-01, 6.684882372050696e-01, 6.525506803780192e-01, 6.363661311538971e-01, - 6.199579567933325e-01, 6.033503643513004e-01, 5.865683094322820e-01, 5.696374016455559e-01, 5.525838072516958e-01, - 5.354341495003542e-01, 5.182154071658814e-01, 5.009548117912680e-01, 4.836797441523142e-01, 4.664176304528364e-01, - 4.491958387581356e-01, 4.320415761679195e-01, 4.149817872214252e-01, 3.980430540166849e-01, 3.812514985127824e-01, - 3.646326874686314e-01, 3.482115404543554e-01, 3.320122413518523e-01, 3.160581537396951e-01, 3.003717405342550e-01, - 2.849744882339612e-01, 2.698868360870567e-01, 2.551281104752023e-01, 2.407164647759538e-01, 2.266688249366323e-01, - 2.130008409605561e-01, 1.997268444741311e-01, 1.868598125100347e-01, 1.744113376077630e-01, 1.623916042982366e-01, - 1.508093720039881e-01, 1.396719643506733e-01, 1.289852648491186e-01, 1.187537188695662e-01, 1.089803417907089e-01, - 9.966673316465058e-02, 9.081309669365416e-02, 8.241826576309315e-02, 7.447973421347953e-02, 6.699369195627566e-02, - 5.995506493224793e-02, 5.335755875796826e-02, 4.719370517091751e-02, 4.145491000214293e-02, 3.613150075407039e-02, - 3.121277069249126e-02, 2.668701415521377e-02, 2.254154337372088e-02, 1.876266772162453e-02, 1.533559472880042e-02, - 1.224415763156159e-02, 9.470118155887091e-03, 6.991265476184880e-03, 4.775245154322467e-03, 2.750746382614873e-03}; - -const LC3_FLOAT MDCT_WINDOW_80[160] = { - -7.078546706512391e-04, -2.098197727900724e-03, -4.525198076002370e-03, -8.233976327300612e-03, - -1.337713096257934e-02, -1.999721557401502e-02, -2.800909464274782e-02, -3.721502082245055e-02, - -4.731768261606175e-02, -5.794654834034055e-02, -6.867606753531441e-02, -7.904647440788692e-02, - -8.859705468085925e-02, -9.688303623049199e-02, -1.034961241263523e-01, -1.080766457616878e-01, - -1.103242262600913e-01, -1.099809851424550e-01, -1.068172142230882e-01, -1.006190418791648e-01, - -9.116452506492527e-02, -7.820617483254730e-02, -6.146688124166948e-02, -4.063362855701623e-02, - -1.536329520788766e-02, 1.470155068746303e-02, 4.989736509080558e-02, 9.050369257152079e-02, - 1.366911019414417e-01, 1.884686389218322e-01, 2.456456803467095e-01, 3.077789078889820e-01, - 3.741642373060188e-01, 4.438114799213576e-01, 5.154735456539700e-01, 5.876661722564289e-01, - 6.587619767809000e-01, 7.270576699841359e-01, 7.908752989295335e-01, 8.486643364959733e-01, - 8.991320235484349e-01, 9.413348145272842e-01, 9.747634827941575e-01, 9.994114730415857e-01, - 1.015760373791603e+00, 1.024736164069697e+00, 1.027634294456205e+00, 1.025991493983836e+00, - 1.021427210603284e+00, 1.015439859549357e+00, 1.009366925499550e+00, 1.003508162416449e+00, - 9.988898206257559e-01, 9.953133902427869e-01, 9.925943919208190e-01, 9.905771957917731e-01, - 9.891371616557014e-01, 9.881790747212391e-01, 9.876249269174586e-01, 9.874056275509585e-01, - 9.874524849192456e-01, 9.876951134084213e-01, 9.880640617030884e-01, 9.884926873551375e-01, - 9.889230031022089e-01, 9.893074965384659e-01, 9.896146331889107e-01, 9.898319269347060e-01, - 9.899693102025342e-01, 9.900603352632121e-01, 9.901575015155720e-01, 9.903255289051605e-01, - 9.906303787150326e-01, 9.911298894709990e-01, 9.918665491182922e-01, 9.928619727154252e-01, - 9.941156069136238e-01, 9.956033775539884e-01, 9.972793109558521e-01, 9.990784840729244e-01, - 1.000922365901945e+00, 1.002728111386909e+00, 1.004416038098237e+00, 1.005919224127911e+00, - 1.007189345025525e+00, 1.008200146369426e+00, 1.008949493525753e+00, 1.009458241425143e+00, - 1.009768980817384e+00, 1.009940336228694e+00, 1.010039453539107e+00, 1.010132323996401e+00, - 1.010272524848519e+00, 1.010494354532353e+00, 1.010808068774316e+00, 1.011201071127927e+00, - 1.011641272406023e+00, 1.012080125934687e+00, 1.012458183122033e+00, 1.012706955800289e+00, - 1.012755013843985e+00, 1.012530134411619e+00, 1.011962331100864e+00, 1.010982135506986e+00, - 1.009512438049510e+00, 1.007460860286395e+00, 1.004708677491086e+00, 1.001111413242302e+00, - 9.965041017623596e-01, 9.907199995730845e-01, 9.823765865983288e-01, 9.708821747608998e-01, - 9.546732976073705e-01, 9.321553861564006e-01, 9.018003682081348e-01, 8.623984077953557e-01, - 8.132817365236141e-01, 7.544551974836834e-01, 6.866580716267418e-01, 6.113488038789190e-01, - 5.306181649316597e-01, 4.471309850999502e-01, 3.639114681156236e-01, 2.841647033392408e-01, - 2.110209448747969e-01, 1.472287968327703e-01, 9.482665349502291e-02, 5.482436608328477e-02, - 2.701461405056264e-02, 9.996743588367519e-03, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_160[320] = { - -4.619898752628163e-04, -9.747166718929050e-04, -1.664473096973725e-03, -2.597106916737789e-03, - -3.806285163352241e-03, -5.324608721716763e-03, -7.175885277771099e-03, -9.382480860899108e-03, - -1.195270300743193e-02, -1.489528159506296e-02, -1.820666399965468e-02, -2.187570925786862e-02, - -2.588471937157619e-02, -3.020862738245264e-02, -3.481597793538342e-02, -3.967067992672979e-02, - -4.472698045914417e-02, -4.994225863256500e-02, -5.526334794593565e-02, -6.063717235243996e-02, - -6.600961519440657e-02, -7.131966266443390e-02, -7.651178225890490e-02, -8.152964005319532e-02, - -8.631137544905677e-02, -9.080411291245728e-02, -9.495377758870335e-02, -9.870736514214426e-02, - -1.020202684361974e-01, -1.048438825017798e-01, -1.071382314127799e-01, -1.088690135027248e-01, - -1.099969655786929e-01, -1.104898474883336e-01, -1.103225838568563e-01, -1.094621746650760e-01, - -1.078834293141886e-01, -1.055612509762041e-01, -1.024650162703341e-01, -9.857014566194629e-02, - -9.384684920715425e-02, -8.826309993000785e-02, -8.178792716809512e-02, -7.438785600211463e-02, - -6.602189797715241e-02, -5.665655641133161e-02, -4.624456893420224e-02, -3.474585776145929e-02, - -2.211581608120528e-02, -8.310425696208936e-03, 6.717697635290676e-03, 2.300642061077823e-02, - 4.060106462625085e-02, 5.953239090915557e-02, 7.983354189816511e-02, 1.015233140203748e-01, - 1.246171387327525e-01, 1.491152519299797e-01, 1.750067399059861e-01, 2.022699854906251e-01, - 2.308655379767671e-01, 2.607365124918583e-01, 2.918144694729168e-01, 3.240095704645023e-01, - 3.572175180786021e-01, 3.913146885756875e-01, 4.261571642320424e-01, 4.615925445090212e-01, - 4.974471592901086e-01, 5.335326819631583e-01, 5.696546730080154e-01, 6.056083823929643e-01, - 6.411830842823245e-01, 6.761653499550255e-01, 7.103400549562944e-01, 7.434943718765665e-01, - 7.754281892901473e-01, 8.059437233154637e-01, 8.348589373399948e-01, 8.620108336276733e-01, - 8.872599706865123e-01, 9.104863121445679e-01, 9.315962496426278e-01, 9.505220861927248e-01, - 9.672366712325431e-01, 9.817397501303696e-01, 9.940557180662704e-01, 1.004247514102417e+00, - 1.012407428282884e+00, 1.018650990561848e+00, 1.023118841384460e+00, 1.025972450969440e+00, - 1.027397523939210e+00, 1.027585830688143e+00, 1.026738673647482e+00, 1.025061777648234e+00, - 1.022756514615106e+00, 1.020009139549275e+00, 1.016996499560845e+00, 1.013915946100629e+00, - 1.011044869639164e+00, 1.007773858455400e+00, 1.004848753962734e+00, 1.002245009135684e+00, - 9.999393169239009e-01, 9.979055415627330e-01, 9.961203379971326e-01, 9.945597525471822e-01, - 9.932031606606762e-01, 9.920297273323891e-01, 9.910230654424902e-01, 9.901668953434221e-01, - 9.894488374513719e-01, 9.888556356037892e-01, 9.883778520531268e-01, 9.880051626345804e-01, - 9.877295459610343e-01, 9.875412739766566e-01, 9.874329809802893e-01, 9.873949921033299e-01, - 9.874197049003676e-01, 9.874973205882319e-01, 9.876201238703241e-01, 9.877781920433015e-01, - 9.879637979933339e-01, 9.881678007807095e-01, 9.883835200189653e-01, 9.886022219397892e-01, - 9.888182771263505e-01, 9.890247977602895e-01, 9.892178658748239e-01, 9.893923680007577e-01, - 9.895463342815009e-01, 9.896772011542693e-01, 9.897859195209235e-01, 9.898725363809847e-01, - 9.899410789223559e-01, 9.899945557067980e-01, 9.900394023736973e-01, 9.900814722948890e-01, - 9.901293790312005e-01, 9.901902265696609e-01, 9.902734448815004e-01, 9.903862280081246e-01, - 9.905379830873822e-01, 9.907348826312993e-01, 9.909842592301273e-01, 9.912905118607647e-01, - 9.916586940166509e-01, 9.920906151219310e-01, 9.925887208794144e-01, 9.931516528513824e-01, - 9.937790866568735e-01, 9.944668184371617e-01, 9.952116634297566e-01, 9.960068616185641e-01, - 9.968461329825753e-01, 9.977203369515556e-01, 9.986213520769593e-01, 9.995382582242990e-01, - 1.000461955079660e+00, 1.001380551217109e+00, 1.002284871786226e+00, 1.003163845364970e+00, - 1.004009147462043e+00, 1.004811375053364e+00, 1.005563968008037e+00, 1.006259855360867e+00, - 1.006895570408563e+00, 1.007466616298057e+00, 1.007972441990187e+00, 1.008411468616852e+00, - 1.008786009787269e+00, 1.009097763850333e+00, 1.009351762546296e+00, 1.009552401900961e+00, - 1.009707093778162e+00, 1.009822090220407e+00, 1.009906958448099e+00, 1.009969021400474e+00, - 1.010017890428877e+00, 1.010060809299530e+00, 1.010106564965965e+00, 1.010161131093372e+00, - 1.010231078494249e+00, 1.010319484524512e+00, 1.010430470494512e+00, 1.010564099281000e+00, - 1.010721360243234e+00, 1.010899655674578e+00, 1.011096993993037e+00, 1.011308167670753e+00, - 1.011529185153809e+00, 1.011753008569803e+00, 1.011973876511603e+00, 1.012182837094955e+00, - 1.012373028737774e+00, 1.012535058602453e+00, 1.012660975529858e+00, 1.012740575296603e+00, - 1.012765922449960e+00, 1.012726958954961e+00, 1.012615904116265e+00, 1.012422888521601e+00, - 1.012140460211194e+00, 1.011758810583150e+00, 1.011269960947744e+00, 1.010663676735228e+00, - 1.009930754807923e+00, 1.009058249873833e+00, 1.008034308295421e+00, 1.006843352506855e+00, - 1.005470005637052e+00, 1.003894772403371e+00, 1.002098854400575e+00, 1.000060686758758e+00, - 9.977600196406868e-01, 9.951746430061121e-01, 9.922861082472264e-01, 9.890757868707590e-01, - 9.847362453480265e-01, 9.798613526271561e-01, 9.741378617337759e-01, 9.673331975559332e-01, - 9.592539757044516e-01, 9.496984081652284e-01, 9.384634163826711e-01, 9.253567968750328e-01, - 9.101986790930605e-01, 8.928338316495705e-01, 8.731437835983047e-01, 8.510420440685049e-01, - 8.264839911291133e-01, 7.994681492797084e-01, 7.700431275216928e-01, 7.383028603058783e-01, - 7.043814340356083e-01, 6.684616478236647e-01, 6.307755329382612e-01, 5.915799587176216e-01, - 5.511703155400274e-01, 5.098915423728179e-01, 4.681017110047964e-01, 4.261772971493010e-01, - 3.845172335531009e-01, 3.435228672445613e-01, 3.036004651973099e-01, 2.651434678028531e-01, - 2.285283969438072e-01, 1.941021906320984e-01, 1.621735416384830e-01, 1.330015240938615e-01, - 1.067840430193724e-01, 8.365057236623041e-02, 6.365188111381356e-02, 4.676538412257621e-02, - 3.288072750732215e-02, 2.183057564646270e-02, 1.336381425803019e-02, 6.758124889697787e-03, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_240[480] = { - -3.613496418928369e-04, -7.078546706512391e-04, -1.074443637110903e-03, -1.533478537964509e-03, - -2.098197727900724e-03, -2.778420871815740e-03, -3.584129920673041e-03, -4.525198076002370e-03, - -5.609327243712055e-03, -6.843234536105624e-03, -8.233976327300612e-03, -9.785314755557023e-03, - -1.149880303071551e-02, -1.337713096257934e-02, -1.542181679511618e-02, -1.762979910961727e-02, - -1.999721557401502e-02, -2.252080561390149e-02, -2.519406300389030e-02, -2.800909464274782e-02, - -3.095765092956728e-02, -3.402996266948349e-02, -3.721502082245055e-02, -4.050053247568393e-02, - -4.387219218706189e-02, -4.731768261606175e-02, -5.082325342672667e-02, -5.437166635159518e-02, - -5.794654834034055e-02, -6.153426201732499e-02, -6.511708163113709e-02, -6.867606753531441e-02, - -7.219447805250771e-02, -7.565695975592170e-02, -7.904647440788692e-02, -8.234442557322251e-02, - -8.553324579905185e-02, -8.859705468085925e-02, -9.152091100798199e-02, -9.428847446755965e-02, - -9.688303623049198e-02, -9.929123258537813e-02, -1.015008467688577e-01, -1.034961241263523e-01, - -1.052637003544443e-01, -1.067939984687745e-01, -1.080766457616878e-01, -1.090997300590506e-01, - -1.098524491515805e-01, -1.103242262600913e-01, -1.105084619148789e-01, -1.103977408741932e-01, - -1.099809851424550e-01, -1.092492774392824e-01, -1.081974227416502e-01, -1.068172142230882e-01, - -1.050995803285455e-01, -1.030360111111103e-01, -1.006190418791648e-01, -9.784120023411771e-02, - -9.469304216883027e-02, -9.116452506492527e-02, -8.724644532866996e-02, -8.293043914044632e-02, - -7.820617483254730e-02, -7.306142427456862e-02, -6.748468182105991e-02, -6.146688124166948e-02, - -5.499497258200362e-02, -4.805444424454820e-02, -4.063362855701623e-02, -3.272045590229335e-02, - -2.430122582451853e-02, -1.536329520788766e-02, -5.891434269890659e-03, 4.126595858583295e-03, - 1.470155068746303e-02, 2.584738191459814e-02, 3.757652772246801e-02, 4.989736509080558e-02, - 6.282034030592902e-02, 7.635397728566121e-02, 9.050369257152079e-02, 1.052747118478660e-01, - 1.206703467513333e-01, 1.366911019414417e-01, 1.533343890681390e-01, 1.705954709184399e-01, - 1.884686389218322e-01, 2.069449962574092e-01, 2.260093000067393e-01, 2.456456803467095e-01, - 2.658346019332584e-01, 2.865543814049772e-01, 3.077789078889820e-01, 3.294769437072290e-01, - 3.516171481750350e-01, 3.741642373060188e-01, 3.970739591211551e-01, 4.203043046885219e-01, - 4.438114799213576e-01, 4.675442291623012e-01, 4.914498631045615e-01, 5.154735456539700e-01, - 5.395557644293222e-01, 5.636399817032525e-01, 5.876661722564289e-01, 6.115695310143157e-01, - 6.352890592874099e-01, 6.587619767809000e-01, 6.819230974423550e-01, 7.047092819314779e-01, - 7.270576699841359e-01, 7.489068963384272e-01, 7.701990187606995e-01, 7.908752989295335e-01, - 8.108788692151807e-01, 8.301579139160681e-01, 8.486643364959733e-01, 8.663548164329093e-01, - 8.831896853053627e-01, 8.991320235484349e-01, 9.141540563656075e-01, 9.282282546151819e-01, - 9.413348145272842e-01, 9.534619388400459e-01, 9.646048250501910e-01, 9.747634827941575e-01, - 9.839435385219192e-01, 9.921529097154242e-01, 9.994114730415857e-01, 1.005746084650236e+00, - 1.011183971347815e+00, 1.015760373791603e+00, 1.019515072412387e+00, 1.022490937034641e+00, - 1.024736164069697e+00, 1.026304095700693e+00, 1.027250978292214e+00, 1.027634294456205e+00, - 1.027511063644843e+00, 1.026942795115598e+00, 1.025991493983836e+00, 1.024716149969084e+00, - 1.023175976163407e+00, 1.021427210603284e+00, 1.019521566634239e+00, 1.017510118327508e+00, - 1.015439859549357e+00, 1.013460916839174e+00, 1.011654901040475e+00, 1.009366925499550e+00, - 1.007263182132894e+00, 1.005313192386866e+00, 1.003508162416449e+00, 1.001840787319378e+00, - 1.000303927234380e+00, 9.988898206257559e-01, 9.975915283480670e-01, 9.964015284765968e-01, - 9.953133902427869e-01, 9.943201078053212e-01, 9.934158959186011e-01, 9.925943919208190e-01, - 9.918510277326026e-01, 9.911797988363887e-01, 9.905771957917731e-01, 9.900381047643838e-01, - 9.895594394179152e-01, 9.891371616557014e-01, 9.887684373604154e-01, 9.884497924570929e-01, - 9.881790747212391e-01, 9.879528358230726e-01, 9.877691368590689e-01, 9.876249269174586e-01, - 9.875179947346887e-01, 9.874458127312921e-01, 9.874056275509585e-01, 9.873951115886979e-01, - 9.874115368168944e-01, 9.874524849192456e-01, 9.875149888347144e-01, 9.875968894760857e-01, - 9.876951134084213e-01, 9.878075819424549e-01, 9.879311998177238e-01, 9.880640617030884e-01, - 9.882032571565917e-01, 9.883471084085503e-01, 9.884926873551375e-01, 9.886386592120545e-01, - 9.887825578295630e-01, 9.889230031022089e-01, 9.890581715933395e-01, 9.891867674284610e-01, - 9.893074965384659e-01, 9.894196399062921e-01, 9.895220757174378e-01, 9.896146331889107e-01, - 9.896970346678272e-01, 9.897692596535289e-01, 9.898319269347060e-01, 9.898852572653667e-01, - 9.899307640365727e-01, 9.899693102025343e-01, 9.900025692522435e-01, 9.900321562263099e-01, - 9.900603352632121e-01, 9.900889812894406e-01, 9.901206586012907e-01, 9.901575015155720e-01, - 9.902023946214220e-01, 9.902575406142213e-01, 9.903255289051605e-01, 9.904087914462694e-01, - 9.905096491583045e-01, 9.906303787150326e-01, 9.907727108894024e-01, 9.909387444078919e-01, - 9.911298894709990e-01, 9.913476318763218e-01, 9.915928560402563e-01, 9.918665491182922e-01, - 9.921691315380984e-01, 9.925010851461232e-01, 9.928619727154252e-01, 9.932519181564613e-01, - 9.936700207375173e-01, 9.941156069136238e-01, 9.945873147903244e-01, 9.950837402063278e-01, - 9.956033775539884e-01, 9.961439922621166e-01, 9.967034533921340e-01, 9.972793109558521e-01, - 9.978690858367024e-01, 9.984697087896268e-01, 9.990784840729244e-01, 9.996919011206490e-01, - 1.000308193833526e+00, 1.000922365901945e+00, 1.001532636590676e+00, 1.002135464655177e+00, - 1.002728111386909e+00, 1.003307449770187e+00, 1.003870934089686e+00, 1.004416038098237e+00, - 1.004940548815171e+00, 1.005442141810160e+00, 1.005919224127911e+00, 1.006370303149314e+00, - 1.006793927824538e+00, 1.007189345025525e+00, 1.007555573455895e+00, 1.007892674961336e+00, - 1.008200146369426e+00, 1.008478423284851e+00, 1.008727884997619e+00, 1.008949493525753e+00, - 1.009144112734761e+00, 1.009313224929575e+00, 1.009458241425143e+00, 1.009581280555682e+00, - 1.009684090687164e+00, 1.009768980817384e+00, 1.009838308708799e+00, 1.009894548257807e+00, - 1.009940336228694e+00, 1.009977916643680e+00, 1.010010230290263e+00, 1.010039453539107e+00, - 1.010068202038694e+00, 1.010098388689342e+00, 1.010132323996401e+00, 1.010171656775640e+00, - 1.010218096148412e+00, 1.010272524848519e+00, 1.010336490294771e+00, 1.010410221483215e+00, - 1.010494354532353e+00, 1.010588873699422e+00, 1.010693501186928e+00, 1.010808068774316e+00, - 1.010931436739342e+00, 1.011062876503041e+00, 1.011201071127927e+00, 1.011344700694417e+00, - 1.011491904228184e+00, 1.011641272406023e+00, 1.011790282474963e+00, 1.011937567254485e+00, - 1.012080125934687e+00, 1.012216235487353e+00, 1.012342907951334e+00, 1.012458183122033e+00, - 1.012558879696851e+00, 1.012642857380847e+00, 1.012706955800289e+00, 1.012748952907404e+00, - 1.012765799894453e+00, 1.012755013843985e+00, 1.012713798678211e+00, 1.012639775003457e+00, - 1.012530134411619e+00, 1.012382309473470e+00, 1.012194068117524e+00, 1.011962331100864e+00, - 1.011685173724601e+00, 1.011359143572147e+00, 1.010982135506986e+00, 1.010550715971368e+00, - 1.010062133151922e+00, 1.009512438049510e+00, 1.008898689394160e+00, 1.008215923600973e+00, - 1.007460860286395e+00, 1.006627741823389e+00, 1.005712337656749e+00, 1.004708677491086e+00, - 1.003611467285588e+00, 1.002414286392268e+00, 1.001111413242302e+00, 9.996961651093181e-01, - 9.981625949525345e-01, 9.965041017623596e-01, 9.947148884277037e-01, 9.927891912841345e-01, - 9.907199995730845e-01, 9.884793707533194e-01, 9.855347660016696e-01, 9.823765865983286e-01, - 9.789747333404933e-01, 9.751623811486372e-01, 9.708821747608998e-01, 9.660805524695870e-01, - 9.606976399184645e-01, 9.546732976073706e-01, 9.479479345282376e-01, 9.404609052933396e-01, - 9.321553861564006e-01, 9.229775478442888e-01, 9.128745354570823e-01, 9.018003682081348e-01, - 8.897163275605041e-01, 8.765908974996186e-01, 8.623984077953557e-01, 8.471200801854385e-01, - 8.307479727020245e-01, 8.132817365236141e-01, 7.947291447585267e-01, 7.751108841891807e-01, - 7.544551974836834e-01, 7.327963552921717e-01, 7.101790843209148e-01, 6.866580716267418e-01, - 6.622962432368731e-01, 6.371684119604742e-01, 6.113488038789190e-01, 5.849206604934815e-01, - 5.579747428663487e-01, 5.306181649316717e-01, 5.029523957059122e-01, 4.750868825511614e-01, - 4.471309850999535e-01, 4.192049917945288e-01, 3.914252910998820e-01, 3.639114681156252e-01, - 3.367837772954476e-01, 3.101627843160973e-01, 2.841647033392418e-01, 2.589033711808454e-01, - 2.344880603710975e-01, 2.110209448747974e-01, 1.885997642296488e-01, 1.673100807904834e-01, - 1.472287968327706e-01, 1.284223074167396e-01, 1.109422548710344e-01, 9.482665349502306e-02, - 8.009914366829558e-02, 6.676765847398403e-02, 5.482436608328485e-02, 4.424588851571281e-02, - 3.499361000717621e-02, 2.701461405056267e-02, 2.024370180670145e-02, 1.460796755137538e-02, - 9.996743588367531e-03, 5.305235098871444e-03, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_320[640] = { - -3.021153494057143e-04, -5.867737487939294e-04, -8.366504004139796e-04, -1.126635355725494e-03, - -1.470492941694331e-03, -1.873473391018495e-03, -2.339292362082021e-03, -2.872008069419264e-03, - -3.476256385086407e-03, -4.155963816705528e-03, -4.914563787665504e-03, -5.755172503953251e-03, - -6.680623380533122e-03, -7.693816924650567e-03, -8.796760749750191e-03, -9.990503073705982e-03, - -1.127574117138621e-02, -1.265334152129685e-02, -1.412438986522702e-02, -1.568889620430290e-02, - -1.734512089366117e-02, -1.909097368362797e-02, -2.092546711168754e-02, -2.284684792818856e-02, - -2.485207716234951e-02, -2.693746704328349e-02, -2.909952486193999e-02, -3.133504629493832e-02, - -3.363960728361352e-02, -3.600820974457969e-02, -3.843601741746971e-02, -4.091746034850161e-02, - -4.344654894948344e-02, -4.601786724624048e-02, -4.862598509282497e-02, -5.126474204655663e-02, - -5.392644753556616e-02, -5.660384311081047e-02, -5.929116747072080e-02, -6.198268202511926e-02, - -6.467025548071184e-02, -6.734542216184526e-02, -7.000099017198280e-02, -7.263057011354321e-02, - -7.522784961377151e-02, -7.778525942347714e-02, -8.029480247839878e-02, -8.274924535373614e-02, - -8.514125464087215e-02, -8.746379123238275e-02, -8.971069341834263e-02, -9.187564084638347e-02, - -9.395176975347193e-02, -9.593137735886889e-02, -9.780843257659243e-02, -9.957851303827886e-02, - -1.012361165314596e-01, -1.027741036495644e-01, -1.041861222641119e-01, -1.054680247057000e-01, - -1.066160875985523e-01, -1.076255384835563e-01, -1.084912299471198e-01, -1.092087422379003e-01, - -1.097736146613313e-01, -1.101808861640070e-01, -1.104271876052675e-01, -1.105108362290460e-01, - -1.104281465492726e-01, -1.101739218186236e-01, -1.097437360338336e-01, -1.091353125572511e-01, - -1.083467335729228e-01, -1.073739938306107e-01, -1.062130155324388e-01, -1.048606145834788e-01, - -1.033132401525343e-01, -1.015673163469357e-01, -9.962005506126154e-02, -9.746803229469267e-02, - -9.510723623306666e-02, -9.253303383231506e-02, -8.974125216128212e-02, -8.672877689119252e-02, - -8.349213839083708e-02, -8.002639902061687e-02, -7.632679536516856e-02, -7.238806162166744e-02, - -6.820576796149519e-02, -6.377611429172260e-02, -5.909386001558149e-02, -5.415316322402774e-02, - -4.894812724598650e-02, -4.347347112195197e-02, -3.772461300253332e-02, -3.169587609244436e-02, - -2.538179830690266e-02, -1.877689096555516e-02, -1.187461378850388e-02, -4.669099247423082e-03, - 2.844096748870385e-03, 1.066976124794342e-02, 1.881355950582949e-02, 2.728156010437695e-02, - 3.607810469851272e-02, 4.520702759803914e-02, 5.467238802204326e-02, 6.447866054615346e-02, - 7.462862199422061e-02, 8.512490568723846e-02, 9.596983987496970e-02, 1.071650779014335e-01, - 1.187115850305241e-01, 1.306101067250375e-01, 1.428596447589721e-01, 1.554584725339102e-01, - 1.684041609371527e-01, 1.816947894623263e-01, 1.953273880886783e-01, 2.092963206850239e-01, - 2.235945635254679e-01, 2.382160219461597e-01, 2.531529721334063e-01, 2.683961570569586e-01, - 2.839361392493072e-01, 2.997624255177811e-01, 3.158619077906196e-01, 3.322210551086769e-01, - 3.488264676990591e-01, 3.656640377499646e-01, 3.827152968157059e-01, 3.999611859760947e-01, - 4.173843265025887e-01, 4.349669624916473e-01, 4.526876397402144e-01, 4.705242008503956e-01, - 4.884539254831315e-01, 5.064545550235134e-01, 5.245006748662190e-01, 5.425674372882107e-01, - 5.606312044701524e-01, 5.786672646386708e-01, 5.966477035050948e-01, 6.145458904162185e-01, - 6.323361944662236e-01, 6.499926319211774e-01, 6.674874032292857e-01, 6.847932667399612e-01, - 7.018835463513400e-01, 7.187322544823347e-01, 7.353128213893310e-01, 7.516001985652684e-01, - 7.675699252273948e-01, 7.831974571624924e-01, 7.984583859818390e-01, 8.133295347030278e-01, - 8.277892271515950e-01, 8.418178561101360e-01, 8.553961300139363e-01, 8.685068980898102e-01, - 8.811334436653052e-01, 8.932596784799233e-01, 9.048748835980528e-01, 9.159657608120536e-01, - 9.265215299450000e-01, 9.365339988633418e-01, 9.459977028429117e-01, 9.549088408436811e-01, - 9.632658122557368e-01, 9.710688896122810e-01, 9.783204156360773e-01, 9.850226760127131e-01, - 9.911792082081333e-01, 9.967989944502682e-01, 1.001894024615659e+00, 1.006474342231823e+00, - 1.010552057109195e+00, 1.014142538208007e+00, 1.017262593268930e+00, 1.019928842669923e+00, - 1.022159867011177e+00, 1.023976320927187e+00, 1.025400734608122e+00, 1.026455340400072e+00, - 1.027164510654160e+00, 1.027552729180790e+00, 1.027644462380432e+00, 1.027463246660797e+00, - 1.027035903410657e+00, 1.026389068000259e+00, 1.025548201799728e+00, 1.024537134749709e+00, - 1.023380803775376e+00, 1.022103695693341e+00, 1.020728359657958e+00, 1.019275334687329e+00, - 1.017765178792830e+00, 1.016217355867531e+00, 1.014665311686846e+00, 1.013249071090664e+00, - 1.011948006992127e+00, 1.010189090179223e+00, 1.008557961167850e+00, 1.007011287608451e+00, - 1.005548764575910e+00, 1.004168417268956e+00, 1.002867268893035e+00, 1.001641769115897e+00, - 1.000489068954641e+00, 9.994060799749374e-01, 9.983898865406841e-01, 9.974370849972721e-01, - 9.965444836911705e-01, 9.957098545943852e-01, 9.949302413030897e-01, 9.942024045863540e-01, - 9.935241604969254e-01, 9.928930430130044e-01, 9.923068103443909e-01, 9.917633778190438e-01, - 9.912597642374404e-01, 9.907954498484041e-01, 9.903677893656558e-01, 9.899751611066148e-01, - 9.896160337369861e-01, 9.892890160408989e-01, 9.889928511129679e-01, 9.887260333430423e-01, - 9.884868721088945e-01, 9.882751039537586e-01, 9.880892168751595e-01, 9.879277114724612e-01, - 9.877898261218510e-01, 9.876743442038471e-01, 9.875807496078497e-01, 9.875072021876561e-01, - 9.874529447589979e-01, 9.874169741527905e-01, 9.873984685207834e-01, 9.873958301311858e-01, - 9.874080027710336e-01, 9.874343401290739e-01, 9.874736235387018e-01, 9.875243137719285e-01, - 9.875856201221135e-01, 9.876563785063032e-01, 9.877358921155149e-01, 9.878225576787804e-01, - 9.879150968481590e-01, 9.880132731565830e-01, 9.881156946084619e-01, 9.882211314188272e-01, - 9.883289032519310e-01, 9.884378310018685e-01, 9.885476787868710e-01, 9.886568414746639e-01, - 9.887645868459630e-01, 9.888708540445242e-01, 9.889744320992592e-01, 9.890747269455915e-01, - 9.891710038703801e-01, 9.892631024032380e-01, 9.893507219573624e-01, 9.894330645494204e-01, - 9.895096919388534e-01, 9.895810813422480e-01, 9.896467469067676e-01, 9.897067365020641e-01, - 9.897606930400666e-01, 9.898094478563998e-01, 9.898530133261707e-01, 9.898914705684924e-01, - 9.899254194103574e-01, 9.899554202030650e-01, 9.899824494486951e-01, 9.900065116928948e-01, - 9.900284805353695e-01, 9.900497484789281e-01, 9.900709561632662e-01, 9.900928358611601e-01, - 9.901163920607219e-01, 9.901427479709606e-01, 9.901734275350572e-01, 9.902087332329851e-01, - 9.902498637985275e-01, 9.902983686695558e-01, 9.903548501470234e-01, 9.904205084933333e-01, - 9.904959297726740e-01, 9.905825150202904e-01, 9.906812569810133e-01, 9.907922087340426e-01, - 9.909165464981378e-01, 9.910550740962871e-01, 9.912084614290896e-01, 9.913768610980639e-01, - 9.915605826937839e-01, 9.917604214872976e-01, 9.919767175562684e-01, 9.922091101818779e-01, - 9.924579135466506e-01, 9.927231225056266e-01, 9.930049538427406e-01, 9.933027281437943e-01, - 9.936161084869942e-01, 9.939453714404443e-01, 9.942895145656371e-01, 9.946481676207727e-01, - 9.950203031067961e-01, 9.954058173659507e-01, 9.958038713694317e-01, 9.962130271017117e-01, - 9.966324689957675e-01, 9.970615306490058e-01, 9.974990583293081e-01, 9.979437430375855e-01, - 9.983940572002874e-01, 9.988493116887893e-01, 9.993083430214909e-01, 9.997689221333534e-01, - 1.000231131275969e+00, 1.000692135698996e+00, 1.001152013920163e+00, 1.001608526000461e+00, - 1.002060493867275e+00, 1.002507212061815e+00, 1.002947129400411e+00, 1.003378909587027e+00, - 1.003801368578070e+00, 1.004213810320699e+00, 1.004615386562846e+00, 1.005004618375781e+00, - 1.005380628601598e+00, 1.005743282364652e+00, 1.006091510392348e+00, 1.006424907424988e+00, - 1.006742427727669e+00, 1.007044321511378e+00, 1.007330218597112e+00, 1.007599401798709e+00, - 1.007852064386603e+00, 1.008088176165563e+00, 1.008308033204578e+00, 1.008511247273756e+00, - 1.008698144207627e+00, 1.008869515256392e+00, 1.009025659761512e+00, 1.009166718967367e+00, - 1.009293362609020e+00, 1.009406398832440e+00, 1.009507017171120e+00, 1.009595264293017e+00, - 1.009672145744679e+00, 1.009739084785160e+00, 1.009796675060142e+00, 1.009846137382005e+00, - 1.009888083631667e+00, 1.009924092276850e+00, 1.009955384765721e+00, 1.009982268770147e+00, - 1.010006298177305e+00, 1.010028618428735e+00, 1.010050254076988e+00, 1.010071952131355e+00, - 1.010094366238073e+00, 1.010118917317053e+00, 1.010146497096682e+00, 1.010177110711677e+00, - 1.010211755260102e+00, 1.010251003469427e+00, 1.010295468653759e+00, 1.010345234996637e+00, - 1.010400316698172e+00, 1.010461564316351e+00, 1.010528615445659e+00, 1.010601521285347e+00, - 1.010679788081867e+00, 1.010763905869062e+00, 1.010853429760676e+00, 1.010947547074519e+00, - 1.011045953108263e+00, 1.011148486293359e+00, 1.011254397791134e+00, 1.011363082075863e+00, - 1.011473302008831e+00, 1.011584996312149e+00, 1.011697416504599e+00, 1.011808919793469e+00, - 1.011919264025716e+00, 1.012027240794153e+00, 1.012132151631041e+00, 1.012232734564333e+00, - 1.012327560477901e+00, 1.012416383754384e+00, 1.012497890726292e+00, 1.012570434021054e+00, - 1.012633295255708e+00, 1.012685277016726e+00, 1.012725564992284e+00, 1.012752577651415e+00, - 1.012765062889864e+00, 1.012762356719162e+00, 1.012743376077777e+00, 1.012706484200181e+00, - 1.012650842226435e+00, 1.012575427778520e+00, 1.012479473490919e+00, 1.012361105121003e+00, - 1.012219809594718e+00, 1.012054359992419e+00, 1.011864000215460e+00, 1.011647223869087e+00, - 1.011402518267713e+00, 1.011129654652857e+00, 1.010826951260377e+00, 1.010492924436361e+00, - 1.010126353960416e+00, 1.009725892479312e+00, 1.009290060983833e+00, 1.008817301052548e+00, - 1.008305027555130e+00, 1.007752833675443e+00, 1.007157827358150e+00, 1.006518049344503e+00, - 1.005831403532018e+00, 1.005095592119373e+00, 1.004308630055050e+00, 1.003467498305776e+00, - 1.002569500413888e+00, 1.001612710105563e+00, 1.000594272975683e+00, 9.995111701168786e-01, - 9.983609218719522e-01, 9.971409288327860e-01, 9.958488863050556e-01, 9.944818543153893e-01, - 9.930375282832211e-01, 9.915146560759479e-01, 9.899136802423638e-01, 9.881930623810997e-01, - 9.859422591203311e-01, 9.835667898378924e-01, 9.811423034808365e-01, 9.785214441250228e-01, - 9.756636036109838e-01, 9.725453442532574e-01, 9.691456634185092e-01, 9.654406178310209e-01, - 9.614043615076308e-01, 9.570113065179300e-01, 9.522367669696690e-01, 9.470548839544214e-01, - 9.414403740008491e-01, 9.353691612846549e-01, 9.288190093977164e-01, 9.217662887169115e-01, - 9.141896283466009e-01, 9.060694681113471e-01, 8.973891675497357e-01, 8.881332000806269e-01, - 8.782893885841422e-01, 8.678469565343039e-01, 8.567970644671067e-01, 8.451334654019180e-01, - 8.328542805780399e-01, 8.199594783897041e-01, 8.064511006873497e-01, 7.923346478686025e-01, - 7.776204488292163e-01, 7.623206183595970e-01, 7.464486491227057e-01, 7.300205729992958e-01, - 7.130567383226717e-01, 6.955805444755916e-01, 6.776173229836567e-01, 6.591955305148172e-01, - 6.403486426892321e-01, 6.211072197441818e-01, 6.015049275244730e-01, 5.815787608870452e-01, - 5.613674511156324e-01, 5.409188627354076e-01, 5.202736834971303e-01, 4.994780733459294e-01, - 4.785774177949064e-01, 4.576172599874928e-01, 4.366490208265804e-01, 4.157221460415995e-01, - 3.948856590950757e-01, 3.741903189229770e-01, 3.536868899553974e-01, 3.334260017756462e-01, - 3.134586473252229e-01, 2.938337904395871e-01, 2.745992637590817e-01, 2.558030636168172e-01, - 2.374902188466697e-01, 2.197036032185785e-01, 2.024855415115456e-01, 1.858749915117319e-01, - 1.699067802117410e-01, 1.546132267478873e-01, 1.400238206749695e-01, 1.261637395672913e-01, - 1.130534434072719e-01, 1.007084973747940e-01, 8.914024389873081e-02, 7.835612100141792e-02, - 6.835821233920988e-02, 5.914211536028976e-02, 5.069893012340832e-02, 4.301717763585550e-02, - 3.608020726673359e-02, 2.986316337017630e-02, 2.433722657129812e-02, 1.947675241971700e-02, - 1.525710171255895e-02, 1.163787492636240e-02, 8.433087782643718e-03, 4.449668997344735e-03, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_480[960] = { - -2.353032150516754e-04, -4.619898752628163e-04, -6.262931535610879e-04, -7.929180432976445e-04, - -9.747166718929050e-04, -1.180256894474562e-03, -1.409209039594871e-03, -1.664473096973725e-03, - -1.946591608170231e-03, -2.257081732588478e-03, -2.597106916737789e-03, -2.967607624839524e-03, - -3.370454877988472e-03, -3.806285163352241e-03, -4.276873767639064e-03, -4.782469904501813e-03, - -5.324608721716763e-03, -5.903403814095400e-03, -6.520419726599805e-03, -7.175885277771099e-03, - -7.871422820642307e-03, -8.606586039759667e-03, -9.382480860899108e-03, -1.019827182163307e-02, - -1.105520547739066e-02, -1.195270300743193e-02, -1.289205910303846e-02, -1.387263484323160e-02, - -1.489528159506296e-02, -1.595856621933800e-02, -1.706288556735433e-02, -1.820666399965468e-02, - -1.939065975232718e-02, -2.061355417582714e-02, -2.187570925786862e-02, -2.317526315266411e-02, - -2.451227449041489e-02, -2.588471937157619e-02, -2.729263737090799e-02, -2.873390902713615e-02, - -3.020862738245264e-02, -3.171440372994384e-02, -3.325098858986303e-02, -3.481597793538342e-02, - -3.640892406933019e-02, -3.802742318209150e-02, -3.967067992672979e-02, -4.133575417353826e-02, - -4.302203371734278e-02, -4.472698045914417e-02, -4.645022292934329e-02, -4.818891490266687e-02, - -4.994225863256500e-02, -5.170690802826666e-02, -5.348162036097223e-02, -5.526334794593565e-02, - -5.705123152423822e-02, -5.884271749745559e-02, -6.063717235243996e-02, -6.243104027829089e-02, - -6.422303545004304e-02, -6.600961519440657e-02, -6.778962269634495e-02, -6.955996868581379e-02, - -7.131966266443390e-02, -7.306581273272733e-02, -7.479758913001458e-02, -7.651178225890490e-02, - -7.820711420768856e-02, -7.988010693411644e-02, -8.152964005319532e-02, -8.315237353264004e-02, - -8.474728946770714e-02, -8.631137544905677e-02, -8.784374452959058e-02, -8.934164364321417e-02, - -9.080411291245728e-02, -9.222795761428432e-02, -9.361232867223340e-02, -9.495377758870335e-02, - -9.625155313139856e-02, -9.750284620437569e-02, -9.870736514214426e-02, -9.986271288271026e-02, - -1.009680221406219e-01, -1.020202684361974e-01, -1.030183804850491e-01, -1.039596356759290e-01, - -1.048438825017798e-01, -1.056686838192766e-01, -1.064342821660323e-01, -1.071382314127799e-01, - -1.077799961121537e-01, -1.083570625865931e-01, -1.088690135027248e-01, -1.093135588677235e-01, - -1.096903559498340e-01, -1.099969655786929e-01, -1.102332261219973e-01, -1.103972812085189e-01, - -1.104898474883336e-01, -1.105086416532167e-01, -1.104537426996073e-01, -1.103225838568563e-01, - -1.101145827722143e-01, -1.098276928170364e-01, -1.094621746650760e-01, -1.090163960055733e-01, - -1.084908852561722e-01, -1.078834293141886e-01, -1.071937180231978e-01, -1.064196358069465e-01, - -1.055612509762041e-01, -1.046162812518618e-01, -1.035849043557610e-01, -1.024650162703341e-01, - -1.012568997532046e-01, -9.995864571932928e-02, -9.857014566194627e-02, -9.708911135857967e-02, - -9.551545820689084e-02, -9.384684920715425e-02, -9.208300062891550e-02, -9.022171021406450e-02, - -8.826309993000785e-02, -8.620493821803937e-02, -8.404742152815330e-02, -8.178792716809512e-02, - -7.942625026703617e-02, -7.695980775819990e-02, -7.438785600211463e-02, -7.170797002873608e-02, - -6.891994783815969e-02, -6.602189797715241e-02, -6.301349420724424e-02, -5.989191912667712e-02, - -5.665655641133161e-02, -5.330406164482222e-02, -4.983427241976235e-02, -4.624456893420224e-02, - -4.253455686336916e-02, -3.870195772538443e-02, -3.474585776145929e-02, -3.066341518682682e-02, - -2.645425077642105e-02, -2.211581608120528e-02, -1.764740541599136e-02, -1.304581363895818e-02, - -8.310425696208936e-03, -3.438268661133170e-03, 1.570315476576933e-03, 6.717697635290676e-03, - 1.200477020244778e-02, 1.743398319747869e-02, 2.300642061077823e-02, 2.872481423270595e-02, - 3.458896350634671e-02, 4.060106462625085e-02, 4.676102915752826e-02, 5.307133911821893e-02, - 5.953239090915557e-02, 6.614647812869151e-02, 7.291293184312803e-02, 7.983354189816511e-02, - 8.690807412770696e-02, 9.413813765275064e-02, 1.015233140203748e-01, 1.090651518336202e-01, - 1.167626546016197e-01, 1.246171387327525e-01, 1.326272948938113e-01, 1.407938190608664e-01, - 1.491152519299797e-01, 1.575921408388593e-01, 1.662224799248571e-01, 1.750067399059861e-01, - 1.839431938620024e-01, 1.930318183054904e-01, 2.022699854906251e-01, 2.116567430906184e-01, - 2.211888523410642e-01, 2.308655379767671e-01, 2.406837992341654e-01, 2.506420640291662e-01, - 2.607365124918583e-01, 2.709659073501196e-01, 2.813259021832532e-01, 2.918144694729168e-01, - 3.024270279840051e-01, 3.131603499997996e-01, 3.240095704645023e-01, 3.349719592361666e-01, - 3.460422935204829e-01, 3.572175180786021e-01, 3.684915649120530e-01, 3.798595119591716e-01, - 3.913146885756875e-01, 4.028532873867052e-01, 4.144688328137527e-01, 4.261571642320424e-01, - 4.379113897565727e-01, 4.497256320417501e-01, 4.615925445090212e-01, 4.735067030065239e-01, - 4.854600184866710e-01, 4.974471592901086e-01, 5.094597228333853e-01, 5.214909841729947e-01, - 5.335326819631583e-01, 5.455789811615239e-01, 5.576217157959890e-01, 5.696546730080154e-01, - 5.816685576268035e-01, 5.936560624526468e-01, 6.056083823929643e-01, 6.175192060085208e-01, - 6.293796611336280e-01, 6.411830842823245e-01, 6.529203544876097e-01, 6.645840786371451e-01, - 6.761653499550255e-01, 6.876573952173626e-01, 6.990511539119996e-01, 7.103400549562944e-01, - 7.215149331458728e-01, 7.325691772738999e-01, 7.434943718765665e-01, 7.542846327442048e-01, - 7.649313654540612e-01, 7.754281892901473e-01, 7.857670170752049e-01, 7.959414651061612e-01, - 8.059437233154637e-01, 8.157687070715176e-01, 8.254086223972127e-01, 8.348589373399948e-01, - 8.441125827416620e-01, 8.531651194538425e-01, 8.620108336276733e-01, 8.706456337542150e-01, - 8.790631561061171e-01, 8.872599706865123e-01, 8.952313288619367e-01, 9.029751680353524e-01, - 9.104863121445679e-01, 9.177625550620636e-01, 9.247997426966093e-01, 9.315962496426278e-01, - 9.381494858921667e-01, 9.444588390359354e-01, 9.505220861927248e-01, 9.563402921286364e-01, - 9.619114522936701e-01, 9.672366712325431e-01, 9.723156637834687e-01, 9.771501187120180e-01, - 9.817397501303696e-01, 9.860865871353246e-01, 9.901906380163595e-01, 9.940557180662704e-01, - 9.976842395284637e-01, 1.001080961257010e+00, 1.004247514102417e+00, 1.007188578458507e+00, - 1.009906654565108e+00, 1.012407428282884e+00, 1.014694702432600e+00, 1.016774659209400e+00, - 1.018650990561848e+00, 1.020330464463111e+00, 1.021817328911793e+00, 1.023118841384460e+00, - 1.024240262467000e+00, 1.025189721888128e+00, 1.025972450969440e+00, 1.026596938589443e+00, - 1.027069179375841e+00, 1.027397523939210e+00, 1.027587902203109e+00, 1.027648951922701e+00, - 1.027585830688143e+00, 1.027408519661012e+00, 1.027122986826984e+00, 1.026738673647482e+00, - 1.026261663878092e+00, 1.025701002415063e+00, 1.025061777648234e+00, 1.024353980976701e+00, - 1.023582385618774e+00, 1.022756514615106e+00, 1.021880604350422e+00, 1.020963871317665e+00, - 1.020009139549275e+00, 1.019027285501251e+00, 1.018019442784231e+00, 1.016996499560845e+00, - 1.015957433206324e+00, 1.014923441259795e+00, 1.013915946100629e+00, 1.013047565149327e+00, - 1.012216130365610e+00, 1.011044869639164e+00, 1.009914592130044e+00, 1.008824888092573e+00, - 1.007773858455400e+00, 1.006761700412993e+00, 1.005786648810854e+00, 1.004848753962734e+00, - 1.003946083413733e+00, 1.003078846506546e+00, 1.002245009135684e+00, 1.001444733905817e+00, - 1.000676188436651e+00, 9.999393169239009e-01, 9.992320848298057e-01, 9.985548127155425e-01, - 9.979055415627330e-01, 9.972842679758880e-01, 9.966890948441745e-01, 9.961203379971326e-01, - 9.955761256313581e-01, 9.950565724564597e-01, 9.945597525471822e-01, 9.940860378486615e-01, - 9.936337788972491e-01, 9.932031606606759e-01, 9.927921871265732e-01, 9.924015177880798e-01, - 9.920297273323891e-01, 9.916767775088281e-01, 9.913408767719142e-01, 9.910230654424902e-01, - 9.907216425865902e-01, 9.904366799536263e-01, 9.901668953434221e-01, 9.899131011580791e-01, - 9.896735637374597e-01, 9.894488374513719e-01, 9.892374835404283e-01, 9.890401927796704e-01, - 9.888556356037892e-01, 9.886843467692753e-01, 9.885247606051014e-01, 9.883778520531268e-01, - 9.882423270582524e-01, 9.881185638915363e-01, 9.880051626345804e-01, 9.879032023766432e-01, - 9.878111744348976e-01, 9.877295459610343e-01, 9.876571983429736e-01, 9.875949843246187e-01, - 9.875412739766566e-01, 9.874969061399389e-01, 9.874606249127551e-01, 9.874329809802893e-01, - 9.874126414437681e-01, 9.874004750404033e-01, 9.873949921033299e-01, 9.873969162747074e-01, - 9.874049060317581e-01, 9.874197049003676e-01, 9.874399717110517e-01, 9.874663281231737e-01, - 9.874973205882319e-01, 9.875338926695315e-01, 9.875746535410983e-01, 9.876201238703241e-01, - 9.876689801932402e-01, 9.877221556193183e-01, 9.877781920433015e-01, 9.878376489591358e-01, - 9.878991990245439e-01, 9.879637979933339e-01, 9.880300303653743e-01, 9.880984675859855e-01, - 9.881678007807095e-01, 9.882390300097154e-01, 9.883107693992456e-01, 9.883835200189653e-01, - 9.884560159878955e-01, 9.885294200392185e-01, 9.886022219397892e-01, 9.886749404176028e-01, - 9.887466261142505e-01, 9.888182771263505e-01, 9.888882480852147e-01, 9.889574384705896e-01, - 9.890247977602895e-01, 9.890911247701029e-01, 9.891551701556196e-01, 9.892178658748239e-01, - 9.892779555818088e-01, 9.893365186903538e-01, 9.893923680007577e-01, 9.894462830852175e-01, - 9.894972124952000e-01, 9.895463342815009e-01, 9.895923617530382e-01, 9.896362652966239e-01, - 9.896772011542693e-01, 9.897162195263046e-01, 9.897520286480039e-01, 9.897859195209235e-01, - 9.898170267411330e-01, 9.898462068764986e-01, 9.898725363809847e-01, 9.898975138787787e-01, - 9.899200050208486e-01, 9.899410789223559e-01, 9.899600605054418e-01, 9.899782261038060e-01, - 9.899945557067980e-01, 9.900103500807507e-01, 9.900248320990181e-01, 9.900394023736973e-01, - 9.900532105829365e-01, 9.900674746047259e-01, 9.900814722948890e-01, 9.900966926051257e-01, - 9.901122448734595e-01, 9.901293790312005e-01, 9.901474648912307e-01, 9.901680598867444e-01, - 9.901902265696609e-01, 9.902151896501201e-01, 9.902424418296485e-01, 9.902734448815004e-01, - 9.903071270768942e-01, 9.903448913950654e-01, 9.903862280081246e-01, 9.904324484666853e-01, - 9.904825650601110e-01, 9.905379830873822e-01, 9.905980602136440e-01, 9.906640366554630e-01, - 9.907348826312993e-01, 9.908120376822228e-01, 9.908947858311721e-01, 9.909842592301273e-01, - 9.910795247770178e-01, 9.911819240108124e-01, 9.912905118607647e-01, 9.914064705361564e-01, - 9.915288011543961e-01, 9.916586940166509e-01, 9.917952720685562e-01, 9.919396217291009e-01, - 9.920906151219310e-01, 9.922495028313456e-01, 9.924152398352751e-01, 9.925887208794144e-01, - 9.927688708468421e-01, 9.929569112537944e-01, 9.931516528513824e-01, 9.933539244159140e-01, - 9.935626893131695e-01, 9.937790866568735e-01, 9.940016434044485e-01, 9.942312024833810e-01, - 9.944668184371617e-01, 9.947093441694513e-01, 9.949572854565533e-01, 9.952116634297566e-01, - 9.954712635321227e-01, 9.957367951478069e-01, 9.960068616185641e-01, 9.962823025614079e-01, - 9.965617986382630e-01, 9.968461329825753e-01, 9.971338271912752e-01, 9.974256691222113e-01, - 9.977203369515556e-01, 9.980185087055744e-01, 9.983185871761977e-01, 9.986213520769593e-01, - 9.989255426466267e-01, 9.992317314100975e-01, 9.995382582242990e-01, 9.998461160718275e-01, - 1.000153907612080e+00, 1.000461955079660e+00, 1.000768859280338e+00, 1.001075613053728e+00, - 1.001380551217109e+00, 1.001684244734497e+00, 1.001985425397567e+00, 1.002284871786226e+00, - 1.002580975161843e+00, 1.002874411368430e+00, 1.003163845364970e+00, 1.003450063374329e+00, - 1.003731570287893e+00, 1.004009147462043e+00, 1.004281457582935e+00, 1.004549339226336e+00, - 1.004811375053364e+00, 1.005068272394360e+00, 1.005318795748286e+00, 1.005563968008037e+00, - 1.005802269635282e+00, 1.006034554002353e+00, 1.006259855360867e+00, 1.006479018139540e+00, - 1.006690541428116e+00, 1.006895570408563e+00, 1.007093045696527e+00, 1.007283799246233e+00, - 1.007466616298057e+00, 1.007642728426847e+00, 1.007811036585595e+00, 1.007972441990187e+00, - 1.008125875904472e+00, 1.008272602383284e+00, 1.008411468616852e+00, 1.008543573152632e+00, - 1.008668018334797e+00, 1.008786009787269e+00, 1.008896526233555e+00, 1.009000766336071e+00, - 1.009097763850333e+00, 1.009188880897370e+00, 1.009273163797313e+00, 1.009351762546296e+00, - 1.009423944949143e+00, 1.009491175244507e+00, 1.009552401900961e+00, 1.009608886895764e+00, - 1.009659973830751e+00, 1.009707093778162e+00, 1.009749238562067e+00, 1.009787744284661e+00, - 1.009822090220407e+00, 1.009853706282597e+00, 1.009881498943010e+00, 1.009906958448099e+00, - 1.009929567021562e+00, 1.009950573483366e+00, 1.009969021400474e+00, 1.009986499185054e+00, - 1.010002363879044e+00, 1.010017890428877e+00, 1.010032170180360e+00, 1.010046722045583e+00, - 1.010060809299530e+00, 1.010075674445289e+00, 1.010090449982098e+00, 1.010106564965965e+00, - 1.010123226584120e+00, 1.010141762173145e+00, 1.010161131093372e+00, 1.010182635897876e+00, - 1.010205587931660e+00, 1.010231078494249e+00, 1.010257950227988e+00, 1.010287732968580e+00, - 1.010319484524512e+00, 1.010354079663767e+00, 1.010390635488037e+00, 1.010430470494512e+00, - 1.010472266495074e+00, 1.010517096381509e+00, 1.010564099281000e+00, 1.010614266894512e+00, - 1.010666285876455e+00, 1.010721360243234e+00, 1.010778416755264e+00, 1.010838252644461e+00, - 1.010899655674578e+00, 1.010963729626641e+00, 1.011029191301694e+00, 1.011096993993037e+00, - 1.011165861239173e+00, 1.011236610341260e+00, 1.011308167670753e+00, 1.011381453638912e+00, - 1.011454785713102e+00, 1.011529185153809e+00, 1.011603680910505e+00, 1.011678803938046e+00, - 1.011753008569803e+00, 1.011827484797985e+00, 1.011900936547881e+00, 1.011973876511603e+00, - 1.012044885003304e+00, 1.012114985644919e+00, 1.012182837094955e+00, 1.012249023976742e+00, - 1.012312095063070e+00, 1.012373028737774e+00, 1.012430463679316e+00, 1.012484972246822e+00, - 1.012535058602453e+00, 1.012581678169188e+00, 1.012623472898504e+00, 1.012660975529858e+00, - 1.012692758750213e+00, 1.012719789201144e+00, 1.012740575296603e+00, 1.012755753887085e+00, - 1.012763948841204e+00, 1.012765922449960e+00, 1.012760298661069e+00, 1.012747819936584e+00, - 1.012726958954961e+00, 1.012698607692183e+00, 1.012661400539405e+00, 1.012615904116265e+00, - 1.012560833005713e+00, 1.012497050269805e+00, 1.012422888521601e+00, 1.012339226241367e+00, - 1.012244921966297e+00, 1.012140460211194e+00, 1.012024302085441e+00, 1.011897560567707e+00, - 1.011758810583150e+00, 1.011608449127642e+00, 1.011445162723270e+00, 1.011269960947744e+00, - 1.011081255645969e+00, 1.010879608424312e+00, 1.010663676735228e+00, 1.010434184200640e+00, - 1.010189681124657e+00, 1.009930754807923e+00, 1.009655660215271e+00, 1.009365251564694e+00, - 1.009058249873833e+00, 1.008734758578989e+00, 1.008393079963091e+00, 1.008034308295421e+00, - 1.007656661215973e+00, 1.007260142622887e+00, 1.006843352506855e+00, 1.006407009542103e+00, - 1.005949145170711e+00, 1.005470005637052e+00, 1.004967986424467e+00, 1.004443531995945e+00, - 1.003894772403371e+00, 1.003321903663793e+00, 1.002723127308148e+00, 1.002098854400575e+00, - 1.001447278873483e+00, 1.000768505317086e+00, 1.000060686758758e+00, 9.993242684851855e-01, - 9.985573503390627e-01, 9.977600196406868e-01, 9.969306036935497e-01, 9.960694269553644e-01, - 9.951746430061121e-01, 9.942466438407230e-01, 9.932837131068657e-01, 9.922861082472264e-01, - 9.912523092989319e-01, 9.901827419790691e-01, 9.890757868707590e-01, 9.879313024174022e-01, - 9.863553220272523e-01, 9.847362453480265e-01, 9.831750948772566e-01, 9.815583336011345e-01, - 9.798613526271561e-01, 9.780617486993630e-01, 9.761574317374303e-01, 9.741378617337759e-01, - 9.719990112065752e-01, 9.697327413658168e-01, 9.673331975559332e-01, 9.647915124057732e-01, - 9.621011497566145e-01, 9.592539757044516e-01, 9.562427177295731e-01, 9.530600909726344e-01, - 9.496984081652284e-01, 9.461498120176854e-01, 9.424071613625743e-01, 9.384634163826711e-01, - 9.343112966094085e-01, 9.299449872197452e-01, 9.253567968750328e-01, 9.205404627076625e-01, - 9.154896280575360e-01, 9.101986790930605e-01, 9.046620597741508e-01, 8.988755194372424e-01, - 8.928338316495705e-01, 8.865337190368053e-01, 8.799712722567934e-01, 8.731437835983047e-01, - 8.660476534563131e-01, 8.586812520174252e-01, 8.510420440685049e-01, 8.431297226886574e-01, - 8.349435141989714e-01, 8.264839911291133e-01, 8.177505366573690e-01, 8.087449817124315e-01, - 7.994681492797084e-01, 7.899235162194718e-01, 7.801137731566502e-01, 7.700431275216928e-01, - 7.597145736971065e-01, 7.491330971820804e-01, 7.383028603058783e-01, 7.272298755824693e-01, - 7.159201919962611e-01, 7.043814340356083e-01, 6.926196927377140e-01, 6.806438831866077e-01, - 6.684616478236647e-01, 6.560830137986515e-01, 6.435179268559957e-01, 6.307755329382612e-01, - 6.178641647786525e-01, 6.047954625702541e-01, 5.915799587176216e-01, 5.782289366005894e-01, - 5.647535885752191e-01, 5.511703155400274e-01, 5.374905090437071e-01, 5.237263500445715e-01, - 5.098915423728255e-01, 4.960008074926423e-01, 4.820662943337458e-01, 4.681017110048007e-01, - 4.541216995958746e-01, 4.401421815729068e-01, 4.261772971493010e-01, 4.122417888542512e-01, - 3.983499612526493e-01, 3.845172335531009e-01, 3.707583717376236e-01, 3.570886786795506e-01, - 3.435228672445627e-01, 3.300763764703638e-01, 3.167640325043893e-01, 3.036004651973109e-01, - 2.905996158436682e-01, 2.777758503744847e-01, 2.651434678028531e-01, 2.527161881181577e-01, - 2.405069849650012e-01, 2.285283969438072e-01, 2.167933432162879e-01, 2.053139897833021e-01, - 1.941021906320988e-01, 1.831680872008943e-01, 1.725221947208913e-01, 1.621735416384834e-01, - 1.521320683467849e-01, 1.424052801149985e-01, 1.330015240938615e-01, 1.239260664828526e-01, - 1.151858295527293e-01, 1.067840430193724e-01, 9.872637505002878e-02, 9.101379000888035e-02, - 8.365057236623055e-02, 7.663508305536153e-02, 6.997033405748826e-02, 6.365188111381365e-02, - 5.768176015814392e-02, 5.205244216987966e-02, 4.676538412257621e-02, 4.180950541438362e-02, - 3.718640251368464e-02, 3.288072750732215e-02, 2.889548499582958e-02, 2.520980565928884e-02, - 2.183057564646272e-02, 1.872896194002638e-02, 1.592127815153420e-02, 1.336381425803020e-02, - 1.108558877807282e-02, 8.943474189364638e-03, 6.758124889697787e-03, 3.504438130619497e-03, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_80_5ms[80] = { - 9.959086585790517e-04, 3.819056787237678e-03, 9.540832613229890e-03, 1.921659800166160e-02, 3.382719081038548e-02, - 5.424831667522354e-02, 8.120777668775610e-02, 1.152171887125930e-01, 1.564942331034909e-01, 2.049363422022628e-01, - 2.601166575816199e-01, 3.212814164616093e-01, 3.873472997948746e-01, 4.569497078592333e-01, 5.285192958868393e-01, - 6.003522489375573e-01, 6.706896380227332e-01, 7.378044458510402e-01, 8.000925313431716e-01, 8.561409184410547e-01, - 9.048272294524792e-01, 9.453685031730190e-01, 9.773507430600533e-01, 1.000800872826561e+00, 1.016171590112097e+00, - 1.024315247630982e+00, 1.026415431432931e+00, 1.023858366571912e+00, 1.018135705524407e+00, 1.010794822557756e+00, - 1.003406509762925e+00, 9.967831265986109e-01, 9.920995520917141e-01, 9.892206942816891e-01, 9.879658322200813e-01, - 9.881273531631907e-01, 9.894805541465801e-01, 9.917849916000535e-01, 9.947847580943504e-01, 9.982119669301160e-01, - 1.001791235858836e+00, 1.005242583245485e+00, 1.008283053756130e+00, 1.010631281038659e+00, 1.012015300253356e+00, - 1.012180753005270e+00, 1.010896765282633e+00, 1.007963362035220e+00, 1.003227255072391e+00, 9.966050551498514e-01, - 9.868284225039941e-01, 9.731250287581631e-01, 9.540636479502398e-01, 9.283864275822276e-01, 8.950916858157935e-01, - 8.534769362643825e-01, 8.032090930429980e-01, 7.444735201251689e-01, 6.780787033699449e-01, 6.053970453856138e-01, - 5.282077505750667e-01, 4.486552956056635e-01, 3.691875990296312e-01, 2.924566408966777e-01, 2.210718537110463e-01, - 1.573148583944309e-01, 1.030525757797768e-01, 5.982732244758054e-02, 2.871831923385133e-02, 9.683884928956490e-03, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_160_5ms[160] = { - 6.143388180964179e-04, 1.489582832987000e-03, 2.884104959764029e-03, 4.934298832466617e-03, 7.779130464154915e-03, - 1.154910606525086e-02, 1.637155619860352e-02, 2.237116158648752e-02, 2.966159685753317e-02, 3.835663329277230e-02, - 4.855610986150206e-02, 6.035055738891727e-02, 7.382288203064732e-02, 8.903563687211119e-02, 1.060356225286319e-01, - 1.248534855777947e-01, 1.454931890869180e-01, 1.679435556337752e-01, 1.921728622634411e-01, 2.181238261985594e-01, - 2.457259744642953e-01, 2.748839432649996e-01, 3.054824712370942e-01, 3.373873799614014e-01, 3.704415932452488e-01, - 4.044749630814483e-01, 4.393004362003260e-01, 4.747225454237193e-01, 5.105341492548225e-01, 5.465201916422433e-01, - 5.824658100332457e-01, 6.181452662624718e-01, 6.533411462740817e-01, 6.878367295965062e-01, 7.214176027060971e-01, - 7.538887973483771e-01, 7.850546571907628e-01, 8.147397447696774e-01, 8.427819363777799e-01, 8.690376742017057e-01, - 8.933935477349644e-01, 9.157483563218768e-01, 9.360270196617569e-01, 9.541731142261065e-01, 9.701635474343885e-01, - 9.840036439809510e-01, 9.957199420334376e-01, 1.005374268639838e+00, 1.013046655758663e+00, 1.018843380560658e+00, - 1.022896948293643e+00, 1.025355286710874e+00, 1.026382881625701e+00, 1.026155530733488e+00, 1.024853974580724e+00, - 1.022664602721801e+00, 1.019779396547454e+00, 1.016391686789653e+00, 1.012697033320358e+00, 1.008885191761748e+00, - 1.005378742804807e+00, 1.001563778373068e+00, 9.982531564931281e-01, 9.954346644968789e-01, 9.930950268060122e-01, - 9.912170911359961e-01, 9.897805192546195e-01, 9.887624937408933e-01, 9.881383235740961e-01, 9.878819413827574e-01, - 9.879662130250981e-01, 9.883630508181326e-01, 9.890434070785485e-01, 9.899772316163624e-01, 9.911334564321237e-01, - 9.924800441092685e-01, 9.939841207305906e-01, 9.956121471675398e-01, 9.973300590248015e-01, 9.991033633647473e-01, - 1.000897441314013e+00, 1.002677088643863e+00, 1.004407190937699e+00, 1.006052289109999e+00, 1.007576934100958e+00, - 1.008945862447015e+00, 1.010124241309341e+00, 1.011077969726137e+00, 1.011773962181442e+00, 1.012180362866919e+00, - 1.012266707295288e+00, 1.012004064757857e+00, 1.011365223023975e+00, 1.010324996851905e+00, 1.008860731864438e+00, - 1.006952983357691e+00, 1.004586273379809e+00, 1.001749900308864e+00, 9.984386632116344e-01, 9.946500332901397e-01, - 9.895756853352172e-01, 9.838303127859196e-01, 9.769999155793757e-01, 9.689141159310996e-01, 9.594038121639412e-01, - 9.483086322505029e-01, 9.354860218216989e-01, 9.208101305030523e-01, 9.041732260327581e-01, 8.854882249661838e-01, - 8.646864947605046e-01, 8.417237467711145e-01, 8.165875713256009e-01, 7.892986353718001e-01, 7.599171886893816e-01, - 7.285474515411827e-01, 6.953282935906302e-01, 6.604334017809461e-01, 6.240661431421666e-01, 5.864461424698465e-01, - 5.478160663871147e-01, 5.084499758302218e-01, 4.686361426418982e-01, 4.286789889246253e-01, 3.889032719013045e-01, - 3.496431418636314e-01, 3.112360816586544e-01, 2.740128472224535e-01, 2.382847225401666e-01, 2.043379825955252e-01, - 1.724305860483632e-01, 1.427939789949265e-01, 1.156385879569741e-01, 9.115821766571995e-02, 6.952749039054593e-02, - 5.088975408628225e-02, 3.533430192568954e-02, 2.286680405144430e-02, 1.338005016725895e-02, 6.640506529168652e-03, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_240_5ms[240] = { - 5.087227626168386e-04, 9.959086585790517e-04, 1.682208006328800e-03, 2.609697259047744e-03, 3.819056787237678e-03, - 5.349319592933909e-03, 7.243906383895192e-03, 9.540832613229890e-03, 1.227637642543709e-02, 1.548950238899404e-02, - 1.921659800166160e-02, 2.349369619441617e-02, 2.835199581667961e-02, 3.382719081038548e-02, 3.994939538719628e-02, - 4.674775238543380e-02, 5.424831667522354e-02, 6.247770776443612e-02, 7.145835917501348e-02, 8.120777668775610e-02, - 9.174400412319896e-02, 1.030764959637497e-01, 1.152171887125930e-01, 1.281665713944242e-01, 1.419264381068653e-01, - 1.564942331034909e-01, 1.718593189799504e-01, 1.880134254543744e-01, 2.049363422022628e-01, 2.226123055761096e-01, - 2.410151242797736e-01, 2.601166575816199e-01, 2.798871008989962e-01, 3.002880135563586e-01, 3.212814164616093e-01, - 3.428208463088390e-01, 3.648596557863134e-01, 3.873472997948746e-01, 4.102294951869188e-01, 4.334494534591082e-01, - 4.569497078592333e-01, 4.806696403251166e-01, 5.045473815014847e-01, 5.285192958868393e-01, 5.525196099932443e-01, - 5.764872452085427e-01, 6.003522489375573e-01, 6.240509872809882e-01, 6.475182586093196e-01, 6.706896380227332e-01, - 6.935029068990036e-01, 7.158927516396895e-01, 7.378044458510402e-01, 7.591787241845952e-01, 7.799586608897265e-01, - 8.000925313431716e-01, 8.195318652294690e-01, 8.382288957404715e-01, 8.561409184410547e-01, 8.732316951214179e-01, - 8.894702022170831e-01, 9.048272294524792e-01, 9.192736375782965e-01, 9.327940405054362e-01, 9.453685031730190e-01, - 9.569883933538136e-01, 9.676486424195593e-01, 9.773507430600533e-01, 9.861027831072527e-01, 9.939122412655677e-01, - 1.000800872826561e+00, 1.006787811971719e+00, 1.011901269172423e+00, 1.016171590112097e+00, 1.019636414864842e+00, - 1.022336613864005e+00, 1.024315247630982e+00, 1.025621299895396e+00, 1.026303439275662e+00, 1.026415431432931e+00, - 1.026007933174836e+00, 1.025137435167917e+00, 1.023858366571912e+00, 1.022226936424625e+00, 1.020300550334848e+00, - 1.018135705524407e+00, 1.015792146756340e+00, 1.013325966774524e+00, 1.010794822557756e+00, 1.008265131568879e+00, - 1.006046874304407e+00, 1.003406509762925e+00, 1.000977398831985e+00, 9.987704535700208e-01, 9.967831265986109e-01, - 9.950118905889862e-01, 9.934523971504882e-01, 9.920995520917141e-01, 9.909475998606236e-01, 9.899902426925508e-01, - 9.892206942816891e-01, 9.886318043013834e-01, 9.882160904669929e-01, 9.879658322200813e-01, 9.878730767519871e-01, - 9.879296932443894e-01, 9.881273531631907e-01, 9.884575535474619e-01, 9.889115869213529e-01, 9.894805541465801e-01, - 9.901553455166457e-01, 9.909266562913843e-01, 9.917849916000535e-01, 9.927206838643636e-01, 9.937239208721489e-01, - 9.947847580943504e-01, 9.958931493776203e-01, 9.970389567617592e-01, 9.982119669301160e-01, 9.994020338838508e-01, - 1.000598323893564e+00, 1.001791235858836e+00, 1.002969837054169e+00, 1.004123786397111e+00, 1.005242583245485e+00, - 1.006315717067918e+00, 1.007332693127034e+00, 1.008283053756130e+00, 1.009156423082384e+00, 1.009942535308151e+00, - 1.010631281038659e+00, 1.011212744622770e+00, 1.011677230257499e+00, 1.012015300253356e+00, 1.012217779097186e+00, - 1.012275790821109e+00, 1.012180753005270e+00, 1.011924425888915e+00, 1.011498917644724e+00, 1.010896765282633e+00, - 1.010110965619444e+00, 1.009135094671655e+00, 1.007963362035220e+00, 1.006590756505588e+00, 1.005013115379014e+00, - 1.003227255072391e+00, 1.001231060075500e+00, 9.990235555436858e-01, 9.966050551498514e-01, 9.939894706113089e-01, - 9.904539200261149e-01, 9.868284225039941e-01, 9.827716736909488e-01, 9.782206672373213e-01, 9.731250287581631e-01, - 9.674323528812744e-01, 9.610947043524248e-01, 9.540636479502398e-01, 9.462952991190324e-01, 9.377489107516087e-01, - 9.283864275822276e-01, 9.181762606422500e-01, 9.070861558801854e-01, 8.950916858157935e-01, 8.821696237804294e-01, - 8.683025287048570e-01, 8.534769362643825e-01, 8.376852006833730e-01, 8.209275259764013e-01, 8.032090930429980e-01, - 7.845450482523652e-01, 7.649554851899686e-01, 7.444735201251689e-01, 7.231348066419057e-01, 7.009860555207412e-01, - 6.780787033699450e-01, 6.544686506489734e-01, 6.302212149502727e-01, 6.053970453856138e-01, 5.800715766089168e-01, - 5.543129276657669e-01, 5.282077505750727e-01, 5.018369724442092e-01, 4.752902962082383e-01, 4.486552956056652e-01, - 4.220281118338883e-01, 3.955057965950340e-01, 3.691875990296320e-01, 3.431732847389720e-01, 3.175633015043183e-01, - 2.924566408966782e-01, 2.679463783886042e-01, 2.441231331518492e-01, 2.210718537110466e-01, 1.988719153219592e-01, - 1.775967625327044e-01, 1.573148583944310e-01, 1.380903364946733e-01, 1.199837497591550e-01, 1.030525757797769e-01, - 8.735085011789188e-02, 7.292811584897502e-02, 5.982732244758056e-02, 4.808178837444506e-02, 3.771135297837851e-02, - 2.871831923385135e-02, 2.108352028641225e-02, 1.476289412849005e-02, 9.683884928956495e-03, 5.642168789286858e-03, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_320_5ms[320] = { - 4.595886345493055e-04, 7.919323614002698e-04, 1.227927169310031e-03, 1.783653266717233e-03, 2.479549413444207e-03, - 3.329799454594261e-03, 4.353535478916468e-03, 5.564965156664018e-03, 6.986108359341676e-03, 8.629882322202329e-03, - 1.051343406844975e-02, 1.265082642578719e-02, 1.506090447446532e-02, 1.775591229287213e-02, 2.075475983187825e-02, - 2.406813715401559e-02, 2.771207863541604e-02, 3.169933248543932e-02, 3.604609640533871e-02, 4.076128638095439e-02, - 4.586038120884381e-02, 5.135136676471998e-02, 5.724780220726930e-02, 6.355854744461048e-02, 7.029450733434550e-02, - 7.745987198268531e-02, 8.506635369887924e-02, 9.311641620512773e-02, 1.016162955027316e-01, 1.105690806271684e-01, - 1.199789286645804e-01, 1.298417294090302e-01, 1.401623800497866e-01, 1.509371564593891e-01, 1.621632295622287e-01, - 1.738354123649302e-01, 1.859520359191026e-01, 1.985008828937603e-01, 2.114778554475382e-01, 2.248732557074316e-01, - 2.386763947872762e-01, 2.528729453658238e-01, 2.674547009618951e-01, 2.824031465430401e-01, 2.977050145264297e-01, - 3.133419120661713e-01, 3.292976696294886e-01, 3.455490160824131e-01, 3.620795045342974e-01, 3.788648665671841e-01, - 3.958851576591690e-01, 4.131143794748322e-01, 4.305308301005456e-01, 4.481076715576617e-01, 4.658227790464821e-01, - 4.836466393241829e-01, 5.015564851667653e-01, 5.195228071176610e-01, 5.375197039843709e-01, 5.555183841040963e-01, - 5.734957812557457e-01, 5.914186654649489e-01, 6.092622887527459e-01, 6.269981160888640e-01, 6.446002007776794e-01, - 6.620384583071039e-01, 6.792906550106088e-01, 6.963256426589250e-01, 7.131194393772130e-01, 7.296469905863920e-01, - 7.458864594794676e-01, 7.618094719403713e-01, 7.773958448163656e-01, 7.926208751337592e-01, 8.074666387233143e-01, - 8.219101564897180e-01, 8.359343163788637e-01, 8.495180470826319e-01, 8.626485837105826e-01, 8.753083234662220e-01, - 8.874884715160425e-01, 8.991737724042251e-01, 9.103527429187326e-01, 9.210144133066616e-01, 9.311556192776946e-01, - 9.407644740241826e-01, 9.498382236872068e-01, 9.583732599601223e-01, 9.663690412284377e-01, 9.738235617865406e-01, - 9.807442506043361e-01, 9.871297972052695e-01, 9.929872268444632e-01, 9.983241398929388e-01, 1.003150760219063e+00, - 1.007473713377193e+00, 1.011309151636166e+00, 1.014666681083198e+00, 1.017563337333301e+00, 1.020014681326785e+00, - 1.022039872150903e+00, 1.023654257342442e+00, 1.024881624147540e+00, 1.025739288978437e+00, 1.026250709375593e+00, - 1.026436666375082e+00, 1.026320857404224e+00, 1.025922917798664e+00, 1.025269979527211e+00, 1.024382188798244e+00, - 1.023284940887058e+00, 1.022000829220643e+00, 1.020555973231408e+00, 1.018971390778550e+00, 1.017275179369116e+00, - 1.015489129111694e+00, 1.013639356938881e+00, 1.011747750709711e+00, 1.009840844244693e+00, 1.007939764480188e+00, - 1.006407400915498e+00, 1.004374825095777e+00, 1.002469814737132e+00, 1.000689073754539e+00, 9.990346001249977e-01, - 9.975024904153303e-01, 9.960941547576162e-01, 9.948051243621099e-01, 9.936362728142866e-01, 9.925826537087717e-01, - 9.916447007525191e-01, 9.908170758245324e-01, 9.900998445795673e-01, 9.894873685512386e-01, 9.889794323427195e-01, - 9.885701787626714e-01, 9.882591911282058e-01, 9.880404423341358e-01, 9.879133688360181e-01, 9.878718098237022e-01, - 9.879150762106034e-01, 9.880368938846610e-01, 9.882364564839506e-01, 9.885073687439192e-01, 9.888487088987707e-01, - 9.892539488627546e-01, 9.897220412447528e-01, 9.902463287269285e-01, 9.908256340476208e-01, 9.914531811725067e-01, - 9.921276814881759e-01, 9.928422499725458e-01, 9.935955098307742e-01, 9.943804814776256e-01, 9.951957244449919e-01, - 9.960341878404958e-01, 9.968943831870675e-01, 9.977692009836100e-01, 9.986571134591464e-01, 9.995509738170480e-01, - 1.000449227898040e+00, 1.001344692310058e+00, 1.002235786606954e+00, 1.003115291715261e+00, 1.003981602446902e+00, - 1.004827468041713e+00, 1.005651275972376e+00, 1.006445772052972e+00, 1.007209352772459e+00, 1.007934783656087e+00, - 1.008620496650569e+00, 1.009259314290145e+00, 1.009849742422788e+00, 1.010384692193296e+00, 1.010862783160582e+00, - 1.011277044709547e+00, 1.011626247430694e+00, 1.011903571699736e+00, 1.012107954864219e+00, 1.012232755709885e+00, - 1.012277089047072e+00, 1.012234505114778e+00, 1.012104319978655e+00, 1.011880293122688e+00, 1.011561972516341e+00, - 1.011143373963981e+00, 1.010624321020038e+00, 1.009999148545101e+00, 1.009268031808824e+00, 1.008425698479647e+00, - 1.007472774447058e+00, 1.006404483571931e+00, 1.005222003295591e+00, 1.003921160689206e+00, 1.002503762756151e+00, - 1.000966332772540e+00, 9.993114007411373e-01, 9.975362702189898e-01, 9.956442306333592e-01, 9.936333924912825e-01, - 9.908677480361242e-01, 9.882326326262749e-01, 9.853620567056602e-01, 9.822305093671991e-01, 9.788185853162172e-01, - 9.751026333215268e-01, 9.710631852370086e-01, 9.666759668947944e-01, 9.619242192293307e-01, 9.567841986369235e-01, - 9.512394303101863e-01, 9.452700238623795e-01, 9.388615698236068e-01, 9.319946435581106e-01, 9.246592033932568e-01, - 9.168383396399868e-01, 9.085218034087421e-01, 8.996967011299613e-01, 8.903562054918268e-01, 8.804877931535187e-01, - 8.700884209228057e-01, 8.591492134848259e-01, 8.476686394755906e-01, 8.356428970797861e-01, 8.230753889817990e-01, - 8.099649296155544e-01, 7.963204506324437e-01, 7.821460539775005e-01, 7.674541821769616e-01, 7.522563457568547e-01, - 7.365702052057368e-01, 7.204090552899627e-01, 7.037975107157410e-01, 6.867542812151157e-01, 6.693041888771051e-01, - 6.514710959179395e-01, 6.332854832820911e-01, 6.147685389896460e-01, 5.959553778639692e-01, 5.768737955463938e-01, - 5.575534287167304e-01, 5.380320138068979e-01, 5.183454027643563e-01, 4.985259415650634e-01, 4.786156067459849e-01, - 4.586473038370941e-01, 4.386643656872842e-01, 4.187046888325280e-01, 3.988123056192917e-01, 3.790262923635886e-01, - 3.593914828698096e-01, 3.399474132903109e-01, 3.207392420889753e-01, 3.018061113177048e-01, 2.831905952786929e-01, - 2.649288369241889e-01, 2.470608550624402e-01, 2.296201119084317e-01, 2.126433716126151e-01, 1.961601816145380e-01, - 1.802035203864437e-01, 1.647996883470626e-01, 1.499787548077656e-01, 1.357643522991611e-01, 1.221842534547464e-01, - 1.092601994264172e-01, 9.701788451015501e-02, 8.547680283183663e-02, 7.465976378295235e-02, 6.458254322751883e-02, - 5.526281189874138e-02, 4.670976978373095e-02, 3.893244425578719e-02, 3.192976013776996e-02, 2.569810636390756e-02, - 2.022259265088492e-02, 1.548317776486452e-02, 1.144924909653903e-02, 8.076482660383199e-03, 5.300044080947794e-03, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_WINDOW_480_5ms[480] = { - 4.090106504820579e-04, 6.143388180964179e-04, 8.571759876954877e-04, 1.147015057857495e-03, 1.489582832987000e-03, - 1.889770382231583e-03, 2.353000800169909e-03, 2.884104959764029e-03, 3.488213786635855e-03, 4.170040431489613e-03, - 4.934298832466617e-03, 5.787076505403503e-03, 6.733811743137561e-03, 7.779130464154915e-03, 8.927044958757816e-03, - 1.018202888968871e-02, 1.154910606525086e-02, 1.303349217699797e-02, 1.463951288465963e-02, 1.637155619860352e-02, - 1.823455383898077e-02, 2.023309488998589e-02, 2.237116158648752e-02, 2.465237348403478e-02, 2.708101935270475e-02, - 2.966159685753317e-02, 3.239884850877327e-02, 3.529601774976465e-02, 3.835663329277230e-02, 4.158447932459513e-02, - 4.498322421745353e-02, 4.855610986150206e-02, 5.230596475016741e-02, 5.623624576084146e-02, 6.035055738891727e-02, - 6.465186317477950e-02, 6.914195749790462e-02, 7.382288203064732e-02, 7.869709331995660e-02, 8.376761638427657e-02, - 8.903563687211118e-02, 9.450199243028472e-02, 1.001680193006426e-01, 1.060356225286319e-01, 1.121060220821844e-01, - 1.183788547045326e-01, 1.248534855777947e-01, 1.315302847610869e-01, 1.384103079528939e-01, 1.454931890869180e-01, - 1.527772946853750e-01, 1.602608842337125e-01, 1.679435556337752e-01, 1.758245615079801e-01, 1.839020119821303e-01, - 1.921728622634411e-01, 2.006344295681524e-01, 2.092853879977170e-01, 2.181238261985594e-01, 2.271462264407930e-01, - 2.363479205237173e-01, 2.457259744642953e-01, 2.552771551741124e-01, 2.649981094228982e-01, 2.748839432649996e-01, - 2.849296444030153e-01, 2.951306505827265e-01, 3.054824712370942e-01, 3.159799638238941e-01, 3.266169794538543e-01, - 3.373873799614014e-01, 3.482855915638277e-01, 3.593057693987583e-01, 3.704415932452488e-01, 3.816862385160692e-01, - 3.930329782788047e-01, 4.044749630814483e-01, 4.160051103939122e-01, 4.276159595085598e-01, 4.393004362003260e-01, - 4.510516333434032e-01, 4.628616046119925e-01, 4.747225454237193e-01, 4.866266705542529e-01, 4.985664508456704e-01, - 5.105341492548225e-01, 5.225212793188740e-01, 5.345190505841265e-01, 5.465201916422433e-01, 5.585172769552711e-01, - 5.705021536899105e-01, 5.824658100332457e-01, 5.943991720381216e-01, 6.062948176207270e-01, 6.181452662624718e-01, - 6.299422016714543e-01, 6.416768736044914e-01, 6.533411462740817e-01, 6.649277540000037e-01, 6.764292700223311e-01, - 6.878367295965062e-01, 6.991421467689277e-01, 7.103379606632721e-01, 7.214176027060971e-01, 7.323746102405828e-01, - 7.432008025932804e-01, 7.538887973483771e-01, 7.644315495717613e-01, 7.748223151443820e-01, 7.850546571907628e-01, - 7.951223518167163e-01, 8.050193862201107e-01, 8.147397447696774e-01, 8.242774413707643e-01, 8.336267114335371e-01, - 8.427819363777799e-01, 8.517386186427548e-01, 8.604920874939698e-01, 8.690376742017057e-01, 8.773720451249032e-01, - 8.854927938913381e-01, 8.933935477349644e-01, 9.010727088526728e-01, 9.085249398881980e-01, 9.157483563218768e-01, - 9.227413839712016e-01, 9.295017469413066e-01, 9.360270196617569e-01, 9.423143052164881e-01, 9.483629792665091e-01, - 9.541731142261065e-01, 9.597438382130120e-01, 9.650738394220176e-01, 9.701635474343885e-01, 9.750143364412617e-01, - 9.796277191617885e-01, 9.840036439809510e-01, 9.881426772731259e-01, 9.920470446911211e-01, 9.957199420334376e-01, - 9.991640812275709e-01, 1.002381307710643e+00, 1.005374268639838e+00, 1.008146718214831e+00, 1.010703123647275e+00, - 1.013046655758663e+00, 1.015181271161417e+00, 1.017111643578857e+00, 1.018843380560658e+00, 1.020381713994816e+00, - 1.021731101971518e+00, 1.022896948293643e+00, 1.023885455671576e+00, 1.024702974608899e+00, 1.025355286710874e+00, - 1.025848243050604e+00, 1.026188366261215e+00, 1.026382881625701e+00, 1.026438102255574e+00, 1.026360125820994e+00, - 1.026155530733488e+00, 1.025831456886557e+00, 1.025395432284244e+00, 1.024853974580724e+00, 1.024213482124578e+00, - 1.023481184943025e+00, 1.022664602721801e+00, 1.021770903480975e+00, 1.020806917660529e+00, 1.019779396547454e+00, - 1.018695995335235e+00, 1.017564416918053e+00, 1.016391686789653e+00, 1.015184918030332e+00, 1.013950835315021e+00, - 1.012697033320358e+00, 1.011430749860716e+00, 1.010158346781076e+00, 1.008885191761748e+00, 1.007592718305943e+00, - 1.006805603478092e+00, 1.005378742804807e+00, 1.004049051787112e+00, 1.002778356298787e+00, 1.001563778373068e+00, - 1.000404915291105e+00, 9.993014844615166e-01, 9.982531564931281e-01, 9.972595460676951e-01, 9.963202131848272e-01, - 9.954346644968789e-01, 9.946023543844607e-01, 9.938226881029791e-01, 9.930950268060122e-01, 9.924186919309267e-01, - 9.917929657090736e-01, 9.912170911359961e-01, 9.906902760441473e-01, 9.902117003786811e-01, 9.897805192546193e-01, - 9.893958602389157e-01, 9.890568243690241e-01, 9.887624937408933e-01, 9.885119364350415e-01, 9.883042028597552e-01, - 9.881383235740961e-01, 9.880133161159576e-01, 9.879281898513085e-01, 9.878819413827574e-01, 9.878735508484809e-01, - 9.879019873841568e-01, 9.879662130250981e-01, 9.880651778500144e-01, 9.881978162133899e-01, 9.883630508181326e-01, - 9.885597957603544e-01, 9.887869526128024e-01, 9.890434070785485e-01, 9.893280319166613e-01, 9.896396899060125e-01, - 9.899772316163624e-01, 9.903394929409673e-01, 9.907252968668226e-01, 9.911334564321237e-01, 9.915627747807666e-01, - 9.920120436855326e-01, 9.924800441092685e-01, 9.929655482846576e-01, 9.934673212537685e-01, 9.939841207305906e-01, - 9.945146969322154e-01, 9.950577931942117e-01, 9.956121471675398e-01, 9.961764915534302e-01, 9.967495543671935e-01, - 9.973300590248015e-01, 9.979167245036720e-01, 9.985082643417953e-01, 9.991033633647473e-01, 9.997003478609010e-01, - 1.000299741957418e+00, 1.000897441314013e+00, 1.001493964257960e+00, 1.002087624593489e+00, 1.002677088643863e+00, - 1.003261045483858e+00, 1.003838183774652e+00, 1.004407190937699e+00, 1.004966753528881e+00, 1.005515557572658e+00, - 1.006052289109999e+00, 1.006575635258931e+00, 1.007084285781611e+00, 1.007576934100958e+00, 1.008052277555815e+00, - 1.008509017718116e+00, 1.008945862447015e+00, 1.009361528531177e+00, 1.009754742820913e+00, 1.010124241309341e+00, - 1.010468769795370e+00, 1.010787087537248e+00, 1.011077969726137e+00, 1.011340205650538e+00, 1.011572597114216e+00, - 1.011773962181442e+00, 1.011943138906979e+00, 1.012078982659783e+00, 1.012180362866919e+00, 1.012246166897464e+00, - 1.012275305013586e+00, 1.012266707295288e+00, 1.012219319453278e+00, 1.012132107622966e+00, 1.012004064757857e+00, - 1.011834207632025e+00, 1.011621572933544e+00, 1.011365223023975e+00, 1.011064253702468e+00, 1.010717792733157e+00, - 1.010324996851905e+00, 1.009885057526159e+00, 1.009397209381147e+00, 1.008860731864438e+00, 1.008274947065247e+00, - 1.007639223374887e+00, 1.006952983357691e+00, 1.006215708265639e+00, 1.005426938305289e+00, 1.004586273379809e+00, - 1.003693377657581e+00, 1.002747984657666e+00, 1.001749900308864e+00, 1.000699003803502e+00, 9.995952485989262e-01, - 9.984386632116344e-01, 9.972293415774932e-01, 9.959672769174924e-01, 9.946500332901397e-01, 9.932403996813470e-01, - 9.912511516117244e-01, 9.895756853352172e-01, 9.877713214760662e-01, 9.858577479051078e-01, 9.838303127859196e-01, - 9.816822625580078e-01, 9.794074486605805e-01, 9.769999155793757e-01, 9.744528356359687e-01, 9.717597500340699e-01, - 9.689141159310996e-01, 9.659101618500662e-01, 9.627421831412876e-01, 9.594038121639412e-01, 9.558889978382734e-01, - 9.521922434090249e-01, 9.483086322505029e-01, 9.442332539187503e-01, 9.399607238929982e-01, 9.354860218216989e-01, - 9.308052967663477e-01, 9.259146970284931e-01, 9.208101305030523e-01, 9.154873597416558e-01, 9.099426066529104e-01, - 9.041732260327581e-01, 8.981763729936715e-01, 8.919490241013392e-01, 8.854882249661838e-01, 8.787919436722827e-01, - 8.718585835568161e-01, 8.646864947605047e-01, 8.572738135700366e-01, 8.496195859658071e-01, 8.417237467711145e-01, - 8.335862715770727e-01, 8.252074428838668e-01, 8.165875713256009e-01, 8.077280370477699e-01, 7.986311592191131e-01, - 7.892986353718001e-01, 7.797330954210866e-01, 7.699379531983687e-01, 7.599171886893816e-01, 7.496758423734833e-01, - 7.392176841476761e-01, 7.285474515411827e-01, 7.176714478163359e-01, 7.065962311464494e-01, 6.953282935906302e-01, - 6.838739059112046e-01, 6.722395305539791e-01, 6.604334017809461e-01, 6.484643596235256e-01, 6.363395004626368e-01, - 6.240661431421666e-01, 6.116530334821534e-01, 5.991098644638286e-01, 5.864461424698465e-01, 5.736694851703749e-01, - 5.607881029948401e-01, 5.478160663871271e-01, 5.347619788897301e-01, 5.216365147692703e-01, 5.084499758302256e-01, - 4.952135086430446e-01, 4.819387562519412e-01, 4.686361426419003e-01, 4.553170769563941e-01, 4.419939954454178e-01, - 4.286789889246267e-01, 4.153837786572842e-01, 4.021211063103491e-01, 3.889032719013054e-01, 3.757425439137077e-01, - 3.626515183776310e-01, 3.496431418636322e-01, 3.367290822653354e-01, 3.239228075238623e-01, 3.112360816586549e-01, - 2.986807941537710e-01, 2.862694673284843e-01, 2.740128472224539e-01, 2.619228330079575e-01, 2.500098438708934e-01, - 2.382847225401669e-01, 2.267578490199104e-01, 2.154390996938547e-01, 2.043379825955254e-01, 1.934636765792024e-01, - 1.828250319214460e-01, 1.724305860483634e-01, 1.622886348529314e-01, 1.524071880359812e-01, 1.427939789949266e-01, - 1.334565845242183e-01, 1.244023922999665e-01, 1.156385879569742e-01, 1.071721547807196e-01, 9.900985872728905e-02, - 9.115821766572002e-02, 8.362344855837105e-02, 7.641140367416376e-02, 6.952749039054598e-02, 6.297656454790079e-02, - 5.676284244020858e-02, 5.088975408628229e-02, 4.535983304624439e-02, 4.017457306236873e-02, 3.533430192568957e-02, - 3.083806062123772e-02, 2.668355420358626e-02, 2.286680405144430e-02, 1.938236337675363e-02, 1.622312720409645e-02, - 1.338005016725895e-02, 1.084218595595746e-02, 8.596753980908744e-03, 6.640506529168652e-03, 5.172703110468352e-03, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - - -const LC3_FLOAT MDCT_HRA_WINDOW_480_2_5ms[240] = { - 1.928875250471185e-07, 1.268623078914631e-06, 3.736943081685792e-06, 8.649386473419844e-06, 1.752499879209154e-05, - 3.251004192297566e-05, 5.654995150945631e-05, 9.358653414327445e-05, 1.487809853781833e-04, 2.287619057346095e-04, - 3.418963835622074e-04, 4.985810015573861e-04, 7.115482671394238e-04, 9.961824750040105e-04, 1.370837415765066e-03, - 1.857146703383843e-03, 2.480315886706181e-03, 3.269384042869696e-03, 4.257441351253188e-03, 5.481788360538607e-03, - 6.984022437256788e-03, 8.810037359146468e-03, 1.100992329671028e-02, 1.363775656493463e-02, 1.675127150559057e-02, - 2.041141057401967e-02, 2.468175295733717e-02, 2.962782656580052e-02, 3.531631267855188e-02, 4.181415652877682e-02, - 4.918760034374654e-02, 5.750115754515065e-02, 6.681654781077175e-02, 7.719161248813326e-02, 8.867922857347045e-02, - 1.013262374019720e-01, 1.151724017179353e-01, 1.302494023407827e-01, 1.465798836473051e-01, 1.641765559275968e-01, - 1.830413626142431e-01, 2.031647215674081e-01, 2.245248520040451e-01, 2.470872021104946e-01, 2.708039965464759e-01, - 2.956139274737775e-01, 3.214420168557505e-01, 3.481996809305596e-01, 3.757850292873181e-01, 4.040834302177654e-01, - 4.329683704138883e-01, 4.623026302356333e-01, 4.919397855296871e-01, 5.217260335074649e-01, 5.515023240298861e-01, - 5.811067597335228e-01, 6.103772100633116e-01, 6.391540670154212e-01, 6.672830559207561e-01, 6.946180045149623e-01, - 7.210234691482331e-01, 7.463771190956836e-01, 7.705717887049389e-01, 7.935171220325148e-01, 8.151407544921331e-01, - 8.353889991744725e-01, 8.542270299166949e-01, 8.716385768842180e-01, 8.876251715716619e-01, 9.022049953400274e-01, - 9.154113980197115e-01, 9.272911604251438e-01, 9.379025770646191e-01, 9.473134335138002e-01, 9.555989477431630e-01, - 9.628397371519567e-01, 9.691198641470655e-01, 9.745250036731624e-01, 9.791407668194774e-01, 9.830512059497915e-01, - 9.863375189657285e-01, 9.890769633791019e-01, 9.913419847656554e-01, 9.931995587544050e-01, 9.947107408108303e-01, - 9.959304135675596e-01, 9.969072172806543e-01, 9.976836451676292e-01, 9.982962820245519e-01, 9.987761617973335e-01, - 9.991492178976376e-01, 9.994367991905715e-01, 9.996562248627440e-01, 9.998213528339476e-01, 9.999431389208511e-01, - 1.000030167405588e+00, 1.000089137729581e+00, 1.000125296398298e+00, 1.000142807515464e+00, 1.000145059370791e+00, - 1.000134907956303e+00, 1.000114861040898e+00, 1.000087208438067e+00, 1.000054105383460e+00, 1.000017616583971e+00, - 9.999797286315710e-01, 9.999423382309206e-01, 9.999072232012880e-01, 9.998760025910959e-01, 9.998500915686289e-01, - 9.998306560737898e-01, 9.998185715517388e-01, 9.998143894342878e-01, 9.998183143680869e-01, 9.998301944838478e-01, - 9.998495262367371e-01, 9.998754745167079e-01, 9.999069078401956e-01, 9.999424475239904e-01, 9.999805288598742e-01, - 1.000019471519221e+00, 1.000057555786879e+00, 1.000093100812805e+00, 1.000124540917058e+00, 1.000150496102128e+00, - 1.000169833298924e+00, 1.000181715452526e+00, 1.000185636273393e+00, 1.000181439257840e+00, 1.000169320335504e+00, - 1.000149814156658e+00, 1.000123764529774e+00, 1.000092279821119e+00, 1.000056674215966e+00, 1.000018395617911e+00, - 9.999789406480724e-01, 9.999397567326687e-01, 9.999021306794866e-01, 9.998670624939285e-01, 9.998351225350340e-01, - 9.998062895304436e-01, 9.997797665333356e-01, 9.997537716957203e-01, 9.997253008334399e-01, 9.996898592447866e-01, - 9.996411611766667e-01, 9.995707967428177e-01, 9.994678679836200e-01, 9.993185980679096e-01, 9.991059202780914e-01, - 9.988090562524252e-01, 9.984030958127336e-01, 9.978585933978946e-01, 9.971411984750603e-01, 9.962113391583908e-01, - 9.950239795154223e-01, 9.935284716160412e-01, 9.916685232530794e-01, 9.893823014422549e-01, 9.866026903106617e-01, - 9.832577198181265e-01, 9.792711789106039e-01, 9.745634231307387e-01, 9.690523823244767e-01, 9.626547687789766e-01, - 9.552874798038419e-01, 9.468691813614447e-01, 9.373220508813107e-01, 9.265736480032657e-01, 9.145588719963409e-01, - 9.012219545005915e-01, 8.865184267401519e-01, 8.704169923325978e-01, 8.529012312555665e-01, 8.339710584198038e-01, - 8.136438625110305e-01, 7.919552579077074e-01, 7.689593947581650e-01, 7.447287893964823e-01, 7.193536583208960e-01, - 6.929407625549489e-01, 6.656117935585394e-01, 6.375013549431151e-01, 6.087546140984144e-01, 5.795247127727363e-01, - 5.499700344866872e-01, 5.202514288725478e-01, 4.905294887819369e-01, 4.609619660928919e-01, 4.317013978660552e-01, - 4.028929974356116e-01, 3.746728468420245e-01, 3.471664092737412e-01, 3.204873641715565e-01, 2.947367542923338e-01, - 2.700024238683050e-01, 2.463587202023185e-01, 2.238664274584689e-01, 2.025729006480214e-01, 1.825123693148748e-01, - 1.637063835467572e-01, 1.461643790086412e-01, 1.298843420747792e-01, 1.148535602600838e-01, 1.010494465619472e-01, - 8.844042869400506e-02, 7.698689534753124e-02, 6.664219153548699e-02, 5.735365389394342e-02, 4.906367480666277e-02, - 4.171078175510523e-02, 3.523071580898128e-02, 2.955749109487545e-02, 2.462441579169607e-02, 2.036505497804320e-02, - 1.671411663728698e-02, 1.360824429995981e-02, 1.098670301702559e-02, 8.791949345648940e-03, 6.970080454492374e-03, - 5.471161958930394e-03, 4.249438341364304e-03, 3.263433520599239e-03, 2.475952111493295e-03, 1.853994056678125e-03, - 1.368596596909542e-03, 9.946180283333026e-04, 7.104774789034889e-04, 4.978641589703932e-04, 3.414283510010364e-04, - 2.284649445606105e-04, 1.485987233730432e-04, 9.347897725317759e-05, 5.648942347847280e-05, 3.247793542861785e-05, - 1.750922386335714e-05, 8.642407336226362e-06, 3.734302301245202e-06, 1.267861256795911e-06, 1.927766981311251e-07}; - -const LC3_FLOAT MDCT_HRA_WINDOW_960_2_5ms[480] = { - 1.363353492760669e-07, 4.577676005269251e-07, 9.975675168391671e-07, 1.840776229085288e-06, 3.092248230077047e-06, - 4.880943708557620e-06, 7.363817805099883e-06, 1.073000750387602e-05, 1.520538607055496e-05, 2.105750528134522e-05, - 2.860093592119667e-05, 3.820301288710557e-05, 5.028998805188179e-05, 6.535359090391442e-05, 8.395799364585048e-05, - 1.067471738361778e-04, 1.344526637637966e-04, 1.679016715435404e-04, 2.080255544044134e-04, 2.558686198117505e-04, - 3.125972249248099e-04, 3.795091394541575e-04, 4.580431312676675e-04, 5.497887281277575e-04, 6.564961027629782e-04, - 7.800860221325537e-04, 9.226597952927381e-04, 1.086509147791288e-03, 1.274125944085974e-03, 1.488211673202887e-03, - 1.731686606830910e-03, 2.007698533412427e-03, 2.319630966669840e-03, 2.671110722544265e-03, 3.066014754864068e-03, - 3.508476137357141e-03, 4.002889078021606e-03, 4.553912851519276e-03, 5.166474536289647e-03, 5.845770445618693e-03, - 6.597266146035767e-03, 7.426694962226363e-03, 8.340054875180547e-03, 9.343603729551937e-03, 1.044385267714563e-02, - 1.164755779600632e-02, 1.296170983861615e-02, 1.439352207806304e-02, 1.595041623748902e-02, 1.764000650541313e-02, - 1.947008165734806e-02, 2.144858532216432e-02, 2.358359444954804e-02, 2.588329605228426e-02, 2.835596231360897e-02, - 3.100992416515645e-02, 3.385354345474830e-02, 3.689518383513415e-02, 4.014318051454780e-02, 4.360580901740066e-02, - 4.729125310846769e-02, 5.120757203648361e-02, 5.536266725318061e-02, 5.976424876157179e-02, 6.441980124289254e-02, - 6.933655010531084e-02, 7.452142758961615e-02, 7.998103905796611e-02, 8.572162958181787e-02, 9.174905093483054e-02, - 9.806872908624656e-02, 1.046856322804917e-01, 1.116042397799019e-01, 1.188285113399959e-01, 1.263618574809210e-01, - 1.342071106149135e-01, 1.423664970880752e-01, 1.508416101956496e-01, 1.596333842333865e-01, 1.687420696535257e-01, - 1.781672094023636e-01, 1.879076165271377e-01, 1.979613531528743e-01, 2.083257109445936e-01, 2.189971931864894e-01, - 2.299714986269890e-01, 2.412435072564368e-01, 2.528072682020181e-01, 2.646559899418406e-01, 2.767820330562002e-01, - 2.891769057483280e-01, 3.018312623786579e-01, 3.147349052652145e-01, 3.278767900074122e-01, 3.412450345907444e-01, - 3.548269325249284e-01, 3.686089702575019e-01, 3.825768490881926e-01, 3.967155117862224e-01, 4.110091740828488e-01, - 4.254413611747417e-01, 4.399949493303511e-01, 4.546522126414323e-01, 4.693948749058132e-01, 4.842041665659120e-01, - 4.990608865612834e-01, 5.139454688835927e-01, 5.288380535501122e-01, 5.437185616384643e-01, 5.585667739524391e-01, - 5.733624128178846e-01, 5.880852264406471e-01, 6.027150751969793e-01, 6.172320191724501e-01, 6.316164062197546e-01, - 6.458489597703579e-01, 6.599108656108541e-01, 6.737838568232726e-01, 6.874502960899853e-01, 7.008932545787268e-01, - 7.140965866515435e-01, 7.270449996828834e-01, 7.397241183258171e-01, 7.521205426304834e-01, 7.642218994939656e-01, - 7.760168870042503e-01, 7.874953113309442e-01, 7.986481159099932e-01, 8.094674027667472e-01, 8.199464459192338e-01, - 8.300796968994718e-01, 8.398627825231116e-01, 8.492924951249206e-01, 8.583667755581161e-01, 8.670846893280041e-01, - 8.754463962937875e-01, 8.834531144261093e-01, 8.911070781514043e-01, 8.984114918473676e-01, 9.053704790768982e-01, - 9.119890281611266e-01, 9.182729346961321e-01, 9.242287416134559e-01, 9.298636773723805e-01, 9.351855928531210e-01, - 9.402028974955879e-01, 9.449244951992589e-01, 9.493597204669394e-01, 9.535182752397909e-01, 9.574101668338553e-01, - 9.610456473502188e-01, 9.644351548926832e-01, 9.675892568889318e-01, 9.705185957742447e-01, 9.732338372611643e-01, - 9.757456213845153e-01, 9.780645164789403e-01, 9.802009762158145e-01, 9.821652997980082e-01, 9.839675953844861e-01, - 9.856177467920233e-01, 9.871253834983186e-01, 9.884998539492639e-01, 9.897502021530162e-01, 9.908851475245483e-01, - 9.919130679264989e-01, 9.928419858351684e-01, 9.936795575444219e-01, 9.944330653049196e-01, 9.951094122815642e-01, - 9.957151201982998e-01, 9.962563295265126e-01, 9.967388020613602e-01, 9.971679257195168e-01, 9.975487213822326e-01, - 9.978858515994010e-01, 9.981836309637017e-01, 9.984460379589807e-01, 9.986767280839717e-01, 9.988790480513948e-01, - 9.990560508634377e-01, 9.992105115676724e-01, 9.993449435025852e-01, 9.994616148490124e-01, 9.995625653127808e-01, - 9.996496227746003e-01, 9.997244197555017e-01, 9.997884095596641e-01, 9.998428819710351e-01, 9.998889783954170e-01, - 9.999277063554146e-01, 9.999599532614691e-01, 9.999864993978808e-01, 1.000008030077971e+00, 1.000025146937107e+00, - 1.000038378346013e+00, 1.000048188939381e+00, 1.000054988266291e+00, 1.000059138579006e+00, 1.000060961785582e+00, - 1.000060745599070e+00, 1.000058748922255e+00, 1.000055206511563e+00, 1.000050332967367e+00, 1.000044326100310e+00, - 1.000037369724671e+00, 1.000029635930232e+00, 1.000021286883873e+00, 1.000012476211096e+00, 1.000003350006250e+00, - 9.999940475182815e-01, 9.999847015566445e-01, 9.999754386595657e-01, 9.999663790642979e-01, 9.999576365163719e-01, - 9.999493179522237e-01, 9.999415230869807e-01, 9.999343439366570e-01, 9.999278643015735e-01, 9.999221592354568e-01, - 9.999172945224162e-01, 9.999133261818468e-01, 9.999103000191805e-01, 9.999082512384065e-01, 9.999072041302636e-01, - 9.999071718480597e-01, 9.999081562811047e-01, 9.999101480338050e-01, 9.999131265164656e-01, 9.999170601519115e-01, - 9.999219066999991e-01, 9.999276137001288e-01, 9.999341190298563e-01, 9.999413515757679e-01, 9.999492320108540e-01, - 9.999576736708096e-01, 9.999665835199758e-01, 9.999758631960602e-01, 9.999854101213793e-01, 9.999951186671812e-01, - 1.000004881356628e+00, 1.000014590091279e+00, 1.000024137385544e+00, 1.000033417593335e+00, 1.000042328111225e+00, - 1.000050770542848e+00, 1.000058651809861e+00, 1.000065885195634e+00, 1.000072391308898e+00, 1.000078098955774e+00, - 1.000082945909961e+00, 1.000086879572280e+00, 1.000089857512229e+00, 1.000091847885646e+00, 1.000092829723974e+00, - 1.000092793091916e+00, 1.000091739111420e+00, 1.000089679850895e+00, 1.000086638079347e+00, 1.000082646885623e+00, - 1.000077749163242e+00, 1.000071996961268e+00, 1.000065450701385e+00, 1.000058178260741e+00, 1.000050253919262e+00, - 1.000041757168942e+00, 1.000032771381191e+00, 1.000023382326608e+00, 1.000013676539597e+00, 1.000003739518099e+00, - 9.999936537463840e-01, 9.999834965263427e-01, 9.999733376002018e-01, 9.999632365449369e-01, 9.999532399160947e-01, - 9.999433781162252e-01, 9.999336619607787e-01, 9.999240789122246e-01, 9.999145889513631e-01, 9.999051200534473e-01, - 9.998955632358651e-01, 9.998857671439174e-01, 9.998755321416521e-01, 9.998646038760159e-01, 9.998526662846789e-01, - 9.998393340210341e-01, 9.998241442739438e-01, 9.998065479650342e-01, 9.997859003125656e-01, 9.997614507583039e-01, - 9.997323322622099e-01, 9.996975499792088e-01, 9.996559693426429e-01, 9.996063035901801e-01, 9.995471007797664e-01, - 9.994767303555520e-01, 9.993933693363640e-01, 9.992949882120472e-01, 9.991793366456373e-01, 9.990439290916592e-01, - 9.988860304525888e-01, 9.987026419065322e-01, 9.984904870492169e-01, 9.982459985022988e-01, 9.979653051476074e-01, - 9.976442201531890e-01, 9.972782299617136e-01, 9.968624844150069e-01, 9.963917881900651e-01, 9.958605937219481e-01, - 9.952629957874448e-01, 9.945927279204203e-01, 9.938431608253206e-01, 9.930073029495663e-01, 9.920778033684794e-01, - 9.910469571281373e-01, 9.899067131820748e-01, 9.886486850471784e-01, 9.872641642923781e-01, 9.857441369608847e-01, - 9.840793030126235e-01, 9.822600988582102e-01, 9.802767230390885e-01, 9.781191650903150e-01, 9.757772376026793e-01, - 9.732406114793927e-01, 9.704988543592059e-01, 9.675414721525257e-01, 9.643579536097365e-01, 9.609378178114939e-01, - 9.572706644392005e-01, 9.533462266503443e-01, 9.491544263479285e-01, 9.446854315961644e-01, 9.399297158962095e-01, - 9.348781189964488e-01, 9.295219088721776e-01, 9.238528444701966e-01, 9.178632387754598e-01, 9.115460217204322e-01, - 9.048948024240450e-01, 8.979039302171362e-01, 8.905685538859580e-01, 8.828846785458305e-01, 8.748492195442639e-01, - 8.664600527878369e-01, 8.577160608906681e-01, 8.486171745551603e-01, 8.391644086184020e-01, 8.293598922305367e-01, - 8.192068926746530e-01, 8.087098323911928e-01, 7.978742988330544e-01, 7.867070468498287e-01, 7.752159933798504e-01, - 7.634102043158196e-01, 7.512998735020282e-01, 7.388962939169839e-01, 7.262118211926384e-01, 7.132598297183557e-01, - 7.000546616722335e-01, 6.866115694122957e-01, 6.729466517435032e-01, 6.590767846515775e-01, 6.450195471597746e-01, - 6.307931430185830e-01, 6.164163189797930e-01, 6.019082804348481e-01, 5.872886052124403e-01, 5.725771563319307e-01, - 5.577939944978301e-01, 5.429592910967905e-01, 5.280932424234555e-01, 5.132159858162120e-01, 4.983475183298941e-01, - 4.835076185113182e-01, 4.687157717768828e-01, 4.539910998210603e-01, 4.393522944120604e-01, 4.248175558579833e-01, - 4.104045363548025e-01, 3.961302883579846e-01, 3.820112180536255e-01, 3.680630439436816e-01, 3.543007605040334e-01, - 3.407386068243548e-01, 3.273900400954695e-01, 3.142677137733552e-01, 3.013834602191723e-01, 2.887482775916394e-01, - 2.763723207514489e-01, 2.642648959268686e-01, 2.524344588847748e-01, 2.408886163515173e-01, 2.296341304326797e-01, - 2.186769257893048e-01, 2.080220993398264e-01, 1.976739322711464e-01, 1.876359041583237e-01, 1.779107090095517e-01, - 1.685002730708834e-01, 1.594057742429125e-01, 1.506276629788181e-01, 1.421656845493104e-01, 1.340189025746913e-01, - 1.261857237370651e-01, 1.186639235964411e-01, 1.114506734428340e-01, 1.045425681223503e-01, 9.793565477860058e-02, - 9.162546245161339e-02, 8.560703247484407e-02, 7.987494960705163e-02, 7.442337382999228e-02, 6.924607273536325e-02, - 6.433645441557491e-02, 5.968760076313909e-02, 5.529230107316437e-02, 5.114308583308901e-02, 4.723226057381158e-02, - 4.355193964722984e-02, 4.009407978727676e-02, 3.685051330522059e-02, 3.381298076557955e-02, 3.097316298675063e-02, - 2.832271221053797e-02, 2.585328228730008e-02, 2.355655772843824e-02, 2.142428148537503e-02, 1.944828132389286e-02, - 1.762049467453352e-02, 1.593299185344667e-02, 1.437799756332653e-02, 1.294791060055676e-02, 1.163532171204003e-02, - 1.043302956305446e-02, 9.334054795489547e-03, 8.331652173617308e-03, 7.419320831822072e-03, 6.590812655146027e-03, - 5.840138838848342e-03, 5.161574687206487e-03, 4.549662724337389e-03, 3.999214200759286e-03, 3.505309088672846e-03, - 3.063294666478038e-03, 2.668782798866110e-03, 2.317646022975776e-03, 2.006012553652158e-03, 1.730260321894845e-03, - 1.487010160247016e-03, 1.273118247295162e-03, 1.085667920762688e-03, 9.219609650399310e-04, 7.795084745479000e-04, - 6.560213892304477e-04, 5.494007928508220e-04, 4.577280587661532e-04, 3.792549215895880e-04, 3.123935467349105e-04, - 2.557066633705375e-04, 2.078978198736850e-04, 1.678018145436083e-04, 1.343753481649133e-04, 1.066879390562912e-04, - 8.391313553401788e-05, 6.532005529093359e-05, 5.026527605947520e-05, 3.818509710338716e-05, 2.858818657228189e-05, - 2.104862555598476e-05, 1.519935578579325e-05, 1.072603433419925e-05, 7.361295334616452e-06, 4.879415604699819e-06, - 3.091377877253446e-06, 1.840321200267112e-06, 9.973582966273186e-07, 4.576899867970956e-07, 1.363156993327630e-07}; - -const LC3_FLOAT MDCT_HRA_WINDOW_480_5ms[480] = { - 9.752475122178133e-08, 6.413568706385488e-07, 1.888722582859778e-06, 4.370037451432268e-06, 8.850535239285388e-06, - 1.640976145163547e-05, 2.852654713353143e-05, 4.717577700625728e-05, 7.493695610161539e-05, 1.151138634046934e-04, - 1.718640547726665e-04, 2.503364524287818e-04, 3.568147253529307e-04, 4.988636346654247e-04, 6.854750052598100e-04, - 9.272095051506971e-04, 1.236329983123574e-03, 1.626921748932395e-03, 2.114994893578391e-03, 2.718563554424897e-03, - 3.457696944351759e-03, 4.354536997897421e-03, 5.433277651003014e-03, 6.720101073517573e-03, 8.243066622086374e-03, - 1.003194888027514e-02, 1.211802190514137e-02, 1.453378770448280e-02, 1.731264802301458e-02, 2.048851971150478e-02, - 2.409539527917081e-02, 2.816685167069475e-02, 3.273551184443837e-02, 3.783246533188810e-02, 4.348665559839211e-02, - 4.972424366422929e-02, 5.656795903921283e-02, 6.403645052356303e-02, 7.214365077720192e-02, 8.089816969852329e-02, - 9.030273251800713e-02, 1.003536790358444e-01, 1.110405405506510e-01, 1.223457106767086e-01, 1.342442253757111e-01, - 1.467036660932157e-01, 1.596841978637899e-01, 1.731387516273307e-01, 1.870133568030685e-01, 2.012476264477750e-01, - 2.157753931632489e-01, 2.305254894308376e-01, 2.454226613848142e-01, 2.603886003668338e-01, 2.753430721265570e-01, - 2.902051194568206e-01, 3.048943105839568e-01, 3.193320029709852e-01, 3.334425905036104e-01, 3.471547014476447e-01, - 3.604024000326147e-01, 3.731263195417857e-01, 3.852742256277580e-01, 3.968020335005454e-01, 4.076742901287472e-01, - 4.178645650568324e-01, 4.273556452755667e-01, 4.361395400809099e-01, 4.442173028452789e-01, 4.515986821559811e-01, - 4.583016198658067e-01, 4.643516178635941e-01, 4.697809986240601e-01, 4.746280867221525e-01, 4.789363394414859e-01, - 4.827534543679447e-01, 4.861304804889396e-01, 4.891209569144257e-01, 4.917801000389275e-01, 4.941640559535466e-01, - 4.963292304037445e-01, 4.983317038070890e-01, 5.002267340435251e-01, 5.020683451596181e-01, 5.039089960260009e-01, - 5.057993195650324e-01, 5.077879205925190e-01, 5.099212187075181e-01, 5.122433220684072e-01, 5.147959182947806e-01, - 5.176181700509677e-01, 5.207466049576202e-01, 5.242149921562288e-01, 5.280542009005510e-01, 5.322920397381714e-01, - 5.369530779485470e-01, 5.420584537149585e-01, 5.476256758552612e-01, 5.536684276931489e-01, 5.601963827419005e-01, - 5.672150422730262e-01, 5.747256045798048e-01, 5.827248748908062e-01, 5.912052235447917e-01, 6.001545983308831e-01, - 6.095565949599409e-01, 6.193905875944715e-01, 6.296319193412947e-01, 6.402521506992933e-01, 6.512193622254838e-01, - 6.624985061836945e-01, 6.740518006968909e-01, 6.858391589448801e-01, 6.978186452298805e-01, 7.099469492625143e-01, - 7.221798697869513e-01, 7.344727986533678e-01, 7.467811966479000e-01, 7.590610527959840e-01, 7.712693194564819e-01, - 7.833643163120154e-01, 7.953060973228134e-01, 8.070567758283893e-01, 8.185808042273020e-01, 8.298452060049231e-01, - 8.408197592685507e-01, 8.514771323358515e-01, 8.617929732481214e-01, 8.717459562819760e-01, 8.813177895502246e-01, - 8.904931885580764e-01, 8.992598210679454e-01, 9.076082287937692e-01, 9.155317312832600e-01, 9.230263168675006e-01, - 9.300905248019673e-01, 9.367253217576155e-01, 9.429339747337118e-01, 9.487219213595656e-01, 9.540966375393273e-01, - 9.590675015747306e-01, 9.636456533576906e-01, 9.678438470101040e-01, 9.716762954761368e-01, 9.751585060165801e-01, - 9.783071062524560e-01, 9.811396612648455e-01, 9.836744831733611e-01, 9.859304354792453e-01, 9.879267351759304e-01, - 9.896827561287711e-01, 9.912178374656364e-01, 9.925511006920656e-01, 9.937012789694025e-01, 9.946865615154821e-01, - 9.955244554643670e-01, 9.962316668199601e-01, 9.968240014222112e-01, 9.973162861697706e-01, 9.977223101520583e-01, - 9.980547848638137e-01, 9.983253223174189e-01, 9.985444296291865e-01, 9.987215185204544e-01, 9.988649281201196e-01, - 9.989819594562657e-01, 9.990789200557365e-01, 9.991611771110095e-01, 9.992332177094652e-01, 9.992987146446982e-01, - 9.993605963440879e-01, 9.994211194587087e-01, 9.994819426820254e-01, 9.995442004050701e-01, 9.996085748889234e-01, - 9.996753657478641e-01, 9.997445556919270e-01, 9.998158716802928e-01, 9.998888409489480e-01, 9.999628437059447e-01, - 1.000037122530308e+00, 1.000110932111342e+00, 1.000183434550577e+00, 1.000253775458271e+00, 1.000321131235573e+00, - 1.000384720523657e+00, 1.000443814718821e+00, 1.000497747347372e+00, 1.000545922137548e+00, 1.000587819673348e+00, - 1.000623002564305e+00, 1.000651119113520e+00, 1.000671905511154e+00, 1.000685186620367e+00, 1.000690875455855e+00, - 1.000688971480779e+00, 1.000679557865722e+00, 1.000662797863287e+00, 1.000638930454792e+00, 1.000608265421794e+00, - 1.000571177986086e+00, 1.000528103148456e+00, 1.000479529839953e+00, 1.000425994980975e+00, 1.000368077524065e+00, - 1.000306392536921e+00, 1.000241585363485e+00, 1.000174325883803e+00, 1.000105302878071e+00, 1.000035218487335e+00, - 9.999647827529677e-01, 9.998947082094627e-01, 9.998257045004189e-01, 9.997584729859116e-01, 9.996937013107159e-01, - 9.996320579071534e-01, 9.995741864134795e-01, 9.995206999987033e-01, 9.994721755972762e-01, 9.994291480719714e-01, - 9.993921043401182e-01, 9.993614775166697e-01, 9.993376411467469e-01, 9.993209036195655e-01, 9.993115028741053e-01, - 9.993096015235072e-01, 9.993152825388751e-01, 9.993285456427281e-01, 9.993493045667127e-01, 9.993773853262324e-01, - 9.994125256556279e-01, 9.994543757308175e-01, 9.995025002817920e-01, 9.995563821653024e-01, 9.996154274293025e-01, - 9.996789718565903e-01, 9.997462889273712e-01, 9.998165990914856e-01, 9.998890801932255e-01, 9.999628788477228e-01, - 1.000037122530308e+00, 1.000110932111343e+00, 1.000183434550578e+00, 1.000253775458273e+00, 1.000321131235574e+00, - 1.000384720523658e+00, 1.000443814718822e+00, 1.000497747347373e+00, 1.000545922137550e+00, 1.000587819673349e+00, - 1.000623002564306e+00, 1.000651119113521e+00, 1.000671905511155e+00, 1.000685186620368e+00, 1.000690875455855e+00, - 1.000688971480779e+00, 1.000679557865721e+00, 1.000662797863286e+00, 1.000638930454791e+00, 1.000608265421792e+00, - 1.000571177986083e+00, 1.000528103148453e+00, 1.000479529839950e+00, 1.000425994980971e+00, 1.000368077524061e+00, - 1.000306392536917e+00, 1.000241585363480e+00, 1.000174325883798e+00, 1.000105302878066e+00, 1.000035218487330e+00, - 9.999647827529627e-01, 9.998947082094576e-01, 9.998257045004140e-01, 9.997584729859067e-01, 9.996937013107114e-01, - 9.996320579071492e-01, 9.995741864134757e-01, 9.995206999987001e-01, 9.994721755972732e-01, 9.994291480719688e-01, - 9.993921043401160e-01, 9.993614775166682e-01, 9.993376411467459e-01, 9.993209036195649e-01, 9.993115028741050e-01, - 9.993096015235075e-01, 9.993152825388757e-01, 9.993285456427290e-01, 9.993493045667138e-01, 9.993773853262338e-01, - 9.994125256556294e-01, 9.994543757308189e-01, 9.995025002817937e-01, 9.995563821653038e-01, 9.996154274293039e-01, - 9.996789718565914e-01, 9.997462889273723e-01, 9.998165990914865e-01, 9.998890801932260e-01, 9.999628788477231e-01, - 1.000037087385911e+00, 1.000110692813570e+00, 1.000182706868929e+00, 1.000252041323928e+00, 1.000317522732163e+00, - 1.000377862440740e+00, 1.000431621330905e+00, 1.000477167056245e+00, 1.000512623941274e+00, 1.000535816073234e+00, - 1.000544204364164e+00, 1.000534818530052e+00, 1.000504185023504e+00, 1.000448251960702e+00, 1.000362312003691e+00, - 1.000240924003935e+00, 1.000077833997232e+00, 9.998658958833085e-01, 9.995969918486358e-01, 9.992619523233789e-01, - 9.988504750288640e-01, 9.983510424973004e-01, 9.977508373579080e-01, 9.970356547108338e-01, 9.961898110802319e-01, - 9.951960497774461e-01, 9.940354430376489e-01, 9.926872920341389e-01, 9.911290268265915e-01, 9.893361094467528e-01, - 9.872819446267991e-01, 9.849378040627681e-01, 9.822727714796871e-01, 9.792537170020328e-01, 9.758453102910697e-01, - 9.720100824436398e-01, 9.677085466217928e-01, 9.628993866974633e-01, 9.575397217975740e-01, 9.515854525300023e-01, - 9.449916919338839e-01, 9.377132809663818e-01, 9.297053848015243e-01, 9.209241625967119e-01, 9.113274999097554e-01, - 9.008757898394824e-01, 8.895327463959180e-01, 8.772662317107712e-01, 8.640490775465693e-01, 8.498598811668777e-01, - 8.346837559540076e-01, 8.185130181287622e-01, 8.013477924378186e-01, 7.831965216140859e-01, 7.640763666675557e-01, - 7.440134875182273e-01, 7.230431960387166e-01, 7.012099761451619e-01, 6.785673680876833e-01, 6.551777164863924e-01, - 6.311117838899523e-01, 6.064482336696789e-01, 5.812729878873076e-01, 5.556784673902739e-01, 5.297627228142773e-01, - 5.036284664469868e-01, 4.773820160836825e-01, 4.511321631520609e-01, 4.249889785709717e-01, 3.990625711023555e-01, - 3.734618144045748e-01, 3.482930606136814e-01, 3.236588600361913e-01, 2.996567083459001e-01, 2.763778443910257e-01, - 2.539061231327225e-01, 2.323169891052670e-01, 2.116765758470110e-01, 1.920409557494601e-01, 1.734555625129627e-01, - 1.559548047768156e-01, 1.395618845278644e-01, 1.242888277448971e-01, 1.101367277067382e-01, 9.709619389909366e-02, - 8.514799199591219e-02, 7.426385348588532e-02, 6.440742764829473e-02, 5.553534414838273e-02, 4.759835178173250e-02, - 4.054249795560948e-02, 3.431031430250281e-02, 2.884197618951215e-02, 2.407640752522409e-02, 1.995230681955070e-02, - 1.640907554818694e-02, 1.338763515624311e-02, 1.083112419588716e-02, 8.685471885106049e-03, 6.899848624541457e-03, - 5.426997611391803e-03, 4.223454598964128e-03, 3.249665071710221e-03, 2.470009678121166e-03, 1.852749750240329e-03, - 1.369905213535462e-03, 9.970772330834560e-04, 7.132276282050243e-04, 5.004264891539459e-04, 3.435786103798425e-04, - 2.301383718361825e-04, 1.498216022111699e-04, 9.432178886435202e-05, 5.703679621983551e-05, 3.281105011319028e-05, - 1.769696765784037e-05, 8.738278469978569e-06, 3.776770390150926e-06, 1.282520060393973e-06, 1.950213832061108e-07, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_HRA_WINDOW_960_5ms[960] = { - 6.895487963711672e-08, 2.315162529310440e-07, 5.044776791712418e-07, 9.307951082662299e-07, 1.563406927329763e-06, - 2.467387587537570e-06, 3.721891688909285e-06, 5.422241751611354e-06, 7.682193559629735e-06, 1.063638764371401e-05, - 1.444299034054517e-05, 1.928652559405143e-05, 2.538089690430043e-05, 3.297259712577839e-05, 4.234410206521111e-05, - 5.381744200626993e-05, 6.775794339454556e-05, 8.457813095885401e-05, 1.047417785352287e-04, 1.287680948104183e-04, - 1.572360281259058e-04, 1.907886723956216e-04, 2.301377541053808e-04, 2.760681782947526e-04, 3.294426093879363e-04, - 3.912060607548454e-04, 4.623904649625926e-04, 5.441191948366056e-04, 6.376115037051945e-04, 7.441868515669874e-04, - 8.652690824124538e-04, 1.002390416563642e-03, 1.157195220684898e-03, 1.331443517075892e-03, 1.527014193000520e-03, - 1.745907870144461e-03, 1.990249393843025e-03, 2.262289901491620e-03, 2.564408429555132e-03, 2.899113018840483e-03, - 3.269041278198808e-03, 3.676960367589013e-03, 4.125766362471570e-03, 4.618482962817473e-03, 5.158259511618939e-03, - 5.748368289680850e-03, 6.392201055659471e-03, 7.093264802800713e-03, 7.855176706615627e-03, 8.681658240816716e-03, - 9.576528442223354e-03, 1.054369630902618e-02, 1.158715232077375e-02, 1.271095907270489e-02, 1.391924102158781e-02, - 1.521617334503430e-02, 1.660596992132020e-02, 1.809287044204954e-02, 1.968112667553175e-02, 2.137498790448110e-02, - 2.317868556757386e-02, 2.509641714048705e-02, 2.713232929826755e-02, 2.929050040721149e-02, 3.157492240084053e-02, - 3.398948210100576e-02, 3.653794205159846e-02, 3.922392093875195e-02, 4.205087367774323e-02, 4.502207125299418e-02, - 4.814058040358271e-02, 5.140924325245049e-02, 5.483065698298122e-02, 5.840715367176064e-02, 6.214078039106200e-02, - 6.603327969885861e-02, 7.008607063789310e-02, 7.430023036845897e-02, 7.867647656201358e-02, 8.321515068447660e-02, - 8.791620229900704e-02, 9.277917451814051e-02, 9.780319073433394e-02, 1.029869427561657e-01, 1.083286804746118e-01, - 1.138262031799212e-01, 1.194768526446087e-01, 1.252775080819347e-01, 1.312245830819321e-01, 1.373140246185531e-01, - 1.435413142118472e-01, 1.499014713182564e-01, 1.563890590101503e-01, 1.629981919926660e-01, 1.697225469918130e-01, - 1.765553755327395e-01, 1.834895191111025e-01, 1.905174267437600e-01, 1.976311748676255e-01, 2.048224895376239e-01, - 2.120827708564311e-01, 2.194031195502149e-01, 2.267743655861134e-01, 2.341870987088808e-01, 2.416317007561807e-01, - 2.490983795946414e-01, 2.565772045021951e-01, 2.640581428066213e-01, 2.715310975758094e-01, 2.789859461422405e-01, - 2.864125792327671e-01, 2.938009404650995e-01, 3.011410659646723e-01, 3.084231238498945e-01, 3.156374533302977e-01, - 3.227746031609007e-01, 3.298253691972654e-01, 3.367808307992519e-01, 3.436323858374391e-01, 3.503717840645000e-01, - 3.569912187918766e-01, 3.634832564154323e-01, 3.698408960767766e-01, 3.760576237679591e-01, 3.821274200069671e-01, - 3.880447807855012e-01, 3.938047354128900e-01, 3.994028614671444e-01, 4.048352968090768e-01, 4.100987486186185e-01, - 4.151904994338012e-01, 4.201084101968628e-01, 4.248509203362432e-01, 4.294170449371775e-01, 4.338063690767977e-01, - 4.380190394218450e-01, 4.420557532080190e-01, 4.459177447394188e-01, 4.496067695642793e-01, 4.531250864990879e-01, - 4.564754376870322e-01, 4.596610268884718e-01, 4.626854962106256e-01, 4.655529014908880e-01, 4.682676865530477e-01, - 4.708346565582213e-01, 4.732589506724937e-01, 4.755460142711474e-01, 4.777015708950234e-01, 4.797315941680489e-01, - 4.816422798764418e-01, 4.834400183996339e-01, 4.851313676707616e-01, 4.867230268307342e-01, 4.882218107246894e-01, - 4.896346253731921e-01, 4.909684445331096e-01, 4.922302874448856e-01, 4.934271978441982e-01, 4.945662242969564e-01, - 4.956544018975119e-01, 4.966987353511036e-01, 4.977061834431282e-01, 4.986836448801200e-01, 4.996379454705324e-01, - 5.005758265977741e-01, 5.015039349236500e-01, 5.024288132476197e-01, 5.033568924361829e-01, 5.042944843274677e-01, - 5.052477755087517e-01, 5.062228218592734e-01, 5.072255437473754e-01, 5.082617217696771e-01, 5.093369929206453e-01, - 5.104568470835084e-01, 5.116266237378464e-01, 5.128515087852868e-01, 5.141365314023457e-01, 5.154865608384481e-01, - 5.169063030872989e-01, 5.184002973708743e-01, 5.199729123871391e-01, 5.216283422849100e-01, 5.233706023418981e-01, - 5.252035243345977e-01, 5.271307516011422e-01, 5.291557338103311e-01, 5.312817214614957e-01, 5.335117601505942e-01, - 5.358486846476969e-01, 5.382951128397399e-01, 5.408534395999681e-01, 5.435258306517384e-01, 5.463142164993156e-01, - 5.492202865018518e-01, 5.522454831689516e-01, 5.553909967570894e-01, 5.586577602456578e-01, 5.620464447697334e-01, - 5.655574555837481e-01, 5.691909286262941e-01, 5.729467277513715e-01, 5.768244426856284e-01, 5.808233877646608e-01, - 5.849426014943921e-01, 5.891808469760642e-01, 5.935366132255452e-01, 5.980081174096790e-01, 6.025933080143371e-01, - 6.072898689508155e-01, 6.120952245993402e-01, 6.170065457808297e-01, 6.220207566407007e-01, 6.271345424215810e-01, - 6.323443580952387e-01, 6.376464378179791e-01, 6.430368051681870e-01, 6.485112841196261e-01, 6.540655106995645e-01, - 6.596949452767820e-01, 6.653948854210106e-01, 6.711604792723804e-01, 6.769867393569574e-01, 6.828685567824609e-01, - 6.888007157467320e-01, 6.947779082904570e-01, 7.007947492250285e-01, 7.068457911662456e-01, 7.129255396047764e-01, - 7.190284679449507e-01, 7.251490324444848e-01, 7.312816869891655e-01, 7.374208976383266e-01, 7.435611568791312e-01, - 7.496969975302182e-01, 7.558230062381704e-01, 7.619338365135002e-01, 7.680242212564293e-01, 7.740889847266266e-01, - 7.801230539152502e-01, 7.861214692821104e-01, 7.920793948254449e-01, 7.979921274567765e-01, 8.038551056583576e-01, - 8.096639174059964e-01, 8.154143073453887e-01, 8.211021832154612e-01, 8.267236215176270e-01, 8.322748724351863e-01, - 8.377523640123131e-01, 8.431527056071227e-01, 8.484726906381246e-01, 8.537092986478724e-01, 8.588596967118024e-01, - 8.639212402239919e-01, 8.688914730948750e-01, 8.737681273987250e-01, 8.785491225109360e-01, 8.832325637767802e-01, - 8.878167407543193e-01, 8.923001250745454e-01, 8.966813679615423e-01, 9.009592974545819e-01, 9.051329153725320e-01, - 9.092013940588521e-01, 9.131640729428008e-01, 9.170204549493250e-01, 9.207702027865553e-01, 9.244131351359152e-01, - 9.279492227657136e-01, 9.313785845847777e-01, 9.347014836483568e-01, 9.379183231242151e-01, 9.410296422227417e-01, - 9.440361120910473e-01, 9.469385316675432e-01, 9.497378234904927e-01, 9.524350294515523e-01, 9.550313064834267e-01, - 9.575279221695473e-01, 9.599262502631155e-01, 9.622277661029504e-01, 9.644340419143761e-01, 9.665467419847689e-01, - 9.685676177053684e-01, 9.704985024734301e-01, 9.723413064517235e-01, 9.740980111855780e-01, 9.757706640811671e-01, - 9.773613727522825e-01, 9.788722992464219e-01, 9.803056541645230e-01, 9.816636906919504e-01, 9.829486985613498e-01, - 9.841629979706453e-01, 9.853089334816367e-01, 9.863888679264271e-01, 9.874051763501168e-01, 9.883602400189044e-01, - 9.892564405229114e-01, 9.900961540026917e-01, 9.908817455275554e-01, 9.916155636525488e-01, 9.922999351792323e-01, - 9.929371601433686e-01, 9.935295070502858e-01, 9.940792083761523e-01, 9.945884563506685e-01, 9.950593990338927e-01, - 9.954941366970841e-01, 9.958947185146307e-01, 9.962631395714290e-01, 9.966013381874510e-01, 9.969111935588407e-01, - 9.971945237126117e-01, 9.974530837700109e-01, 9.976885645118487e-01, 9.979025912375212e-01, 9.980967229081705e-01, - 9.982724515633580e-01, 9.984312019997783e-01, 9.985743316998982e-01, 9.987031309979628e-01, 9.988188234704969e-01, - 9.989225665382725e-01, 9.990154522666818e-01, 9.990985083514453e-01, 9.991726992767055e-01, 9.992389276326772e-01, - 9.992980355801597e-01, 9.993508064493677e-01, 9.993979664606926e-01, 9.994401865550964e-01, 9.994780843219823e-01, - 9.995122260124369e-01, 9.995431286258258e-01, 9.995712620577665e-01, 9.995970512975859e-01, 9.996208786634017e-01, - 9.996430860630976e-01, 9.996639772695648e-01, 9.996838201987696e-01, 9.997028491794524e-01, 9.997212672035590e-01, - 9.997392481469061e-01, 9.997569389500512e-01, 9.997744617498990e-01, 9.997919159532207e-01, 9.998093802440068e-01, - 9.998269145173621e-01, 9.998445617335565e-01, 9.998623496867628e-01, 9.998802926840086e-01, 9.998983931308962e-01, - 9.999166430217568e-01, 9.999350253331990e-01, 9.999535153223720e-01, 9.999720817407219e-01, 9.999906880869937e-01, - 1.000009287384094e+00, 1.000027834887701e+00, 1.000046300263356e+00, 1.000064628855653e+00, 1.000082766500416e+00, - 1.000100659718907e+00, 1.000118255908114e+00, 1.000135503526064e+00, 1.000152352271145e+00, 1.000168753254485e+00, - 1.000184659164501e+00, 1.000200024422812e+00, 1.000214805330795e+00, 1.000228960206152e+00, 1.000242449508936e+00, - 1.000255235956603e+00, 1.000267284627736e+00, 1.000278563054190e+00, 1.000289041301502e+00, 1.000298692037510e+00, - 1.000307490589210e+00, 1.000315414987954e+00, 1.000322446003211e+00, 1.000328567165139e+00, 1.000333764776314e+00, - 1.000338027913029e+00, 1.000341348416600e+00, 1.000343720875191e+00, 1.000345142596687e+00, 1.000345613573201e+00, - 1.000345136437780e+00, 1.000343716413940e+00, 1.000341361258634e+00, 1.000338081199265e+00, 1.000333888865364e+00, - 1.000328799215526e+00, 1.000322829460192e+00, 1.000315998980821e+00, 1.000308329246033e+00, 1.000299843725172e+00, - 1.000290567799819e+00, 1.000280528673668e+00, 1.000269755281177e+00, 1.000258278195373e+00, 1.000246129535135e+00, - 1.000233342872247e+00, 1.000219953138478e+00, 1.000205996532915e+00, 1.000191510429709e+00, 1.000176533286394e+00, - 1.000161104552890e+00, 1.000145264581248e+00, 1.000129054536203e+00, 1.000112516306544e+00, 1.000095692417284e+00, - 1.000078625942615e+00, 1.000061360419570e+00, 1.000043939762341e+00, 1.000026408177143e+00, 1.000008810077537e+00, - 9.999911900000854e-01, 9.999735925202352e-01, 9.999560621682817e-01, 9.999386433453050e-01, 9.999213802389432e-01, - 9.999043167388835e-01, 9.998874963519558e-01, 9.998709621167259e-01, 9.998547565174905e-01, 9.998389213976104e-01, - 9.998234978721111e-01, 9.998085262395175e-01, 9.997940458929213e-01, 9.997800952302701e-01, 9.997667115639504e-01, - 9.997539310297094e-01, 9.997417884950316e-01, 9.997303174671138e-01, 9.997195500006013e-01, 9.997095166053042e-01, - 9.997002461541395e-01, 9.996917657915899e-01, 9.996841008429919e-01, 9.996772747250358e-01, 9.996713088578647e-01, - 9.996662225792015e-01, 9.996620330610038e-01, 9.996587552291110e-01, 9.996564016864400e-01, 9.996549826402822e-01, - 9.996545058342721e-01, 9.996549764856241e-01, 9.996563972282545e-01, 9.996587680623811e-01, 9.996620863112294e-01, - 9.996663465854424e-01, 9.996715407557830e-01, 9.996776579346981e-01, 9.996846844672899e-01, 9.996926039321870e-01, - 9.997013971527812e-01, 9.997110422192300e-01, 9.997215145215743e-01, 9.997327867942448e-01, 9.997448291721661e-01, - 9.997576092585791e-01, 9.997710922046226e-01, 9.997852408006243e-01, 9.998000155789548e-01, 9.998153749282088e-01, - 9.998312752183693e-01, 9.998476709365326e-01, 9.998645148326526e-01, 9.998817580746910e-01, 9.998993504124509e-01, - 9.999172403493095e-01, 9.999353753209654e-01, 9.999537018802583e-01, 9.999721658870582e-01, 9.999907127021609e-01, - 1.000009287384094e+00, 1.000027834887701e+00, 1.000046300263357e+00, 1.000064628855654e+00, 1.000082766500417e+00, - 1.000100659718908e+00, 1.000118255908115e+00, 1.000135503526065e+00, 1.000152352271146e+00, 1.000168753254487e+00, - 1.000184659164503e+00, 1.000200024422814e+00, 1.000214805330797e+00, 1.000228960206154e+00, 1.000242449508937e+00, - 1.000255235956604e+00, 1.000267284627737e+00, 1.000278563054191e+00, 1.000289041301503e+00, 1.000298692037512e+00, - 1.000307490589211e+00, 1.000315414987955e+00, 1.000322446003212e+00, 1.000328567165140e+00, 1.000333764776315e+00, - 1.000338027913030e+00, 1.000341348416601e+00, 1.000343720875191e+00, 1.000345142596688e+00, 1.000345613573201e+00, - 1.000345136437780e+00, 1.000343716413940e+00, 1.000341361258634e+00, 1.000338081199264e+00, 1.000333888865363e+00, - 1.000328799215525e+00, 1.000322829460191e+00, 1.000315998980820e+00, 1.000308329246031e+00, 1.000299843725170e+00, - 1.000290567799817e+00, 1.000280528673665e+00, 1.000269755281174e+00, 1.000258278195370e+00, 1.000246129535132e+00, - 1.000233342872243e+00, 1.000219953138474e+00, 1.000205996532911e+00, 1.000191510429705e+00, 1.000176533286390e+00, - 1.000161104552886e+00, 1.000145264581243e+00, 1.000129054536198e+00, 1.000112516306539e+00, 1.000095692417279e+00, - 1.000078625942610e+00, 1.000061360419565e+00, 1.000043939762336e+00, 1.000026408177138e+00, 1.000008810077532e+00, - 9.999911900000801e-01, 9.999735925202301e-01, 9.999560621682765e-01, 9.999386433453000e-01, 9.999213802389382e-01, - 9.999043167388785e-01, 9.998874963519510e-01, 9.998709621167211e-01, 9.998547565174859e-01, 9.998389213976059e-01, - 9.998234978721068e-01, 9.998085262395136e-01, 9.997940458929174e-01, 9.997800952302665e-01, 9.997667115639468e-01, - 9.997539310297062e-01, 9.997417884950285e-01, 9.997303174671109e-01, 9.997195500005988e-01, 9.997095166053018e-01, - 9.997002461541374e-01, 9.996917657915880e-01, 9.996841008429901e-01, 9.996772747250343e-01, 9.996713088578635e-01, - 9.996662225792006e-01, 9.996620330610030e-01, 9.996587552291103e-01, 9.996564016864398e-01, 9.996549826402821e-01, - 9.996545058342721e-01, 9.996549764856244e-01, 9.996563972282549e-01, 9.996587680623816e-01, 9.996620863112300e-01, - 9.996663465854433e-01, 9.996715407557840e-01, 9.996776579346992e-01, 9.996846844672912e-01, 9.996926039321883e-01, - 9.997013971527825e-01, 9.997110422192316e-01, 9.997215145215756e-01, 9.997327867942462e-01, 9.997448291721677e-01, - 9.997576092585806e-01, 9.997710922046239e-01, 9.997852408006256e-01, 9.998000155789563e-01, 9.998153749282102e-01, - 9.998312752183705e-01, 9.998476709365336e-01, 9.998645148326535e-01, 9.998817580746918e-01, 9.998993504124516e-01, - 9.999172403493102e-01, 9.999353753209660e-01, 9.999537018802587e-01, 9.999721658870584e-01, 9.999907127021610e-01, - 1.000009262768464e+00, 1.000027750736626e+00, 1.000046113687940e+00, 1.000064278821780e+00, 1.000082169071538e+00, - 1.000099702238537e+00, 1.000116790156982e+00, 1.000133337763978e+00, 1.000149242061725e+00, 1.000164390968527e+00, - 1.000178662057694e+00, 1.000191921184823e+00, 1.000204021005123e+00, 1.000214799383556e+00, 1.000224077701589e+00, - 1.000231659065357e+00, 1.000237326420850e+00, 1.000240840582544e+00, 1.000241938182520e+00, 1.000240329547572e+00, - 1.000235696512191e+00, 1.000227690175467e+00, 1.000215928609961e+00, 1.000199994530463e+00, 1.000179432930259e+00, - 1.000153748692032e+00, 1.000122404179984e+00, 1.000084816818973e+00, 1.000040356665695e+00, 9.999883439759534e-01, - 9.999280467710976e-01, 9.998586784056549e-01, 9.997793951371076e-01, 9.996892936976876e-01, 9.995874088670188e-01, - 9.994727110434261e-01, 9.993441038107910e-01, 9.992004214970033e-01, 9.990404267193601e-01, 9.988628079116455e-01, - 9.986661768272946e-01, 9.984490660128014e-01, 9.982099262455740e-01, 9.979471239307242e-01, 9.976589384518300e-01, - 9.973435594715599e-01, 9.969990841792483e-01, 9.966235144840385e-01, 9.962147541541155e-01, 9.957706059048574e-01, - 9.952887684414411e-01, 9.947668334645193e-01, 9.942022826511501e-01, 9.935924846270409e-01, 9.929346919504907e-01, - 9.922260381330554e-01, 9.914635347268980e-01, 9.906440685140006e-01, 9.897643988377397e-01, 9.888211551228012e-01, - 9.878108346347950e-01, 9.867298005362246e-01, 9.855742803004703e-01, 9.843403645500459e-01, 9.830240063894612e-01, - 9.816210213063771e-01, 9.801270877173017e-01, 9.785377482356147e-01, 9.768484117402024e-01, 9.750543563222487e-01, - 9.731507331856758e-01, 9.711325715733536e-01, 9.689947847863860e-01, 9.667321773575633e-01, 9.643394534324848e-01, - 9.618112264029069e-01, 9.591420298267040e-01, 9.563263296575538e-01, 9.533585377951747e-01, 9.502330269539270e-01, - 9.469441468339291e-01, 9.434862415648529e-01, 9.398536683783788e-01, 9.360408174512334e-01, 9.320421328469384e-01, - 9.278521344711611e-01, 9.234654409430395e-01, 9.188767932732427e-01, 9.140810792290244e-01, 9.090733582572249e-01, - 9.038488868282046e-01, 8.984031440571518e-01, 8.927318574541139e-01, 8.868310286504967e-01, 8.806969589476717e-01, - 8.743262745326578e-01, 8.677159512065934e-01, 8.608633384737868e-01, 8.537661828424618e-01, 8.464226501927783e-01, - 8.388313470732423e-01, 8.309913407930509e-01, 8.229021781851953e-01, 8.145639029231079e-01, 8.059770712821837e-01, - 7.971427662465509e-01, 7.880626098708469e-01, 7.787387738164395e-01, 7.691739879913762e-01, 7.593715472332762e-01, - 7.493353159843403e-01, 7.390697309175267e-01, 7.285798014827035e-01, 7.178711083511555e-01, 7.069497997461519e-01, - 6.958225856563154e-01, 6.844967299372567e-01, 6.729800403152869e-01, 6.612808563149986e-01, 6.494080351400781e-01, - 6.373709355438772e-01, 6.251793997330287e-01, 6.128437333537300e-01, 6.003746836162993e-01, 5.877834156192006e-01, - 5.750814869390165e-01, 5.622808205578382e-01, 5.493936762043069e-01, 5.364326201891255e-01, 5.234104938203454e-01, - 5.103403804881693e-01, 4.972355715134865e-01, 4.841095308589323e-01, 4.709758588060189e-01, 4.578482547068641e-01, - 4.447404789243264e-01, 4.316663140799624e-01, 4.186395257351866e-01, 4.056738226373441e-01, 3.927828166690819e-01, - 3.799799826463771e-01, 3.672786181177968e-01, 3.546918033248968e-01, 3.422323614910038e-01, 3.299128196128071e-01, - 3.177453699359932e-01, 3.057418323024091e-01, 2.939136175616680e-01, 2.822716922444745e-01, 2.708265446979701e-01, - 2.595881528848133e-01, 2.485659540472639e-01, 2.377688164349652e-01, 2.272050132902212e-01, 2.168821992771410e-01, - 2.068073895309444e-01, 1.969869414909128e-01, 1.874265396648929e-01, 1.781311834549869e-01, 1.691051781531976e-01, - 1.603521291925451e-01, 1.518749397137918e-01, 1.436758114807520e-01, 1.357562491485994e-01, 1.281170678600890e-01, - 1.207584041146470e-01, 1.136797298253828e-01, 1.068798694497608e-01, 1.003570200514591e-01, 9.410877412434678e-02, - 8.813214498499827e-02, 8.242359451816077e-02, 7.697906304046008e-02, 7.179400103167609e-02, 6.686340247035585e-02, - 6.218183950151154e-02, 5.774349815872721e-02, 5.354221486116098e-02, 4.957151340757950e-02, 4.582464219454362e-02, - 4.229461139394613e-02, 3.897422983601720e-02, 3.585614135733534e-02, 3.293286038897012e-02, 3.019680657726779e-02, - 2.764033824859545e-02, 2.525578454921406e-02, 2.303547611198478e-02, 2.097177412248857e-02, 1.905709767802756e-02, - 1.728394935359176e-02, 1.564493890895436e-02, 1.413280509038132e-02, 1.274043549881785e-02, 1.146088451369467e-02, - 1.028738927756386e-02, 9.213383761543762e-03, 8.232510944970423e-03, 7.338633154694566e-03, 6.525840620123105e-03, - 5.788458309403464e-03, 5.121051120120478e-03, 4.518427504569718e-03, 3.975641615147556e-03, 3.487994059724770e-03, - 3.051031360120983e-03, 2.660544209048234e-03, 2.312564622222088e-03, 2.003362082825875e-03, 1.729438775235064e-03, - 1.487524003938835e-03, 1.274567892006584e-03, 1.087734451306357e-03, 9.243941140548951e-04, 7.821158122256320e-04, - 6.586586879186365e-04, 5.519635140582476e-04, 4.601439007796695e-04, 3.814773586413279e-04, 3.143962853984603e-04, - 2.574789385355991e-04, 2.094404511189233e-04, 1.691239438292752e-04, 1.354917813061114e-04, 1.076170162029800e-04, - 8.467505965565773e-05, 6.593561222250244e-05, 5.075488479887568e-05, 3.856813455801580e-05, 2.888253665201353e-05, - 2.127040823889544e-05, 1.536279740228267e-05, 1.084344570939908e-05, 7.443129506680882e-06, 4.934381529209004e-06, - 3.126590786650604e-06, 1.861474073153740e-06, 1.008902130957542e-06, 4.630128105556161e-07, 1.379047824504878e-07, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_HRA_WINDOW_480_10ms[960] = { - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 9.423411645757145e-08, 6.198383813913816e-07, 1.826038044753334e-06, 4.227415544684874e-06, 8.568221371240009e-06, - 1.590138306691229e-05, 2.767384916372097e-05, 4.582461489197476e-05, 7.289566442148343e-05, 1.121553337189409e-04, - 1.677330226576781e-04, 2.447635817250988e-04, 3.495390594774230e-04, 4.896648355656373e-04, 6.742165007916612e-04, - 9.138932038423809e-04, 1.221162590096684e-03, 1.610391938745493e-03, 2.097959688543948e-03, 2.702341257534836e-03, - 3.444162934209273e-03, 4.346217670272292e-03, 5.433436858058855e-03, 6.732812643305091e-03, 8.273266014983896e-03, - 1.008545682987358e-02, 1.220153306437313e-02, 1.465481792555360e-02, 1.747943497487382e-02, 2.070987309036685e-02, - 2.438049487743156e-02, 2.852499398840518e-02, 3.317580867440409e-02, 3.836350071222914e-02, 4.411611056397528e-02, - 5.045850117560903e-02, 5.741170414223051e-02, 6.499228300404947e-02, 7.321172913556540e-02, 8.207590600577601e-02, - 9.158455748369454e-02, 1.017308953166495e-01, 1.125012799073065e-01, 1.238750070616895e-01, 1.358242114920720e-01, - 1.483138955678087e-01, 1.613020891609740e-01, 1.747401434927874e-01, 1.885731587242474e-01, 2.027405417335493e-01, - 2.171766871750067e-01, 2.318117716158385e-01, 2.465726473968904e-01, 2.613838199586506e-01, 2.761684898079396e-01, - 2.908496381590925e-01, 3.053511336415384e-01, 3.195988363856895e-01, 3.335216753280081e-01, 3.470526747443392e-01, - 3.601299968134419e-01, 3.726979341699064e-01, 3.847073300820699e-01, 3.961165192918680e-01, 4.068917464693262e-01, - 4.170075357150957e-01, 4.264469007050540e-01, 4.352013996719531e-01, 4.432710380854631e-01, 4.506640257151909e-01, - 4.573963985795680e-01, 4.634915197715306e-01, 4.689794761564862e-01, 4.738963903364035e-01, 4.782836689638748e-01, - 4.821872093925473e-01, 4.856565867140006e-01, 4.887442424370954e-01, 4.915046944332492e-01, 4.939937853618382e-01, - 4.962679837116828e-01, 4.983837480011794e-01, 5.003969607669508e-01, 5.023624349677376e-01, 5.043334915837460e-01, - 5.063616037481589e-01, 5.084960999306821e-01, 5.107839166820760e-01, 5.132693903594975e-01, 5.159940771247666e-01, - 5.189965912996581e-01, 5.223124537547313e-01, 5.259739442166247e-01, 5.300099539725758e-01, 5.344458381774531e-01, - 5.393032695777062e-01, 5.446000977350559e-01, 5.503502195833738e-01, 5.565634682679432e-01, 5.632455276465002e-01, - 5.703978795909497e-01, 5.780177903898996e-01, 5.860983412324646e-01, 5.946285060985402e-01, 6.035932785464501e-01, - 6.129738470263359e-01, 6.227478165890419e-01, 6.328894733093686e-01, 6.433700864704220e-01, 6.541582425999274e-01, - 6.652202048172945e-01, 6.765202906248624e-01, 6.880212612236103e-01, 6.996847156078869e-01, 7.114714830467992e-01, - 7.233420080447298e-01, 7.352567224482216e-01, 7.471763999968595e-01, 7.590624892758133e-01, 7.708774216994878e-01, - 7.825848918282421e-01, 7.941501079877761e-01, 8.055400118211323e-01, 8.167234660553659e-01, 8.276714104070468e-01, - 8.383569861788307e-01, 8.487556307051457e-01, 8.588451433758131e-01, 8.686057254837016e-01, 8.780199965830640e-01, - 8.870729903819699e-01, 8.957521333967015e-01, 9.040472096414102e-01, 9.119503144919421e-01, 9.194558005383104e-01, - 9.265602177306744e-01, 9.332622494524668e-01, 9.395626453655078e-01, 9.454641510291475e-01, 9.509714334776073e-01, - 9.560910012334918e-01, 9.608311167251793e-01, 9.652016988316350e-01, 9.692142133449947e-01, 9.728815495300325e-01, - 9.762178816434048e-01, 9.792385151909874e-01, 9.819597187561544e-01, 9.843985433157453e-01, 9.865726319613708e-01, - 9.885000237614154e-01, 9.901989560579394e-01, 9.916876697497727e-01, 9.929842220610799e-01, 9.941063109595989e-01, - 9.950711148231832e-01, 9.958951502269355e-01, 9.965941499123417e-01, 9.971829621771531e-01, 9.976754721515079e-01, - 9.980845447462318e-01, 9.984219884986877e-01, 9.986985391068631e-01, 9.989238611254968e-01, 9.991065660804971e-01, - 9.992542451163898e-01, 9.993735142030505e-01, 9.994700698738658e-01, 9.995487534360048e-01, 9.996136215806155e-01, - 9.996680213292980e-01, 9.997146672907700e-01, 9.997557192777461e-01, 9.997928584573587e-01, 9.998273603841155e-01, - 9.998601634925650e-01, 9.998919319028886e-01, 9.999231117133845e-01, 9.999539803782231e-01, 9.999846913144619e-01, - 1.000015271687402e+00, 1.000045768313827e+00, 1.000076123719886e+00, 1.000106243781657e+00, 1.000136035347070e+00, - 1.000165406619359e+00, 1.000194267530612e+00, 1.000222530102796e+00, 1.000250108793741e+00, 1.000276920825814e+00, - 1.000302886495191e+00, 1.000327929459891e+00, 1.000351977005012e+00, 1.000374960283849e+00, 1.000396814533868e+00, - 1.000417479266803e+00, 1.000436898432418e+00, 1.000455020555724e+00, 1.000471798847772e+00, 1.000487191290310e+00, - 1.000501160694917e+00, 1.000513674737357e+00, 1.000524705968167e+00, 1.000534231800605e+00, 1.000542234477265e+00, - 1.000548701016775e+00, 1.000553623142091e+00, 1.000556997191966e+00, 1.000558824017243e+00, 1.000559108863603e+00, - 1.000557861242456e+00, 1.000555094791586e+00, 1.000550827127188e+00, 1.000545079688822e+00, 1.000537877578802e+00, - 1.000529249397403e+00, 1.000519227075235e+00, 1.000507845704000e+00, 1.000495143366764e+00, 1.000481160968755e+00, - 1.000465942069620e+00, 1.000449532717920e+00, 1.000431981288574e+00, 1.000413338323831e+00, 1.000393656378250e+00, - 1.000372989868060e+00, 1.000351394925194e+00, 1.000328929256167e+00, 1.000305652005906e+00, 1.000281623626542e+00, - 1.000256905751110e+00, 1.000231561072014e+00, 1.000205653224064e+00, 1.000179246671831e+00, 1.000152406601017e+00, - 1.000125198813461e+00, 1.000097689625410e+00, 1.000069945768613e+00, 1.000042034293768e+00, 1.000014022475844e+00, - 9.999859777207831e-01, 9.999579674730398e-01, 9.999300591234549e-01, 9.999023199169207e-01, 9.998748168593201e-01, - 9.998476166232155e-01, 9.998207854517803e-01, 9.997943890604891e-01, 9.997684925361024e-01, 9.997431602325028e-01, - 9.997184556629950e-01, 9.996944413886967e-01, 9.996711789027117e-01, 9.996487285098250e-01, 9.996271492015102e-01, - 9.996064985261154e-01, 9.995868324541498e-01, 9.995682052386838e-01, 9.995506692709443e-01, 9.995342749312822e-01, - 9.995190704357798e-01, 9.995051016788571e-01, 9.994924120723486e-01, 9.994810423816121e-01, 9.994710305593550e-01, - 9.994624115779566e-01, 9.994552172611834e-01, 9.994494761163015e-01, 9.994452131676952e-01, 9.994424497931953e-01, - 9.994412035644367e-01, 9.994414880926250e-01, 9.994433128811957e-01, 9.994466831869019e-01, 9.994515998909221e-01, - 9.994580593816230e-01, 9.994660534506217e-01, 9.994755692038015e-01, 9.994865889889091e-01, 9.994990903413156e-01, - 9.995130459494618e-01, 9.995284236414108e-01, 9.995451863938154e-01, 9.995632923644638e-01, 9.995826949494031e-01, - 9.996033428654485e-01, 9.996251802586674e-01, 9.996481468392096e-01, 9.996721780425870e-01, 9.996972052172600e-01, - 9.997231558380996e-01, 9.997499537450264e-01, 9.997775194058337e-01, 9.998057702019313e-01, 9.998346207354666e-01, - 9.998639831560286e-01, 9.998937675048852e-01, 9.999238820744936e-01, 9.999542337808154e-01, 9.999847285458191e-01, - 1.000015271687393e+00, 1.000045768313818e+00, 1.000076123719878e+00, 1.000106243781648e+00, 1.000136035347061e+00, - 1.000165406619350e+00, 1.000194267530604e+00, 1.000222530102788e+00, 1.000250108793733e+00, 1.000276920825807e+00, - 1.000302886495184e+00, 1.000327929459883e+00, 1.000351977005006e+00, 1.000374960283843e+00, 1.000396814533862e+00, - 1.000417479266798e+00, 1.000436898432413e+00, 1.000455020555719e+00, 1.000471798847767e+00, 1.000487191290306e+00, - 1.000501160694914e+00, 1.000513674737354e+00, 1.000524705968165e+00, 1.000534231800603e+00, 1.000542234477263e+00, - 1.000548701016774e+00, 1.000553623142090e+00, 1.000556997191965e+00, 1.000558824017242e+00, 1.000559108863603e+00, - 1.000557861242456e+00, 1.000555094791587e+00, 1.000550827127188e+00, 1.000545079688823e+00, 1.000537877578803e+00, - 1.000529249397404e+00, 1.000519227075236e+00, 1.000507845704002e+00, 1.000495143366766e+00, 1.000481160968757e+00, - 1.000465942069622e+00, 1.000449532717922e+00, 1.000431981288576e+00, 1.000413338323833e+00, 1.000393656378252e+00, - 1.000372989868062e+00, 1.000351394925196e+00, 1.000328929256169e+00, 1.000305652005908e+00, 1.000281623626544e+00, - 1.000256905751112e+00, 1.000231561072016e+00, 1.000205653224065e+00, 1.000179246671832e+00, 1.000152406601018e+00, - 1.000125198813462e+00, 1.000097689625411e+00, 1.000069945768614e+00, 1.000042034293768e+00, 1.000014022475844e+00, - 9.999859777207829e-01, 9.999579674730393e-01, 9.999300591234543e-01, 9.999023199169199e-01, 9.998748168593190e-01, - 9.998476166232144e-01, 9.998207854517789e-01, 9.997943890604876e-01, 9.997684925361007e-01, 9.997431602325010e-01, - 9.997184556629931e-01, 9.996944413886946e-01, 9.996711789027095e-01, 9.996487285098227e-01, 9.996271492015080e-01, - 9.996064985261129e-01, 9.995868324541474e-01, 9.995682052386815e-01, 9.995506692709419e-01, 9.995342749312801e-01, - 9.995190704357777e-01, 9.995051016788550e-01, 9.994924120723468e-01, 9.994810423816103e-01, 9.994710305593536e-01, - 9.994624115779553e-01, 9.994552172611824e-01, 9.994494761163009e-01, 9.994452131676944e-01, 9.994424497931950e-01, - 9.994412035644368e-01, 9.994414880926255e-01, 9.994433128811966e-01, 9.994466831869030e-01, 9.994515998909239e-01, - 9.994580593816250e-01, 9.994660534506239e-01, 9.994755692038041e-01, 9.994865889889122e-01, 9.994990903413189e-01, - 9.995130459494656e-01, 9.995284236414153e-01, 9.995451863938203e-01, 9.995632923644688e-01, 9.995826949494085e-01, - 9.996033428654543e-01, 9.996251802586735e-01, 9.996481468392161e-01, 9.996721780425940e-01, 9.996972052172670e-01, - 9.997231558381070e-01, 9.997499537450341e-01, 9.997775194058416e-01, 9.998057702019393e-01, 9.998346207354748e-01, - 9.998639831560371e-01, 9.998937675048939e-01, 9.999238820745020e-01, 9.999542337808240e-01, 9.999847285458278e-01, - 1.000015271687402e+00, 1.000045768313827e+00, 1.000076123719886e+00, 1.000106243781657e+00, 1.000136035347070e+00, - 1.000165406619359e+00, 1.000194267530612e+00, 1.000222530102796e+00, 1.000250108793741e+00, 1.000276920825814e+00, - 1.000302886495191e+00, 1.000327929459890e+00, 1.000351977005012e+00, 1.000374960283849e+00, 1.000396814533868e+00, - 1.000417479266803e+00, 1.000436898432418e+00, 1.000455020555724e+00, 1.000471798847772e+00, 1.000487191290310e+00, - 1.000501160694917e+00, 1.000513674737357e+00, 1.000524705968167e+00, 1.000534231800605e+00, 1.000542234477265e+00, - 1.000548701016775e+00, 1.000553623142091e+00, 1.000556997191966e+00, 1.000558824017243e+00, 1.000559108863603e+00, - 1.000557861242456e+00, 1.000555094791586e+00, 1.000550827127188e+00, 1.000545079688822e+00, 1.000537877578802e+00, - 1.000529249397403e+00, 1.000519227075234e+00, 1.000507845704000e+00, 1.000495143366764e+00, 1.000481160968755e+00, - 1.000465942069620e+00, 1.000449532717920e+00, 1.000431981288574e+00, 1.000413338323831e+00, 1.000393656378250e+00, - 1.000372989868060e+00, 1.000351394925194e+00, 1.000328929256167e+00, 1.000305652005906e+00, 1.000281623626542e+00, - 1.000256905751111e+00, 1.000231561072014e+00, 1.000205653224064e+00, 1.000179246671831e+00, 1.000152406601017e+00, - 1.000125198813461e+00, 1.000097689625410e+00, 1.000069945768614e+00, 1.000042034293768e+00, 1.000014022475844e+00, - 9.999859777207832e-01, 9.999579674730399e-01, 9.999300591234550e-01, 9.999023199169208e-01, 9.998748168593202e-01, - 9.998476166232156e-01, 9.998207854517805e-01, 9.997943890604892e-01, 9.997684925361026e-01, 9.997431602325029e-01, - 9.997184556629951e-01, 9.996944413886968e-01, 9.996711789027117e-01, 9.996487285098250e-01, 9.996271492015103e-01, - 9.996064985261155e-01, 9.995868324541498e-01, 9.995682052386839e-01, 9.995506692709443e-01, 9.995342749312823e-01, - 9.995190704357798e-01, 9.995051016788571e-01, 9.994924120723486e-01, 9.994810423816120e-01, 9.994710305593552e-01, - 9.994624115779566e-01, 9.994552172611834e-01, 9.994494761163015e-01, 9.994452131676951e-01, 9.994424497931953e-01, - 9.994412035644367e-01, 9.994414880926250e-01, 9.994433128811958e-01, 9.994466831869019e-01, 9.994515998909221e-01, - 9.994580593816230e-01, 9.994660534506217e-01, 9.994755692038015e-01, 9.994865889889089e-01, 9.994990903413155e-01, - 9.995130459494618e-01, 9.995284236414110e-01, 9.995451863938154e-01, 9.995632923644640e-01, 9.995826949494031e-01, - 9.996033428654485e-01, 9.996251802586674e-01, 9.996481468392096e-01, 9.996721780425870e-01, 9.996972052172600e-01, - 9.997231558380997e-01, 9.997499537450264e-01, 9.997775194058337e-01, 9.998057702019313e-01, 9.998346207354665e-01, - 9.998639831560286e-01, 9.998937675048852e-01, 9.999238820744936e-01, 9.999542337808154e-01, 9.999847285458191e-01, - 1.000015234454879e+00, 1.000045514887559e+00, 1.000075353237462e+00, 1.000104407768116e+00, 1.000132214556229e+00, - 1.000158143563050e+00, 1.000181349852841e+00, 1.000200717764093e+00, 1.000214798354899e+00, 1.000221740822748e+00, - 1.000219218852980e+00, 1.000204353032496e+00, 1.000173630567007e+00, 1.000122823551604e+00, 1.000046906963284e+00, - 9.999399773758973e-01, 9.997951731574873e-01, 9.996045966188434e-01, 9.993592382687311e-01, 9.990489030278769e-01, - 9.986621379953039e-01, 9.981861611823875e-01, 9.976067905662288e-01, 9.969083728962124e-01, 9.960737119427251e-01, - 9.950839963248127e-01, 9.939187277034516e-01, 9.925556509742455e-01, 9.909706891139552e-01, 9.891378864826104e-01, - 9.870293655848442e-01, 9.846153034530920e-01, 9.818639348132027e-01, 9.787415898998961e-01, 9.752127750773143e-01, - 9.712403041791187e-01, 9.667854876397981e-01, 9.618083850218845e-01, 9.562681244917907e-01, 9.501232902622440e-01, - 9.433323761603356e-01, 9.358543004959359e-01, 9.276489745130293e-01, 9.186779141170132e-01, 9.089048824643602e-01, - 8.982965495078461e-01, 8.868231537804969e-01, 8.744591515805539e-01, 8.611838392360764e-01, 8.469819351830896e-01, - 8.318441100567543e-01, 8.157674547284579e-01, 7.987558780821055e-01, 7.808204281831013e-01, 7.619795322485697e-01, - 7.422591523986999e-01, 7.216928555056540e-01, 7.003217965330363e-01, 6.781946155731466e-01, 6.553672493579565e-01, - 6.319026583753357e-01, 6.078704709095413e-01, 5.833465453994711e-01, 5.584124525334641e-01, 5.331548785464441e-01, - 5.076649513306994e-01, 4.820374912962984e-01, 4.563701895024020e-01, 4.307627165039317e-01, 4.053157666856800e-01, - 3.801300446346412e-01, 3.553052023472212e-01, 3.309387387548210e-01, 3.071248760994941e-01, 2.839534309593199e-01, - 2.615087010038701e-01, 2.398683915856861e-01, 2.191026087292818e-01, 1.992729466284019e-01, 1.804316980820018e-01, - 1.626212151220100e-01, 1.458734442426148e-01, 1.302096560997370e-01, 1.156403834405376e-01, 1.021655736434582e-01, - 8.977495404596501e-02, 7.844859976518601e-02, 6.815768558157265e-02, 5.886539624579484e-02, 5.052796378898961e-02, - 4.309579643342800e-02, 3.651466171052548e-02, 3.072688641085486e-02, 2.567253786455677e-02, 2.129055449466347e-02, - 1.751979822585132e-02, 1.430000675209340e-02, 1.157262945800897e-02, 9.281536579910191e-03, 7.373596677207363e-03, - 5.799122432483531e-03, 4.512189056010577e-03, 3.470833055336534e-03, 2.637141819806632e-03, 1.977246386436426e-03, - 1.461230953040205e-03, 1.062973263413438e-03, 7.599299954798238e-04, 5.328808285940163e-04, 3.656440417062249e-04, - 2.447753867250028e-04, 1.592606718286519e-04, 1.002110509628055e-04, 6.056851356108083e-05, 3.482755929907460e-05, - 1.877757338165862e-05, 9.269020516017977e-06, 4.005234147116555e-06, 1.359891615054068e-06, 2.067694412143206e-07, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - -const LC3_FLOAT MDCT_HRA_WINDOW_960_10ms[1920] = { - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 6.663107991278473e-08, 2.237239208214098e-07, 4.875418283123564e-07, 8.996727135884617e-07, 1.511418282137696e-06, - 2.385908181307981e-06, 3.600021534325060e-06, 5.246458929559746e-06, 7.435999429480928e-06, 1.029995277226023e-05, - 1.399281202683861e-05, 1.869510977726803e-05, 2.461647918005920e-05, 3.199891951615131e-05, 4.112026404149671e-05, - 5.229784600131515e-05, 6.589235661010597e-05, 8.231188661821365e-05, 1.020161407958678e-04, 1.255208122795613e-04, - 1.534021012578998e-04, 1.863013599410517e-04, 2.249298431778123e-04, 2.700735414768832e-04, 3.225980705756125e-04, - 3.834535891028970e-04, 4.536797133272969e-04, 5.344103954917697e-04, 6.268787298389575e-04, 7.324216481524320e-04, - 8.524844645071808e-04, 9.886252269645022e-04, 1.142518832190136e-03, 1.315960857447457e-03, 1.510871063146860e-03, - 1.729296518144556e-03, 1.973414299303950e-03, 2.245533716484770e-03, 2.548098014131402e-03, 2.883685501012940e-03, - 3.255010060441685e-03, 3.664920994479873e-03, 4.116402157249738e-03, 4.612570334499312e-03, 5.156672829053223e-03, - 5.752084214696966e-03, 6.402302224405338e-03, 7.110942742626702e-03, 7.881733875566514e-03, 8.718509078064964e-03, - 9.625199320718177e-03, 1.060582428632988e-02, 1.166448259057781e-02, 1.280534102790626e-02, 1.403262285008227e-02, - 1.535059509154052e-02, 1.676355496255211e-02, 1.827581533833950e-02, 1.989168937947954e-02, 2.161547432623578e-02, - 2.345143451678970e-02, 2.540378368664082e-02, 2.747666661366220e-02, 2.967414018037076e-02, 3.200015393184128e-02, - 3.445853021429810e-02, 3.705294398569962e-02, 3.978690239552551e-02, 4.266372423642605e-02, 4.568651937534197e-02, - 4.885816827608890e-02, 5.218130172917755e-02, 5.565828090775238e-02, 5.929117787093344e-02, 6.308175663749782e-02, - 6.703145495369379e-02, 7.114136687902073e-02, 7.541222631299167e-02, 7.984439158421140e-02, 8.443783122053150e-02, - 8.919211101557852e-02, 9.410638250258946e-02, 9.917937294123873e-02, 1.044093769170137e-01, 1.097942496457128e-01, - 1.153314020678296e-01, 1.210177978089837e-01, 1.268499520732061e-01, 1.328239325258333e-01, 1.389353622120686e-01, - 1.451794245459895e-01, 1.515508703929904e-01, 1.580440272564225e-01, 1.646528105666080e-01, 1.713707370575420e-01, - 1.781909402035578e-01, 1.851061876750831e-01, 1.921089007594860e-01, 1.991911756799545e-01, 2.063448067325118e-01, - 2.135613111487021e-01, 2.208319555793100e-01, 2.281477840827779e-01, 2.354996474908733e-01, 2.428782340136974e-01, - 2.502741009364257e-01, 2.576777072513037e-01, 2.650794470604564e-01, 2.724696835780986e-01, 2.798387835547953e-01, - 2.871771519416024e-01, 2.944752666082350e-01, 3.017237129269402e-01, 3.089132180325088e-01, 3.160346845688595e-01, - 3.230792237339257e-01, 3.300381874371329e-01, 3.369031993875939e-01, 3.436661849362722e-01, 3.503193995017128e-01, - 3.568555192112148e-01, 3.632675601002685e-01, 3.695489358061075e-01, 3.756935099828519e-01, 3.816956001322418e-01, - 3.875499962002574e-01, 3.932519766094684e-01, 3.987973219750102e-01, 4.041823264714043e-01, 4.094038068104935e-01, - 4.144591088030795e-01, 4.193461114921915e-01, 4.240632288619702e-01, 4.286094091423471e-01, 4.329841317457969e-01, - 4.371874018882834e-01, 4.412197429619175e-01, 4.450821867417134e-01, 4.487762615229755e-01, 4.523039782991779e-01, - 4.556678151025579e-01, 4.588706996409412e-01, 4.619159903744011e-01, 4.648074561841559e-01, 4.675492547935124e-01, - 4.701459101065887e-01, 4.726022886349306e-01, 4.749235751849055e-01, 4.771152479798792e-01, 4.791830533906173e-01, - 4.811329804451050e-01, 4.829712352850382e-01, 4.847042157306455e-01, 4.863384861083030e-01, 4.878807524866530e-01, - 4.893378384567565e-01, 4.907166615802867e-01, 4.920242106170628e-01, 4.932675236294833e-01, 4.944536670468351e-01, - 4.955897157572258e-01, 4.966827342792363e-01, 4.977397590495528e-01, 4.987677818470457e-01, 4.997737343582849e-01, - 5.007644738745453e-01, 5.017467700962179e-01, 5.027272930074345e-01, 5.037126017718407e-01, 5.047091345900308e-01, - 5.057231994503223e-01, 5.067609656974670e-01, 5.078284563386384e-01, 5.089315410026908e-01, 5.100759294672467e-01, - 5.112671656686335e-01, 5.125106221119896e-01, 5.138114946028988e-01, 5.151747972275419e-01, 5.166053575154047e-01, - 5.181078117268841e-01, 5.196866002174090e-01, 5.213459628397580e-01, 5.230899343568223e-01, 5.249223398478975e-01, - 5.268467901024086e-01, 5.288666770055838e-01, 5.309851689306879e-01, 5.332052061618728e-01, 5.355294963802417e-01, - 5.379605102532377e-01, 5.405004771737987e-01, 5.431513812007881e-01, 5.459149572559273e-01, 5.487926876348163e-01, - 5.517857988905945e-01, 5.548952591484511e-01, 5.581217759075547e-01, 5.614657943841375e-01, 5.649274964455743e-01, - 5.685068001804389e-01, 5.722033601438381e-01, 5.760165683110121e-01, 5.799455557653441e-01, 5.839891951397580e-01, - 5.881461038230944e-01, 5.924146479356704e-01, 5.967929470708762e-01, 6.012788797925822e-01, 6.058700898713546e-01, - 6.105639932361040e-01, 6.153577856119751e-01, 6.202484508099709e-01, 6.252327696291247e-01, 6.303073293279928e-01, - 6.354685336188206e-01, 6.407126131349797e-01, 6.460356363201389e-01, 6.514335206861067e-01, 6.569020443853303e-01, - 6.624368580436263e-01, 6.680334967987880e-01, 6.736873924912369e-01, 6.793938859538112e-01, 6.851482393490396e-01, - 6.909456485038137e-01, 6.967812551932001e-01, 7.026501593271524e-01, 7.085474309960862e-01, 7.144681223336159e-01, - 7.204072791571976e-01, 7.263599523499238e-01, 7.323212089493037e-01, 7.382861429114533e-01, 7.442498855217515e-01, - 7.502076154256456e-01, 7.561545682559222e-01, 7.620860458353852e-01, 7.679974249364871e-01, 7.738841655820752e-01, - 7.797418188739772e-01, 7.855660343387494e-01, 7.913525667824293e-01, 7.970972826487233e-01, 8.027961658775241e-01, - 8.084453232632074e-01, 8.140409893145931e-01, 8.195795306209357e-01, 8.250574497306905e-01, 8.304713885521608e-01, - 8.358181312874381e-01, 8.410946069132281e-01, 8.462978912242891e-01, 8.514252084571686e-01, 8.564739325137894e-01, - 8.614415878060635e-01, 8.663258497442113e-01, 8.711245448926651e-01, 8.758356508184248e-01, 8.804572956574126e-01, - 8.849877574247438e-01, 8.894254630948657e-01, 8.937689874771898e-01, 8.980170519121489e-01, 9.021685228115252e-01, - 9.062224100654551e-01, 9.101778653366538e-01, 9.140341802602550e-01, 9.177907845650995e-01, 9.214472441295430e-01, - 9.250032589817625e-01, 9.284586612513364e-01, 9.318134130755062e-01, 9.350676044601444e-01, 9.382214510920930e-01, - 9.412752920963378e-01, 9.442295877284584e-01, 9.470849169901138e-01, 9.498419751530142e-01, 9.525015711749794e-01, - 9.550646249903935e-01, 9.575321646566392e-01, 9.599053233380030e-01, 9.621853361091064e-01, 9.643735365611265e-01, - 9.664713531959190e-01, 9.684803055955929e-01, 9.704020003580881e-01, 9.722381267927611e-01, 9.739904523738324e-01, - 9.756608179536774e-01, 9.772511327422573e-01, 9.787633690633392e-01, 9.801995569024828e-01, 9.815617782659093e-01, - 9.828521613732500e-01, 9.840728747106564e-01, 9.852261209738314e-01, 9.863141309330354e-01, 9.873391572540936e-01, - 9.883034683107520e-01, 9.892093420244598e-01, 9.900590597677280e-01, 9.908549003667192e-01, 9.915991342376211e-01, - 9.922940176897662e-01, 9.929417874263897e-01, 9.935446552714569e-01, 9.941048031482164e-01, 9.946243783321176e-01, - 9.951054889975415e-01, 9.955502000745265e-01, 9.959605294283782e-01, 9.963384443718103e-01, 9.966858585161255e-01, - 9.970046289649677e-01, 9.972965538513794e-01, 9.975633702163375e-01, 9.978067522246161e-01, 9.980283097117545e-01, - 9.982295870540839e-01, 9.984120623522111e-01, 9.985771469170162e-01, 9.987261850461071e-01, 9.988604540777616e-01, - 9.989811647086401e-01, 9.990894615609515e-01, 9.991864239842999e-01, 9.992730670770456e-01, 9.993503429117423e-01, - 9.994191419489804e-01, 9.994802946237851e-01, 9.995345730885834e-01, 9.995826930966561e-01, 9.996253160099111e-01, - 9.996630509147824e-01, 9.996964568300586e-01, 9.997260449905023e-01, 9.997522811902100e-01, 9.997755881698448e-01, - 9.997963480321130e-01, 9.998149046701891e-01, 9.998315661942099e-01, 9.998466073415005e-01, 9.998602718567984e-01, - 9.998727748295070e-01, 9.998843049758280e-01, 9.998950268545727e-01, 9.999050830064863e-01, 9.999145960080379e-01, - 9.999236704318017e-01, 9.999323947068164e-01, 9.999408428735685e-01, 9.999490762295546e-01, 9.999571448627051e-01, - 9.999650890712967e-01, 9.999729406705412e-01, 9.999807241886484e-01, 9.999884579652744e-01, 9.999961552850937e-01, - 1.000003818641721e+00, 1.000011453001950e+00, 1.000019078522643e+00, 1.000026689281996e+00, 1.000034279373492e+00, - 1.000041842912049e+00, 1.000049374040126e+00, 1.000056866933785e+00, 1.000064315808680e+00, 1.000071714925990e+00, - 1.000079058598250e+00, 1.000086341195099e+00, 1.000093557148926e+00, 1.000100700960395e+00, 1.000107767203853e+00, - 1.000114750532603e+00, 1.000121645684037e+00, 1.000128447484626e+00, 1.000135150854742e+00, 1.000141750813332e+00, - 1.000148242482408e+00, 1.000154621091371e+00, 1.000160881981147e+00, 1.000167020608141e+00, 1.000173032547996e+00, - 1.000178913499161e+00, 1.000184659286256e+00, 1.000190265863238e+00, 1.000195729316362e+00, 1.000201045866939e+00, - 1.000206211873884e+00, 1.000211223836059e+00, 1.000216078394407e+00, 1.000220772333881e+00, 1.000225302585160e+00, - 1.000229666226172e+00, 1.000233860483401e+00, 1.000237882733002e+00, 1.000241730501714e+00, 1.000245401467578e+00, - 1.000248893460465e+00, 1.000252204462412e+00, 1.000255332607784e+00, 1.000258276183243e+00, 1.000261033627556e+00, - 1.000263603531226e+00, 1.000265984635963e+00, 1.000268175833992e+00, 1.000270176167217e+00, 1.000271984826231e+00, - 1.000273601149186e+00, 1.000275024620537e+00, 1.000276254869646e+00, 1.000277291669272e+00, 1.000278134933949e+00, - 1.000278784718248e+00, 1.000279241214938e+00, 1.000279504753058e+00, 1.000279575795894e+00, 1.000279454938873e+00, - 1.000279142907386e+00, 1.000278640554535e+00, 1.000277948858822e+00, 1.000277068921773e+00, 1.000276001965517e+00, - 1.000274749330316e+00, 1.000273312472054e+00, 1.000271692959694e+00, 1.000269892472703e+00, 1.000267912798451e+00, - 1.000265755829598e+00, 1.000263423561457e+00, 1.000260918089352e+00, 1.000258241605975e+00, 1.000255396398729e+00, - 1.000252384847089e+00, 1.000249209419954e+00, 1.000245872673023e+00, 1.000242377246174e+00, 1.000238725860863e+00, - 1.000234921317548e+00, 1.000230966493118e+00, 1.000226864338370e+00, 1.000222617875491e+00, 1.000218230195586e+00, - 1.000213704456221e+00, 1.000209043879012e+00, 1.000204251747240e+00, 1.000199331403501e+00, 1.000194286247397e+00, - 1.000189119733258e+00, 1.000183835367906e+00, 1.000178436708454e+00, 1.000172927360150e+00, 1.000167310974248e+00, - 1.000161591245930e+00, 1.000155771912258e+00, 1.000149856750174e+00, 1.000143849574523e+00, 1.000137754236130e+00, - 1.000131574619904e+00, 1.000125314642979e+00, 1.000118978252895e+00, 1.000112569425805e+00, 1.000106092164726e+00, - 1.000099550497809e+00, 1.000092948476653e+00, 1.000086290174636e+00, 1.000079579685283e+00, 1.000072821120651e+00, - 1.000066018609750e+00, 1.000059176296973e+00, 1.000052298340563e+00, 1.000045388911081e+00, 1.000038452189909e+00, - 1.000031492367753e+00, 1.000024513643172e+00, 1.000017520221111e+00, 1.000010516311443e+00, 1.000003506127529e+00, - 9.999964938847642e-01, 9.999894837991481e-01, 9.999824800858419e-01, 9.999754869577321e-01, 9.999685086239848e-01, - 9.999615492886049e-01, 9.999546131489783e-01, 9.999477043944101e-01, 9.999408272046536e-01, 9.999339857484195e-01, - 9.999271841818784e-01, 9.999204266471391e-01, 9.999137172707154e-01, 9.999070601619628e-01, 9.999004594115060e-01, - 9.998939190896278e-01, 9.998874432446441e-01, 9.998810359012452e-01, 9.998747010588128e-01, 9.998684426896991e-01, - 9.998622647374855e-01, 9.998561711152009e-01, 9.998501657035072e-01, 9.998442523488513e-01, 9.998384348615825e-01, - 9.998327170140316e-01, 9.998271025385516e-01, 9.998215951255243e-01, 9.998161984213253e-01, 9.998109160262525e-01, - 9.998057514924167e-01, 9.998007083215891e-01, 9.997957899630165e-01, 9.997909998111978e-01, 9.997863412036158e-01, - 9.997818174184411e-01, 9.997774316721972e-01, 9.997731871173844e-01, 9.997690868400847e-01, 9.997651338575159e-01, - 9.997613311155714e-01, 9.997576814863203e-01, 9.997541877654884e-01, 9.997508526699078e-01, 9.997476788349500e-01, - 9.997446688119369e-01, 9.997418250655351e-01, 9.997391499711387e-01, 9.997366458122413e-01, 9.997343147777986e-01, - 9.997321589595916e-01, 9.997301803495896e-01, 9.997283808373202e-01, 9.997267622072430e-01, 9.997253261361446e-01, - 9.997240741905490e-01, 9.997230078241506e-01, 9.997221283752786e-01, 9.997214370643954e-01, 9.997209349916318e-01, - 9.997206231343719e-01, 9.997205023448855e-01, 9.997205733480192e-01, 9.997208367389500e-01, 9.997212929810099e-01, - 9.997219424035818e-01, 9.997227852000825e-01, 9.997238214260301e-01, 9.997250509972079e-01, 9.997264736879267e-01, - 9.997280891294001e-01, 9.997298968082279e-01, 9.997318960650045e-01, 9.997340860930513e-01, 9.997364659372833e-01, - 9.997390344932165e-01, 9.997417905061193e-01, 9.997447325703145e-01, 9.997478591286405e-01, 9.997511684720751e-01, - 9.997546587395272e-01, 9.997583279177997e-01, 9.997621738417346e-01, 9.997661941945379e-01, 9.997703865082921e-01, - 9.997747481646607e-01, 9.997792763957842e-01, 9.997839682853786e-01, 9.997888207700281e-01, 9.997938306406862e-01, - 9.997989945443773e-01, 9.998043089861064e-01, 9.998097703309746e-01, 9.998153748065003e-01, 9.998211185051531e-01, - 9.998269973870870e-01, 9.998330072830846e-01, 9.998391438977015e-01, 9.998454028126147e-01, 9.998517794901678e-01, - 9.998582692771129e-01, 9.998648674085433e-01, 9.998715690120116e-01, 9.998783691118356e-01, 9.998852626335712e-01, - 9.998922444086656e-01, 9.998993091792668e-01, 9.999064516031954e-01, 9.999136662590592e-01, 9.999209476515181e-01, - 9.999282902166716e-01, 9.999356883275767e-01, 9.999431362998797e-01, 9.999506283975492e-01, 9.999581588387069e-01, - 9.999657218015428e-01, 9.999733114303027e-01, 9.999809218413399e-01, 9.999885471292198e-01, 9.999961813728609e-01, - 1.000003818641712e+00, 1.000011453001941e+00, 1.000019078522634e+00, 1.000026689281987e+00, 1.000034279373484e+00, - 1.000041842912040e+00, 1.000049374040118e+00, 1.000056866933776e+00, 1.000064315808672e+00, 1.000071714925982e+00, - 1.000079058598242e+00, 1.000086341195091e+00, 1.000093557148918e+00, 1.000100700960387e+00, 1.000107767203845e+00, - 1.000114750532595e+00, 1.000121645684029e+00, 1.000128447484618e+00, 1.000135150854734e+00, 1.000141750813325e+00, - 1.000148242482401e+00, 1.000154621091364e+00, 1.000160881981140e+00, 1.000167020608134e+00, 1.000173032547989e+00, - 1.000178913499155e+00, 1.000184659286250e+00, 1.000190265863232e+00, 1.000195729316356e+00, 1.000201045866933e+00, - 1.000206211873878e+00, 1.000211223836054e+00, 1.000216078394402e+00, 1.000220772333876e+00, 1.000225302585155e+00, - 1.000229666226167e+00, 1.000233860483396e+00, 1.000237882732998e+00, 1.000241730501710e+00, 1.000245401467574e+00, - 1.000248893460461e+00, 1.000252204462409e+00, 1.000255332607781e+00, 1.000258276183240e+00, 1.000261033627553e+00, - 1.000263603531224e+00, 1.000265984635960e+00, 1.000268175833990e+00, 1.000270176167215e+00, 1.000271984826229e+00, - 1.000273601149185e+00, 1.000275024620536e+00, 1.000276254869644e+00, 1.000277291669271e+00, 1.000278134933948e+00, - 1.000278784718247e+00, 1.000279241214938e+00, 1.000279504753058e+00, 1.000279575795894e+00, 1.000279454938873e+00, - 1.000279142907386e+00, 1.000278640554536e+00, 1.000277948858822e+00, 1.000277068921773e+00, 1.000276001965517e+00, - 1.000274749330316e+00, 1.000273312472055e+00, 1.000271692959695e+00, 1.000269892472704e+00, 1.000267912798453e+00, - 1.000265755829599e+00, 1.000263423561458e+00, 1.000260918089354e+00, 1.000258241605976e+00, 1.000255396398731e+00, - 1.000252384847091e+00, 1.000249209419956e+00, 1.000245872673025e+00, 1.000242377246176e+00, 1.000238725860866e+00, - 1.000234921317550e+00, 1.000230966493120e+00, 1.000226864338372e+00, 1.000222617875493e+00, 1.000218230195589e+00, - 1.000213704456224e+00, 1.000209043879015e+00, 1.000204251747242e+00, 1.000199331403503e+00, 1.000194286247399e+00, - 1.000189119733260e+00, 1.000183835367908e+00, 1.000178436708457e+00, 1.000172927360152e+00, 1.000167310974250e+00, - 1.000161591245932e+00, 1.000155771912260e+00, 1.000149856750176e+00, 1.000143849574525e+00, 1.000137754236132e+00, - 1.000131574619906e+00, 1.000125314642981e+00, 1.000118978252897e+00, 1.000112569425807e+00, 1.000106092164727e+00, - 1.000099550497811e+00, 1.000092948476655e+00, 1.000086290174638e+00, 1.000079579685284e+00, 1.000072821120652e+00, - 1.000066018609751e+00, 1.000059176296974e+00, 1.000052298340564e+00, 1.000045388911082e+00, 1.000038452189910e+00, - 1.000031492367754e+00, 1.000024513643172e+00, 1.000017520221111e+00, 1.000010516311444e+00, 1.000003506127529e+00, - 9.999964938847641e-01, 9.999894837991480e-01, 9.999824800858417e-01, 9.999754869577318e-01, 9.999685086239841e-01, - 9.999615492886044e-01, 9.999546131489776e-01, 9.999477043944092e-01, 9.999408272046527e-01, 9.999339857484185e-01, - 9.999271841818773e-01, 9.999204266471379e-01, 9.999137172707140e-01, 9.999070601619615e-01, 9.999004594115044e-01, - 9.998939190896263e-01, 9.998874432446425e-01, 9.998810359012436e-01, 9.998747010588109e-01, 9.998684426896972e-01, - 9.998622647374836e-01, 9.998561711151988e-01, 9.998501657035050e-01, 9.998442523488493e-01, 9.998384348615804e-01, - 9.998327170140294e-01, 9.998271025385493e-01, 9.998215951255222e-01, 9.998161984213230e-01, 9.998109160262503e-01, - 9.998057514924145e-01, 9.998007083215869e-01, 9.997957899630143e-01, 9.997909998111957e-01, 9.997863412036135e-01, - 9.997818174184390e-01, 9.997774316721950e-01, 9.997731871173822e-01, 9.997690868400825e-01, 9.997651338575136e-01, - 9.997613311155693e-01, 9.997576814863183e-01, 9.997541877654863e-01, 9.997508526699059e-01, 9.997476788349481e-01, - 9.997446688119350e-01, 9.997418250655334e-01, 9.997391499711371e-01, 9.997366458122399e-01, 9.997343147777973e-01, - 9.997321589595902e-01, 9.997301803495884e-01, 9.997283808373191e-01, 9.997267622072419e-01, 9.997253261361438e-01, - 9.997240741905483e-01, 9.997230078241500e-01, 9.997221283752783e-01, 9.997214370643952e-01, 9.997209349916318e-01, - 9.997206231343722e-01, 9.997205023448859e-01, 9.997205733480196e-01, 9.997208367389504e-01, 9.997212929810105e-01, - 9.997219424035826e-01, 9.997227852000836e-01, 9.997238214260314e-01, 9.997250509972092e-01, 9.997264736879284e-01, - 9.997280891294021e-01, 9.997298968082300e-01, 9.997318960650067e-01, 9.997340860930538e-01, 9.997364659372859e-01, - 9.997390344932195e-01, 9.997417905061224e-01, 9.997447325703176e-01, 9.997478591286439e-01, 9.997511684720787e-01, - 9.997546587395311e-01, 9.997583279178037e-01, 9.997621738417388e-01, 9.997661941945423e-01, 9.997703865082966e-01, - 9.997747481646656e-01, 9.997792763957892e-01, 9.997839682853837e-01, 9.997888207700335e-01, 9.997938306406916e-01, - 9.997989945443829e-01, 9.998043089861125e-01, 9.998097703309806e-01, 9.998153748065066e-01, 9.998211185051595e-01, - 9.998269973870937e-01, 9.998330072830913e-01, 9.998391438977084e-01, 9.998454028126217e-01, 9.998517794901752e-01, - 9.998582692771203e-01, 9.998648674085506e-01, 9.998715690120191e-01, 9.998783691118432e-01, 9.998852626335790e-01, - 9.998922444086736e-01, 9.998993091792749e-01, 9.999064516032034e-01, 9.999136662590675e-01, 9.999209476515264e-01, - 9.999282902166798e-01, 9.999356883275852e-01, 9.999431362998885e-01, 9.999506283975580e-01, 9.999581588387155e-01, - 9.999657218015514e-01, 9.999733114303114e-01, 9.999809218413486e-01, 9.999885471292286e-01, 9.999961813728698e-01, - 1.000003818641721e+00, 1.000011453001950e+00, 1.000019078522643e+00, 1.000026689281996e+00, 1.000034279373492e+00, - 1.000041842912049e+00, 1.000049374040126e+00, 1.000056866933785e+00, 1.000064315808680e+00, 1.000071714925990e+00, - 1.000079058598250e+00, 1.000086341195099e+00, 1.000093557148926e+00, 1.000100700960395e+00, 1.000107767203853e+00, - 1.000114750532602e+00, 1.000121645684037e+00, 1.000128447484626e+00, 1.000135150854742e+00, 1.000141750813332e+00, - 1.000148242482408e+00, 1.000154621091371e+00, 1.000160881981147e+00, 1.000167020608141e+00, 1.000173032547996e+00, - 1.000178913499161e+00, 1.000184659286256e+00, 1.000190265863238e+00, 1.000195729316362e+00, 1.000201045866939e+00, - 1.000206211873884e+00, 1.000211223836059e+00, 1.000216078394407e+00, 1.000220772333881e+00, 1.000225302585160e+00, - 1.000229666226172e+00, 1.000233860483401e+00, 1.000237882733002e+00, 1.000241730501714e+00, 1.000245401467578e+00, - 1.000248893460465e+00, 1.000252204462412e+00, 1.000255332607784e+00, 1.000258276183243e+00, 1.000261033627556e+00, - 1.000263603531226e+00, 1.000265984635963e+00, 1.000268175833992e+00, 1.000270176167217e+00, 1.000271984826231e+00, - 1.000273601149187e+00, 1.000275024620537e+00, 1.000276254869646e+00, 1.000277291669272e+00, 1.000278134933949e+00, - 1.000278784718248e+00, 1.000279241214938e+00, 1.000279504753058e+00, 1.000279575795894e+00, 1.000279454938873e+00, - 1.000279142907386e+00, 1.000278640554535e+00, 1.000277948858822e+00, 1.000277068921773e+00, 1.000276001965517e+00, - 1.000274749330316e+00, 1.000273312472054e+00, 1.000271692959694e+00, 1.000269892472703e+00, 1.000267912798451e+00, - 1.000265755829598e+00, 1.000263423561457e+00, 1.000260918089352e+00, 1.000258241605975e+00, 1.000255396398729e+00, - 1.000252384847089e+00, 1.000249209419954e+00, 1.000245872673023e+00, 1.000242377246174e+00, 1.000238725860863e+00, - 1.000234921317548e+00, 1.000230966493118e+00, 1.000226864338370e+00, 1.000222617875491e+00, 1.000218230195586e+00, - 1.000213704456221e+00, 1.000209043879013e+00, 1.000204251747240e+00, 1.000199331403501e+00, 1.000194286247397e+00, - 1.000189119733258e+00, 1.000183835367906e+00, 1.000178436708454e+00, 1.000172927360150e+00, 1.000167310974248e+00, - 1.000161591245930e+00, 1.000155771912258e+00, 1.000149856750174e+00, 1.000143849574523e+00, 1.000137754236130e+00, - 1.000131574619904e+00, 1.000125314642979e+00, 1.000118978252895e+00, 1.000112569425805e+00, 1.000106092164726e+00, - 1.000099550497809e+00, 1.000092948476653e+00, 1.000086290174636e+00, 1.000079579685283e+00, 1.000072821120651e+00, - 1.000066018609750e+00, 1.000059176296973e+00, 1.000052298340563e+00, 1.000045388911081e+00, 1.000038452189909e+00, - 1.000031492367753e+00, 1.000024513643172e+00, 1.000017520221111e+00, 1.000010516311443e+00, 1.000003506127529e+00, - 9.999964938847643e-01, 9.999894837991482e-01, 9.999824800858421e-01, 9.999754869577322e-01, 9.999685086239848e-01, - 9.999615492886050e-01, 9.999546131489783e-01, 9.999477043944101e-01, 9.999408272046536e-01, 9.999339857484195e-01, - 9.999271841818784e-01, 9.999204266471392e-01, 9.999137172707154e-01, 9.999070601619630e-01, 9.999004594115060e-01, - 9.998939190896279e-01, 9.998874432446442e-01, 9.998810359012452e-01, 9.998747010588128e-01, 9.998684426896991e-01, - 9.998622647374856e-01, 9.998561711152009e-01, 9.998501657035073e-01, 9.998442523488514e-01, 9.998384348615826e-01, - 9.998327170140316e-01, 9.998271025385517e-01, 9.998215951255245e-01, 9.998161984213253e-01, 9.998109160262525e-01, - 9.998057514924167e-01, 9.998007083215890e-01, 9.997957899630168e-01, 9.997909998111979e-01, 9.997863412036158e-01, - 9.997818174184412e-01, 9.997774316721972e-01, 9.997731871173845e-01, 9.997690868400848e-01, 9.997651338575160e-01, - 9.997613311155714e-01, 9.997576814863203e-01, 9.997541877654884e-01, 9.997508526699078e-01, 9.997476788349500e-01, - 9.997446688119369e-01, 9.997418250655351e-01, 9.997391499711387e-01, 9.997366458122413e-01, 9.997343147777986e-01, - 9.997321589595916e-01, 9.997301803495896e-01, 9.997283808373202e-01, 9.997267622072429e-01, 9.997253261361446e-01, - 9.997240741905490e-01, 9.997230078241506e-01, 9.997221283752786e-01, 9.997214370643954e-01, 9.997209349916318e-01, - 9.997206231343720e-01, 9.997205023448855e-01, 9.997205733480192e-01, 9.997208367389500e-01, 9.997212929810099e-01, - 9.997219424035817e-01, 9.997227852000825e-01, 9.997238214260302e-01, 9.997250509972079e-01, 9.997264736879269e-01, - 9.997280891294001e-01, 9.997298968082279e-01, 9.997318960650045e-01, 9.997340860930511e-01, 9.997364659372833e-01, - 9.997390344932165e-01, 9.997417905061193e-01, 9.997447325703143e-01, 9.997478591286405e-01, 9.997511684720751e-01, - 9.997546587395272e-01, 9.997583279177997e-01, 9.997621738417345e-01, 9.997661941945379e-01, 9.997703865082921e-01, - 9.997747481646605e-01, 9.997792763957843e-01, 9.997839682853786e-01, 9.997888207700281e-01, 9.997938306406862e-01, - 9.997989945443773e-01, 9.998043089861064e-01, 9.998097703309746e-01, 9.998153748065003e-01, 9.998211185051530e-01, - 9.998269973870870e-01, 9.998330072830846e-01, 9.998391438977015e-01, 9.998454028126147e-01, 9.998517794901678e-01, - 9.998582692771129e-01, 9.998648674085431e-01, 9.998715690120116e-01, 9.998783691118356e-01, 9.998852626335712e-01, - 9.998922444086656e-01, 9.998993091792668e-01, 9.999064516031954e-01, 9.999136662590593e-01, 9.999209476515181e-01, - 9.999282902166716e-01, 9.999356883275767e-01, 9.999431362998797e-01, 9.999506283975492e-01, 9.999581588387069e-01, - 9.999657218015426e-01, 9.999733114303028e-01, 9.999809218413399e-01, 9.999885471292198e-01, 9.999961813728609e-01, - 1.000003792553732e+00, 1.000011363835885e+00, 1.000018880862106e+00, 1.000026318501453e+00, 1.000033646597102e+00, - 1.000040828844329e+00, 1.000047821703262e+00, 1.000054573213544e+00, 1.000061021697840e+00, 1.000067094351168e+00, - 1.000072705715621e+00, 1.000077756041457e+00, 1.000082129536869e+00, 1.000085692509860e+00, 1.000088291406840e+00, - 1.000089750753633e+00, 1.000089871005573e+00, 1.000088426314299e+00, 1.000085162219593e+00, 1.000079793275302e+00, - 1.000072000618805e+00, 1.000061429493851e+00, 1.000047686736686e+00, 1.000030338235356e+00, 1.000008906371822e+00, - 9.999828674561138e-01, 9.999516491611377e-01, 9.999146279660260e-01, 9.998711266149775e-01, 9.998204115975446e-01, - 9.997616906551822e-01, 9.996941103176716e-01, 9.996167534717882e-01, 9.995286369633262e-01, 9.994287092323502e-01, - 9.993158479803570e-01, 9.991888578669340e-01, 9.990464682325365e-01, 9.988873308431691e-01, 9.987100176521666e-01, - 9.985130185738464e-01, 9.982947392636853e-01, 9.980534988998219e-01, 9.977875279611558e-01, 9.974949659981255e-01, - 9.971738593934303e-01, 9.968221591115168e-01, 9.964377184376065e-01, 9.960182907094022e-01, 9.955615270473709e-01, - 9.950649740926601e-01, 9.945260717652322e-01, 9.939421510586981e-01, 9.933104318925129e-01, 9.926280210466711e-01, - 9.918919102086680e-01, 9.910989741672799e-01, 9.902459691925082e-01, 9.893295316457497e-01, 9.883461768687914e-01, - 9.872922984044433e-01, 9.861641676054160e-01, 9.849579336912377e-01, 9.836696243155244e-01, 9.822951467075759e-01, - 9.808302894530008e-01, 9.792707249777252e-01, 9.776120127982821e-01, 9.758496035985741e-01, 9.739788441893990e-01, - 9.719949834018297e-01, 9.698931789591444e-01, 9.676685053644012e-01, 9.653159628320954e-01, 9.628304872826687e-01, - 9.602069614081798e-01, 9.574402268063275e-01, 9.545250971684157e-01, 9.514563724950412e-01, 9.482288543014010e-01, - 9.448373617624480e-01, 9.412767487368542e-01, 9.375419215980740e-01, 9.336278577909594e-01, 9.295296250234834e-01, - 9.252424009953755e-01, 9.207614935589523e-01, 9.160823612022024e-01, 9.112006337403594e-01, 9.061121330997502e-01, - 9.008128940766279e-01, 8.952991849539681e-01, 8.895675278607562e-01, 8.836147187609806e-01, 8.774378469633509e-01, - 8.710343140474714e-01, 8.644018521077256e-01, 8.575385412223282e-01, 8.504428260617042e-01, 8.431135315574496e-01, - 8.355498775604459e-01, 8.277514924241404e-01, 8.197184254564199e-01, 8.114511581907922e-01, 8.029506144346715e-01, - 7.942181690593274e-01, 7.852556555024425e-01, 7.760653719601955e-01, 7.666500862512726e-01, 7.570130393401874e-01, - 7.471579475117688e-01, 7.370890031926083e-01, 7.268108744186758e-01, 7.163287029512231e-01, 7.056481010455187e-01, - 6.947751468789124e-01, 6.837163786462801e-01, 6.724787873320510e-01, 6.610698081688499e-01, 6.494973107933384e-01, - 6.377695881101478e-01, 6.258953438749761e-01, 6.138836790079482e-01, 6.017440766483936e-01, 5.894863859622419e-01, - 5.771208047134243e-01, 5.646578606110257e-01, 5.521083914445795e-01, 5.394835240208723e-01, 5.267946519170417e-01, - 5.140534120666679e-01, 5.012716601980810e-01, 4.884614451472596e-01, 4.756349820716255e-01, 4.628046245957236e-01, - 4.499828359253513e-01, 4.371821589731387e-01, 4.244151855459629e-01, 4.116945246528834e-01, 3.990327700015137e-01, - 3.864424667608565e-01, 3.739360776795802e-01, 3.615259486603844e-01, 3.492242739034092e-01, 3.370430607443994e-01, - 3.249940943263768e-01, 3.130889022566745e-01, 3.013387194140940e-01, 2.897544530833894e-01, 2.783466486059465e-01, - 2.671254557460968e-01, 2.561005959816459e-01, 2.452813309345670e-01, 2.346764321630724e-01, 2.242941525391207e-01, - 2.141421994355449e-01, 2.042277099441413e-01, 1.945572283400477e-01, 1.851366859983997e-01, 1.759713839565222e-01, - 1.670659782987828e-01, 1.584244685217862e-01, 1.500501890149949e-01, 1.419458037663698e-01, 1.341133043745716e-01, - 1.265540114190599e-01, 1.192685792075560e-01, 1.122570038873269e-01, 1.055186348731866e-01, 9.905218951159138e-02, - 9.285577086735504e-02, 8.692688848791834e-02, 8.126248197036480e-02, 7.585894712900819e-02, 7.071216453687493e-02, - 6.581753019316379e-02, 6.116998805112477e-02, 5.676406412698673e-02, 5.259390190074066e-02, 4.865329871379729e-02, - 4.493574286675733e-02, 4.143445112264064e-02, 3.814240632671975e-02, 3.505239486333388e-02, 3.215704368240290e-02, - 2.944885664345253e-02, 2.692024994241165e-02, 2.456358640583462e-02, 2.237120845811709e-02, 2.033546958929542e-02, - 1.844876417374586e-02, 1.670355551314538e-02, 1.509240200007160e-02, 1.360798132128038e-02, 1.224311264172586e-02, - 1.099077673153155e-02, 9.844134018179273e-03, 8.796540564986736e-03, 7.841561994366898e-03, 6.972985390308479e-03, - 6.184829228925801e-03, 5.471351398766137e-03, 4.827055383826915e-03, 4.246694691940794e-03, 3.725275619368065e-03, - 3.258058449144477e-03, 2.840557186031939e-03, 2.468537934882437e-03, 2.138016031933214e-03, 1.845252040089026e-03, - 1.586746719704406e-03, 1.359235085846040e-03, 1.159679661583578e-03, 9.852630346169412e-04, 8.333798215882749e-04, - 7.016281408336979e-04, 5.878006901877478e-04, 4.898755218427234e-04, 4.060066012630820e-04, 3.345142318353532e-04, - 2.738754213664553e-04, 2.227142607936653e-04, 1.797923795997266e-04, 1.439995364945199e-04, 1.143443979841680e-04, - 8.994555154915584e-05, 7.002279434068894e-05, 5.388873262066439e-05, 4.094072165278127e-05, 3.065317043363458e-05, - 2.257023056170620e-05, 1.629888370183569e-05, 1.150243752713366e-05, 7.894435705240934e-06, 5.232983386684600e-06, - 3.315485520548709e-06, 1.973790197100917e-06, 1.069718110365652e-06, 4.909053882102472e-07, 1.462097501755241e-07, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, - 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; - - - -const LC3_FLOAT* MDCT_WINS_10ms[2][6] = { - {MDCT_WINDOW_80, MDCT_WINDOW_160, MDCT_WINDOW_240, MDCT_WINDOW_320, MDCT_WINDOW_480, NULL}, - {NULL, NULL, NULL, NULL, MDCT_HRA_WINDOW_480_10ms, MDCT_HRA_WINDOW_960_10ms}}; -const LC3_INT MDCT_la_zeroes[6] = {30, 60, 90, 120, 180, 360}; +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_2_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_20_e_8000, lpc_lin_pre_emphasis_40_e_16000, lpc_lin_pre_emphasis_60_e_24000, + lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_60_e_48000 +# ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_e_0_92 +#endif +}; -#ifdef CR8_G_ADD_75MS -const LC3_FLOAT* MDCT_WINS_7_5ms[2][6] = { - {MDCT_WINDOW_80_7_5ms, MDCT_WINDOW_160_7_5ms, MDCT_WINDOW_240_7_5ms, MDCT_WINDOW_320_7_5ms, MDCT_WINDOW_480_7_5ms, NULL}, - {NULL , NULL , NULL , NULL , MDCT_HRA_WINDOW_480_7_5ms, MDCT_HRA_WINDOW_960_7_5ms}}; -const LC3_INT32 MDCT_la_zeroes_7_5ms[6] = {14, 28, 42, 56, 84, 168}; +# ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_62[60] = { + 0x4a26, 0x4be4, 0x4f5d, 0x5490, 0x5b79, 0x6414, 0x6e59, 0x7a43, 0x43e4, 0x4b6f, 0x53bf, 0x5ccc, 0x6690, 0x7106, + 0x7c25, 0x43f3, 0x4a1f, 0x5095, 0x574e, 0x5e46, 0x6578, 0x6cdf, 0x7477, 0x7c39, 0x4210, 0x4613, 0x4a24, 0x4e3e, + 0x5260, 0x5686, 0x5aae, 0x5ed4, 0x62f6, 0x6710, 0x6b21, 0x6f24, 0x7318, 0x76f9, 0x7ac4, 0x7e78, 0x4109, 0x42c7, + 0x4475, 0x4612, 0x479d, 0x4915, 0x4a79, 0x4bc8, 0x4d01, 0x4e22, 0x4f2c, 0x501e, 0x50f6, 0x51b4, 0x5259, 0x52e2, + 0x5351, 0x53a4, 0x53dc, 0x53f8}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_62[60] = { + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_72[60] = { + 0x50c9, 0x54d4, 0x5ce6, 0x68f9, 0x7906, 0x4681, 0x526e, 0x6043, 0x6ff6, 0x40be, 0x4a65, 0x54e8, 0x6040, 0x6c65, + 0x794f, 0x437a, 0x4aa6, 0x5226, 0x59f5, 0x620c, 0x6a68, 0x7301, 0x7bd2, 0x426a, 0x4701, 0x4baa, 0x5062, 0x5526, + 0x59f2, 0x5ec4, 0x6397, 0x6869, 0x6d35, 0x71f9, 0x76b1, 0x7b5a, 0x7ff1, 0x4239, 0x446d, 0x4694, 0x48aa, 0x4ab0, + 0x4ca4, 0x4e84, 0x504f, 0x5204, 0x53a1, 0x5526, 0x5691, 0x57e1, 0x5916, 0x5a2e, 0x5b29, 0x5c07, 0x5cc5, 0x5d65, + 0x5de6, 0x5e46, 0x5e87, 0x5ea7}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_72[60] = { + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_82[60] = { + 0x4382, 0x4cb6, 0x5f17, 0x7a99, 0x4f94, 0x6656, 0x40c0, 0x5081, 0x6263, 0x7658, 0x4629, 0x5222, 0x5f0e, 0x6ce3, + 0x7b98, 0x4591, 0x4dbc, 0x5647, 0x5f2b, 0x6862, 0x71e7, 0x7bb2, 0x42de, 0x47ff, 0x4d39, 0x5288, 0x57e8, 0x5d55, + 0x62cc, 0x6849, 0x6dc8, 0x7345, 0x78bc, 0x7e29, 0x41c5, 0x446c, 0x4709, 0x499a, 0x4c1c, 0x4e8f, 0x50f0, 0x533e, + 0x5577, 0x579a, 0x59a4, 0x5b96, 0x5d6c, 0x5f27, 0x60c4, 0x6243, 0x63a3, 0x64e2, 0x6601, 0x66fd, 0x67d6, 0x688c, + 0x691e, 0x698c, 0x69d6, 0x69fb}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_82[60] = { + (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_92[60] = { + 0x7330, 0x62e5, 0x5ab1, 0x4c35, 0x753a, 0x5425, 0x72a0, 0x4afd, 0x5f0d, 0x7571, 0x470d, 0x547b, 0x62fa, 0x727f, + 0x4180, 0x4a38, 0x5362, 0x5cf7, 0x66f0, 0x7148, 0x7bf5, 0x4379, 0x491b, 0x4edc, 0x54b9, 0x5aae, 0x60b6, 0x66cd, + 0x6cee, 0x7316, 0x7941, 0x7f69, 0x42c5, 0x45d1, 0x48d4, 0x4bcf, 0x4ebd, 0x519e, 0x546f, 0x572e, 0x59d9, 0x5c6f, + 0x5eee, 0x6153, 0x639d, 0x65cb, 0x67dc, 0x69cc, 0x6b9c, 0x6d4a, 0x6ed4, 0x703b, 0x717c, 0x7296, 0x738a, 0x7457, + 0x74fb, 0x7576, 0x75c9, 0x75f2}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_92[60] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_7_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_60_0_62, lpc_lin_pre_emphasis_60_0_72, lpc_lin_pre_emphasis_60_0_82, + lpc_lin_pre_emphasis_80_0_92, lpc_lin_pre_emphasis_60_0_92 +# ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_0_92 +# endif + }; +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_7_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_60_e_0_62, lpc_lin_pre_emphasis_60_e_0_72, lpc_lin_pre_emphasis_60_e_0_82, + lpc_lin_pre_emphasis_80_e_0_92, lpc_lin_pre_emphasis_60_e_0_92 +# ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_e_0_92 +# endif + }; +# endif +# endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_8000[16] = {0x4000, 0x673f, 0x5348, 0x432d, 0x6c5f, 0x576a, + 0x4682, 0x71bf, 0x5bc0, 0x4a02, 0x7764, 0x604d, + 0x4dae, 0x7d50, 0x6514, 0x5188}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_8000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc}; +#else +#define lpc_warp_dee_emphasis_16_8000 NULL +#define lpc_warp_dee_emphasis_16_e_8000 NULL #endif -const LC3_FLOAT* MDCT_WINS_2_5ms[2][6] = { - {MDCT_WINDOW_80_2_5ms, MDCT_WINDOW_160_2_5ms, MDCT_WINDOW_240_2_5ms, MDCT_WINDOW_320_2_5ms, MDCT_WINDOW_480_2_5ms, - NULL}, - {NULL, NULL, NULL, NULL, MDCT_HRA_WINDOW_480_2_5ms, MDCT_HRA_WINDOW_960_2_5ms}}; -const LC3_INT MDCT_la_zeroes_2_5ms[6] = {0, 0, 0, 0, 0, 0}; +#ifdef SUBSET_WB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_16000[16] = {0x4000, 0x6119, 0x49a8, 0x6fc0, 0x54c5, 0x404e, + 0x618f, 0x4a02, 0x7048, 0x552c, 0x409c, 0x6206, + 0x4a5c, 0x70d0, 0x5594, 0x40eb}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_16000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffc, + (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffb}; +#else +#define lpc_warp_dee_emphasis_16_16000 NULL +#define lpc_warp_dee_emphasis_16_e_16000 NULL +#endif -const LC3_FLOAT* MDCT_WINS_5ms[2][6] = { - {MDCT_WINDOW_80_5ms, MDCT_WINDOW_160_5ms, MDCT_WINDOW_240_5ms, MDCT_WINDOW_320_5ms, MDCT_WINDOW_480_5ms, NULL}, - {NULL, NULL, NULL, NULL, MDCT_HRA_WINDOW_480_5ms, MDCT_HRA_WINDOW_960_5ms}}; -const LC3_INT MDCT_la_zeroes_5ms[6] = {10, 20, 30, 40, 60, 120}; +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_24000[16] = {0x4000, 0x5b51, 0x4125, 0x5cf3, 0x424f, 0x5e9c, + 0x437f, 0x604d, 0x44b4, 0x6206, 0x45ee, 0x63c7, + 0x472e, 0x658f, 0x4874, 0x6760}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_24000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffb, + (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfff9}; +#else +#define lpc_warp_dee_emphasis_16_24000 NULL +#define lpc_warp_dee_emphasis_16_e_24000 NULL +#endif -const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6] = {160, 320, 480, 640, 960, 1920}; /* Last 960 dummy */ +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_32000[16] = {0x4000, 0x55e1, 0x733b, 0x4d50, 0x67bd, 0x4599, + 0x5d64, 0x7d50, 0x5413, 0x70d0, 0x4bb0, 0x658f, + 0x4423, 0x5b6e, 0x7aaf, 0x524f}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_32000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffa, + (Word16)0xfffa, (Word16)0xfff9, (Word16)0xfff8, (Word16)0xfff8}; +#else +#define lpc_warp_dee_emphasis_16_32000 NULL +#define lpc_warp_dee_emphasis_16_e_32000 NULL +#endif -const LC3_INT MDCT_WINDOWS_LENGTHS_7_5ms[6] = {120, 240, 360, 480, 720, 1440}; /* Last 960 dummy */ +#ifdef SUBSET_FB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_48000[16] = {0x4000, 0x50c3, 0x65ea, 0x404e, 0x5126, 0x6666, + 0x409c, 0x5188, 0x66e3, 0x40eb, 0x51ec, 0x6760, + 0x413a, 0x524f, 0x67de, 0x4189}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_48000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfff9, + (Word16)0xfff9, (Word16)0xfff8, (Word16)0xfff7, (Word16)0xfff7}; +#else +#define lpc_warp_dee_emphasis_16_48000 NULL +#define lpc_warp_dee_emphasis_16_e_48000 NULL +#endif -const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6] = {80, 160, 240, 320, 480, 960}; +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_96000[16] = {0x4000, 0x4bf4, 0x5a23, 0x6af9, 0x7ef3, 0x4b54, + 0x5966, 0x6a18, 0x7de9, 0x4ab6, 0x58aa, 0x6939, + 0x7ce0, 0x4a19, 0x57f0, 0x685d}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_96000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfff9, (Word16)0xfff8, + (Word16)0xfff7, (Word16)0xfff7, (Word16)0xfff6, (Word16)0xfff5}; +# else +# define lpc_warp_dee_emphasis_16_96000 NULL +# define lpc_warp_dee_emphasis_16_e_96000 NULL +# endif + +RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis[NUM_SAMP_FREQ] = { + lpc_warp_dee_emphasis_16_8000, lpc_warp_dee_emphasis_16_16000, lpc_warp_dee_emphasis_16_24000, + lpc_warp_dee_emphasis_16_32000, lpc_warp_dee_emphasis_16_48000, lpc_warp_dee_emphasis_16_96000}; +RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis_e[NUM_SAMP_FREQ] = { + lpc_warp_dee_emphasis_16_e_8000, lpc_warp_dee_emphasis_16_e_16000, lpc_warp_dee_emphasis_16_e_24000, + lpc_warp_dee_emphasis_16_e_32000, lpc_warp_dee_emphasis_16_e_48000, lpc_warp_dee_emphasis_16_e_96000}; + +RAM_ALIGN const Word16 bands_nrg_scale[32] = {0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_offset_48000_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 25, + 27, 29, 31, 33, 36, 39, 42, 45, 48, 51, 55, 59, 63, 67, 72, 77, 83, 89, 95, 101, 108, 116, + 124, 133, 142, 152, 163, 174, 187, 200, 214, 229, 244, 262, 280, 299, 320, 343, 367, 392, 419, 449, 480}; -const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6] = {40, 80, 120, 160, 240, 480}; +RAM_ALIGN const Word16 bands_offset_96000_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, + 33, 36, 39, 42, 46, 50, 54, 59, 64, 69, 75, 82, 89, 96, 104, 113, 122, 132, 143, 155, 168, 181, + 196, 213, 230, 249, 270, 292, 316, 342, 371, 401, 434, 470, 509, 551, 596, 646, 699, 757, 819, 887, 960}; -/* Per band energy */ -const LC3_INT ACC_COEFF_PER_BAND_8[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, - 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 80}; +RAM_ALIGN const Word16 *const bands_offset_HR[2] = {bands_offset_48000_HR, bands_offset_96000_HR}; -const LC3_INT ACC_COEFF_PER_BAND_16[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 34, 36, 38, - 40, 42, 44, 46, 48, 50, 52, 55, 58, 61, 64, 67, 70, 73, 76, 80, 84, - 88, 92, 96, 101, 106, 111, 116, 121, 127, 133, 139, 146, 153, 160}; +RAM_ALIGN const Word16 bands_offset_48000_5ms_HR[56] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 21, 23, 25, 27, 29, 31, 33, 35, 38, 41, 44, 47, 50, 54, 58, 62, 66, 71, + 76, 81, 87, 93, 100, 107, 114, 122, 131, 140, 149, 160, 171, 183, 196, 209, 224, 240}; +RAM_ALIGN const Word16 bands_offset_96000_5ms_HR[59] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, + 23, 25, 27, 29, 31, 34, 37, 40, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 98, 106, + 115, 124, 135, 146, 158, 171, 185, 200, 217, 235, 254, 275, 298, 323, 349, 378, 409, 443, 480}; -const LC3_INT ACC_COEFF_PER_BAND_24[65] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 46, 49, 52, 55, 58, 61, 64, 68, 72, 76, - 80, 85, 90, 95, 100, 106, 112, 118, 125, 132, 139, 147, 155, 164, 173, 183, 193, 204, 215, 227, 240}; +RAM_ALIGN const Word16 *const bands_offset_5ms_HR[2] = {bands_offset_48000_5ms_HR, bands_offset_96000_5ms_HR}; -const LC3_INT ACC_COEFF_PER_BAND_32[65] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, - 24, 26, 28, 30, 32, 34, 36, 38, 41, 44, 47, 50, 53, 56, 60, 64, 68, 72, 76, 81, 86, 91, - 97, 103, 109, 116, 123, 131, 139, 148, 157, 166, 176, 187, 199, 211, 224, 238, 252, 268, 284, 302, 320}; +RAM_ALIGN const Word16 bands_offset_48000_2_5ms_HR[46] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 25, + 27, 29, 31, 33, 35, 37, 40, 43, 46, 49, 53, 57, 61, 65, 69, 74, 79, 85, 91, 97, 104, 112, 120}; +RAM_ALIGN const Word16 bands_offset_96000_2_5ms_HR[50] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32, + 35, 38, 41, 45, 49, 53, 57, 62, 67, 73, 79, 85, 92, 100, 108, 117, 127, 137, 149, 161, 174, 189, 204, 221, 240}; -const LC3_INT ACC_COEFF_PER_BAND_48[65] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, - 26, 28, 30, 32, 34, 36, 39, 42, 45, 48, 51, 55, 59, 63, 67, 71, 76, 81, 86, 92, 98, 105, - 112, 119, 127, 135, 144, 154, 164, 175, 186, 198, 211, 225, 240, 256, 273, 291, 310, 330, 352, 375, 400}; +RAM_ALIGN const Word16 *const bands_offset_2_5ms_HR[2] = {bands_offset_48000_2_5ms_HR, bands_offset_96000_2_5ms_HR}; -const LC3_INT ACC_COEFF_PER_BAND_8_2_5ms[21] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; +#ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 bands_offset_48000_7_5ms_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, + 26, 28, 30, 32, 34, 36, 38, 41, 44, 47, 50, 53, 56, 60, 64, 68, 73, 78, 83, 89, 95, 101, 108, + 115, 122, 130, 139, 148, 158, 168, 179, 191, 203, 217, 231, 246, 262, 279, 298, 317, 338, 360}; +RAM_ALIGN const Word16 bands_offset_96000_7_5ms_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, + 30, 32, 35, 38, 41, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 97, 105, 114, 123, 132, 143, 155, 167, + 180, 195, 210, 227, 245, 265, 286, 309, 334, 360, 389, 420, 454, 490, 529, 572, 617, 667, 720}; + +RAM_ALIGN const Word16 *const bands_offset_7_5ms_HR[2] = {bands_offset_48000_7_5ms_HR, bands_offset_96000_7_5ms_HR}; +# endif +#endif /* ENABLE_HR_MODE */ + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, + 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, + 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0033, 0x0035, + 0x0037, 0x0039, 0x003b, 0x003d, 0x003f, 0x0041, 0x0043, 0x0045, 0x0047, 0x0049, 0x004b, 0x004d, 0x0050}; +#else +#define bands_offset_8000_lpc_warp NULL +#endif -const LC3_INT ACC_COEFF_PER_BAND_16_2_5ms[36] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 32, 34, 36, 38, 40}; +#ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, + 0x001a, 0x001b, 0x001c, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030, + 0x0032, 0x0034, 0x0037, 0x003a, 0x003d, 0x0040, 0x0043, 0x0046, 0x0049, 0x004c, 0x0050, 0x0054, 0x0058, + 0x005c, 0x0060, 0x0065, 0x006a, 0x006f, 0x0074, 0x0079, 0x007f, 0x0085, 0x008b, 0x0092, 0x0099, 0x00a0}; +#else +#define bands_offset_16000_lpc_warp NULL +#endif -const LC3_INT ACC_COEFF_PER_BAND_24_2_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, - 30, 32, 34, 36, 38, 40, 42, 44, 47, 50, 53, 56, 60}; +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0019, 0x001b, + 0x001d, 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, 0x0031, 0x0034, 0x0037, 0x003a, + 0x003d, 0x0040, 0x0044, 0x0048, 0x004c, 0x0050, 0x0055, 0x005a, 0x005f, 0x0064, 0x006a, 0x0070, 0x0076, + 0x007d, 0x0084, 0x008b, 0x0093, 0x009b, 0x00a4, 0x00ad, 0x00b7, 0x00c1, 0x00cc, 0x00d7, 0x00e3, 0x00f0}; +#else +#define bands_offset_24000_lpc_warp NULL +#endif -const LC3_INT ACC_COEFF_PER_BAND_32_2_5ms[44] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, 30, 32, 34, - 36, 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, 71, 75, 80}; +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, + 0x0020, 0x0022, 0x0024, 0x0026, 0x0029, 0x002c, 0x002f, 0x0032, 0x0035, 0x0038, 0x003c, 0x0040, 0x0044, + 0x0048, 0x004c, 0x0051, 0x0056, 0x005b, 0x0061, 0x0067, 0x006d, 0x0074, 0x007b, 0x0083, 0x008b, 0x0094, + 0x009d, 0x00a6, 0x00b0, 0x00bb, 0x00c7, 0x00d3, 0x00e0, 0x00ee, 0x00fc, 0x010c, 0x011c, 0x012e, 0x0140}; +#else +#define bands_offset_32000_lpc_warp NULL +#endif -const LC3_INT ACC_COEFF_PER_BAND_48_2_5ms[45] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37, - 40, 43, 46, 49, 52, 56, 60, 64, 68, 72, 77, 82, 87, 93, 100}; +#ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0014, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, 0x0020, + 0x0022, 0x0024, 0x0027, 0x002a, 0x002d, 0x0030, 0x0033, 0x0037, 0x003b, 0x003f, 0x0043, 0x0047, 0x004c, + 0x0051, 0x0056, 0x005c, 0x0062, 0x0069, 0x0070, 0x0077, 0x007f, 0x0087, 0x0090, 0x009a, 0x00a4, 0x00af, + 0x00ba, 0x00c6, 0x00d3, 0x00e1, 0x00f0, 0x0100, 0x0111, 0x0123, 0x0136, 0x014a, 0x0160, 0x0177, 0x0190}; +#else +#define bands_offset_48000_lpc_warp NULL +#endif -const LC3_INT ACC_COEFF_PER_BAND_48_2_5ms_HR[46] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 40, 43, 46, - 49, 53, 57, 61, 65, 69, 74, 79, 85, 91, 97, 104, 112, 120}; -const LC3_INT ACC_COEFF_PER_BAND_96_2_5ms_HR[50] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32, - 35, 38, 41, 45, 49, 53, 57, 62, 67, 73, 79, 85, 92, 100, 108, 117, 127, 137, 149, 161, 174, 189, 204, 221, 240}; +#ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_lin[81] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, + 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050}; +#else +#define bands_offset_8000_lpc_lin NULL +#endif +#ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_lin[81] = { + 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 0x0010, 0x0012, 0x0014, 0x0016, 0x0018, 0x001a, + 0x001c, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030, 0x0032, 0x0034, 0x0036, + 0x0038, 0x003a, 0x003c, 0x003e, 0x0040, 0x0042, 0x0044, 0x0046, 0x0048, 0x004a, 0x004c, 0x004e, 0x0050, 0x0052, + 0x0054, 0x0056, 0x0058, 0x005a, 0x005c, 0x005e, 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007c, 0x007e, 0x0080, 0x0082, 0x0084, 0x0086, 0x0088, 0x008a, + 0x008c, 0x008e, 0x0090, 0x0092, 0x0094, 0x0096, 0x0098, 0x009a, 0x009c, 0x009e, 0x00a0}; +#else +#define bands_offset_16000_lpc_lin NULL +#endif -const LC3_INT ACC_COEFF_PER_BAND_8_5ms[40] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40}; - -const LC3_INT ACC_COEFF_PER_BAND_16_5ms[51] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 34, 36, - 38, 40, 42, 44, 46, 48, 50, 52, 54, 57, 60, 63, 66, 69, 72, 76, 80}; - -const LC3_INT ACC_COEFF_PER_BAND_24_5ms[53] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, - 30, 32, 34, 36, 38, 40, 42, 44, 47, 50, 53, 56, 59, 62, 65, 69, 73, 77, 81, 86, 91, 96, 101, 107, 113, 120}; - -const LC3_INT ACC_COEFF_PER_BAND_32_5ms[55] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 26, 28, 30, 32, - 34, 36, 38, 40, 42, 45, 48, 51, 54, 57, 61, 65, 69, 73, - 78, 83, 88, 93, 99, 105, 112, 119, 126, 134, 142, 151, 160}; -const LC3_INT ACC_COEFF_PER_BAND_48_5ms_HR[56] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 21, 23, 25, 27, 29, 31, 33, 35, - 38, 41, 44, 47, 50, 54, 58, 62, 66, 71, 76, 81, 87, 93, - 100, 107, 114, 122, 131, 140, 149, 160, 171, 183, 196, 209, 224, 240}; -const LC3_INT ACC_COEFF_PER_BAND_48_5ms[56] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 23, 25, 27, 29, 31, 33, - 35, 37, 40, 43, 46, 49, 52, 55, 59, 63, 67, 72, 77, 82, - 87, 93, 99, 105, 112, 120, 128, 136, 145, 155, 165, 176, 187, 200}; -const LC3_INT ACC_COEFF_PER_BAND_96_5ms_HR[59] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, - 23, 25, 27, 29, 31, 34, 37, 40, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 98, 106, - 115, 124, 135, 146, 158, 171, 185, 200, 217, 235, 254, 275, 298, 323, 349, 378, 409, 443, 480}; +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_lin[81] = { + 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, 0x0018, 0x001b, 0x001e, 0x0021, 0x0024, 0x0027, + 0x002a, 0x002d, 0x0030, 0x0033, 0x0036, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048, 0x004b, 0x004e, 0x0051, + 0x0054, 0x0057, 0x005a, 0x005d, 0x0060, 0x0063, 0x0066, 0x0069, 0x006c, 0x006f, 0x0072, 0x0075, 0x0078, 0x007b, + 0x007e, 0x0081, 0x0084, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, 0x0096, 0x0099, 0x009c, 0x009f, 0x00a2, 0x00a5, + 0x00a8, 0x00ab, 0x00ae, 0x00b1, 0x00b4, 0x00b7, 0x00ba, 0x00bd, 0x00c0, 0x00c3, 0x00c6, 0x00c9, 0x00cc, 0x00cf, + 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00de, 0x00e1, 0x00e4, 0x00e7, 0x00ea, 0x00ed, 0x00f0}; +#else +#define bands_offset_24000_lpc_lin NULL +#endif +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_lin[81] = { + 0x0000, 0x0004, 0x0008, 0x000c, 0x0010, 0x0014, 0x0018, 0x001c, 0x0020, 0x0024, 0x0028, 0x002c, 0x0030, 0x0034, + 0x0038, 0x003c, 0x0040, 0x0044, 0x0048, 0x004c, 0x0050, 0x0054, 0x0058, 0x005c, 0x0060, 0x0064, 0x0068, 0x006c, + 0x0070, 0x0074, 0x0078, 0x007c, 0x0080, 0x0084, 0x0088, 0x008c, 0x0090, 0x0094, 0x0098, 0x009c, 0x00a0, 0x00a4, + 0x00a8, 0x00ac, 0x00b0, 0x00b4, 0x00b8, 0x00bc, 0x00c0, 0x00c4, 0x00c8, 0x00cc, 0x00d0, 0x00d4, 0x00d8, 0x00dc, + 0x00e0, 0x00e4, 0x00e8, 0x00ec, 0x00f0, 0x00f4, 0x00f8, 0x00fc, 0x0100, 0x0104, 0x0108, 0x010c, 0x0110, 0x0114, + 0x0118, 0x011c, 0x0120, 0x0124, 0x0128, 0x012c, 0x0130, 0x0134, 0x0138, 0x013c, 0x0140}; +#else +#define bands_offset_32000_lpc_lin NULL +#endif -const LC3_INT ACC_COEFF_PER_BAND_48_HR[65] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 25, - 27, 29, 31, 33, 36, 39, 42, 45, 48, 51, 55, 59, 63, 67, 72, 77, 83, 89, 95, 101, 108, 116, - 124, 133, 142, 152, 163, 174, 187, 200, 214, 229, 244, 262, 280, 299, 320, 343, 367, 392, 419, 449, 480}; +#ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_lin[81] = { + 0x0000, 0x0006, 0x000c, 0x0012, 0x0018, 0x001e, 0x0024, 0x002a, 0x0030, 0x0036, 0x003c, 0x0042, 0x0048, 0x004e, + 0x0054, 0x005a, 0x0060, 0x0066, 0x006c, 0x0072, 0x0078, 0x007e, 0x0084, 0x008a, 0x0090, 0x0096, 0x009c, 0x00a2, + 0x00a8, 0x00ae, 0x00b4, 0x00ba, 0x00c0, 0x00c6, 0x00cc, 0x00d2, 0x00d8, 0x00de, 0x00e4, 0x00ea, 0x00f0, 0x00f6, + 0x00fc, 0x0102, 0x0108, 0x010e, 0x0114, 0x011a, 0x0120, 0x0126, 0x012c, 0x0132, 0x0138, 0x013e, 0x0144, 0x014a, + 0x0150, 0x0156, 0x015c, 0x0162, 0x0168, 0x016e, 0x0174, 0x017a, 0x0180, 0x0186, 0x018c, 0x0192, 0x0198, 0x019e, + 0x01a4, 0x01aa, 0x01b0, 0x01b6, 0x01bc, 0x01c2, 0x01c8, 0x01ce, 0x01d4, 0x01da, 0x01e0}; +#else +#define bands_offset_48000_lpc_lin NULL +#endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_5ms[40] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0028}; +#else +#define bands_offset_8000_lpc_warp_5ms NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_5ms[51] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, + 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, + 0x0030, 0x0032, 0x0034, 0x0036, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048, 0x004c, 0x0050}; +#else +#define bands_offset_16000_lpc_warp_5ms NULL +#endif -const LC3_INT ACC_COEFF_PER_BAND_96_HR[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 33, 36, 39, 42, 46, 50, 54, 59, 64, 69, 75, 82, 89, 96, 104, 113, 122, 132, 143, 155, 168, 181, 196, 213, 230, 249, 270, 292, 316, 342, 371, 401, 434, 470, 509, 551, 596, 646, 699, 757, 819, 887, 960}; +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_5ms[53] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x001a, 0x001c, 0x001e, + 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002f, 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, + 0x0045, 0x0049, 0x004d, 0x0051, 0x0056, 0x005b, 0x0060, 0x0065, 0x006b, 0x0071, 0x0078}; +#else +#define bands_offset_24000_lpc_warp_5ms NULL +#endif -const LC3_INT* ACC_COEFF_PER_BAND_HR[6] = {NULL, NULL, NULL, NULL, ACC_COEFF_PER_BAND_48_HR, ACC_COEFF_PER_BAND_96_HR}; +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_5ms[55] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, 0x0020, + 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002d, 0x0030, 0x0033, 0x0036, 0x0039, 0x003d, 0x0041, 0x0045, 0x0049, + 0x004e, 0x0053, 0x0058, 0x005d, 0x0063, 0x0069, 0x0070, 0x0077, 0x007e, 0x0086, 0x008e, 0x0097, 0x00a0}; +#else +#define bands_offset_32000_lpc_warp_5ms NULL +#endif -const LC3_INT* ACC_COEFF_PER_BAND[6] = {ACC_COEFF_PER_BAND_8, ACC_COEFF_PER_BAND_16, ACC_COEFF_PER_BAND_24, - ACC_COEFF_PER_BAND_32, ACC_COEFF_PER_BAND_48, NULL}; +#ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_5ms[56] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0017, 0x0019, 0x001b, 0x001d, 0x001f, 0x0021, + 0x0023, 0x0025, 0x0028, 0x002b, 0x002e, 0x0031, 0x0034, 0x0037, 0x003b, 0x003f, 0x0043, 0x0048, 0x004d, 0x0052, + 0x0057, 0x005d, 0x0063, 0x0069, 0x0070, 0x0078, 0x0080, 0x0088, 0x0091, 0x009b, 0x00a5, 0x00b0, 0x00bb, 0x00c8}; +#else +#define bands_offset_48000_lpc_warp_5ms NULL +#endif -const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6] = { - NULL, NULL, NULL, NULL, ACC_COEFF_PER_BAND_48_2_5ms_HR, ACC_COEFF_PER_BAND_96_2_5ms_HR}; -const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5] = {ACC_COEFF_PER_BAND_8_2_5ms, ACC_COEFF_PER_BAND_16_2_5ms, - ACC_COEFF_PER_BAND_24_2_5ms, ACC_COEFF_PER_BAND_32_2_5ms, - ACC_COEFF_PER_BAND_48_2_5ms}; +#ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_2_5ms[21] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; +#else +#define bands_offset_8000_lpc_warp_2_5ms NULL +#endif +#ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_2_5ms[36] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 32, 34, 36, 38, 40}; +#else +#define bands_offset_16000_lpc_warp_2_5ms NULL +#endif -const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6] = { - NULL, NULL, NULL, NULL, ACC_COEFF_PER_BAND_48_5ms_HR, ACC_COEFF_PER_BAND_96_5ms_HR}; +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_2_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, 47, 50, 53, 56, 60}; +#else +#define bands_offset_24000_lpc_warp_2_5ms NULL +#endif -const LC3_INT* ACC_COEFF_PER_BAND_5ms[5] = {ACC_COEFF_PER_BAND_8_5ms, ACC_COEFF_PER_BAND_16_5ms, - ACC_COEFF_PER_BAND_24_5ms, ACC_COEFF_PER_BAND_32_5ms, - ACC_COEFF_PER_BAND_48_5ms}; +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_2_5ms[44] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, 71, 75, 80}; +#else +#define bands_offset_32000_lpc_warp_2_5ms NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_2_5ms[45] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, + 25, 27, 29, 31, 33, 35, 37, 40, 43, 46, 49, 52, 56, 60, 64, 68, 72, 77, 82, 87, 93, 100}; +#else +#define bands_offset_48000_lpc_warp_2_5ms NULL +#endif + + + +RAM_ALIGN const Word16 *const bands_offset[6] = {bands_offset_8000_lpc_warp, bands_offset_16000_lpc_warp, + bands_offset_24000_lpc_warp, bands_offset_32000_lpc_warp, + bands_offset_48000_lpc_warp, NULL}; #ifdef CR8_G_ADD_75MS -const LC3_INT ACC_COEFF_PER_BAND_8_7_5ms[61] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}; +RAM_ALIGN const Word16 bands_offset_with_one_max_7_5ms[NUM_OFFSETS] = {60, 34, 27, 24, 22 +# ifdef ENABLE_HR_MODE + , 20, 16 +# endif +}; +RAM_ALIGN const Word16 bands_offset_with_two_max_7_5ms[NUM_OFFSETS] = {0, 48, 38, 33, 31 +# ifdef ENABLE_HR_MODE + , 29, 24 +# endif +}; +# endif + +RAM_ALIGN const Word16 bands_offset_with_one_max[NUM_OFFSETS] = {49, 28, 23, 20, 18 +# ifdef ENABLE_HR_MODE + , 17, 12 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max[NUM_OFFSETS] = {63, 40, 33, 29, 27 +# ifdef ENABLE_HR_MODE + , 25, 21 +# endif + }; + +RAM_ALIGN const Word16 *const bands_offset_5ms[6] = {bands_offset_8000_lpc_warp_5ms, bands_offset_16000_lpc_warp_5ms, + bands_offset_24000_lpc_warp_5ms, bands_offset_32000_lpc_warp_5ms, + bands_offset_48000_lpc_warp_5ms, NULL}; +RAM_ALIGN const Word16 bands_offset_with_one_max_5ms[NUM_OFFSETS] = {38, 30, 24, 22, 21 +# ifdef ENABLE_HR_MODE + , 19, 17 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_5ms[NUM_OFFSETS] = {39, 42, 34, 32, 29 +# ifdef ENABLE_HR_MODE + , 27, 24 +# endif + }; -const LC3_INT ACC_COEFF_PER_BAND_16_7_5ms[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 65, 68, - 71, 74, 77, 80, 83, 86, 90, 94, 98, 102, 106, 110, 115, 120}; +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_number_7_5ms [] = {60, 64, 64, 64, 64, 64}; +# else +RAM_ALIGN const Word16 bands_number_7_5ms [] = {60, 64, 64, 64, 64}; +# endif +#endif + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ] = {39, 50, 52, 54, 55, 58}; +#else +RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ] = {39, 50, 52, 54, 55}; +#endif + +RAM_ALIGN const Word16 *const bands_offset_2_5ms[6] = { + bands_offset_8000_lpc_warp_2_5ms, bands_offset_16000_lpc_warp_2_5ms, bands_offset_24000_lpc_warp_2_5ms, + bands_offset_32000_lpc_warp_2_5ms, bands_offset_48000_lpc_warp_2_5ms, NULL}; + +RAM_ALIGN const Word16 bands_offset_with_one_max_2_5ms[NUM_OFFSETS] = {20, 30, 26, 24, 21 +# ifdef ENABLE_HR_MODE + , 19, 16 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_2_5ms[NUM_OFFSETS] = {20, 35, 35, 32, 29 +# ifdef ENABLE_HR_MODE + , 28, 24 +# endif + }; + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_number_2_5ms_HR[] = {20, 35, 40, 43, 45, 49}; +RAM_ALIGN const Word16 bands_number_2_5ms [] = {20, 35, 40, 43, 44, 49}; +# else +RAM_ALIGN const Word16 bands_number_2_5ms [] = {20, 35, 40, 43, 44}; +# endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_offset_96000_lpc_lin[81] = +{ + 0x0000, 0x000c, 0x0018, 0x0024, 0x0030, 0x003c, 0x0048, 0x0054, 0x0060, 0x006c, 0x0078, 0x0084, 0x0090, 0x009c, + 0x00a8, 0x00b4, 0x00c0, 0x00cc, 0x00d8, 0x00e4, 0x00f0, 0x00fc, 0x0108, 0x0114, 0x0120, 0x012c, 0x0138, 0x0144, + 0x0150, 0x015c, 0x0168, 0x0174, 0x0180, 0x018c, 0x0198, 0x01a4, 0x01b0, 0x01bc, 0x01c8, 0x01d4, 0x01e0, 0x01ec, + 0x01f8, 0x0204, 0x0210, 0x021c, 0x0228, 0x0234, 0x0240, 0x024c, 0x0258, 0x0264, 0x0270, 0x027c, 0x0288, 0x0294, + 0x02a0, 0x02ac, 0x02b8, 0x02c4, 0x02d0, 0x02dc, 0x02e8, 0x02f4, 0x0300, 0x030c, 0x0318, 0x0324, 0x0330, 0x033c, + 0x0348, 0x0354, 0x0360, 0x036c, 0x0378, 0x0384, 0x0390, 0x039c, 0x03a8, 0x03b4, 0x03c0 +}; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 bands_offset_96000_lpc_lin_7_5ms[81] = +{ + 0x0000, 0x0009, 0x0012, 0x001b, 0x0024, 0x002d, 0x0036, 0x003f, 0x0048, 0x0051, 0x005a, 0x0063, 0x006c, 0x0075, + 0x007e, 0x0087, 0x0090, 0x0099, 0x00a2, 0x00ab, 0x00b4, 0x00bd, 0x00c6, 0x00cf, 0x00d8, 0x00e1, 0x00ea, 0x00f3, + 0x00fc, 0x0105, 0x010e, 0x0117, 0x0120, 0x0129, 0x0132, 0x013b, 0x0144, 0x014d, 0x0156, 0x015f, 0x0168, 0x0171, + 0x017a, 0x0183, 0x018c, 0x0195, 0x019e, 0x01a7, 0x01b0, 0x01b9, 0x01c2, 0x01cb, 0x01d4, 0x01dd, 0x01e6, 0x01ef, + 0x01f8, 0x0201, 0x020a, 0x0213, 0x021c, 0x0225, 0x022e, 0x0237, 0x0240, 0x0249, 0x0252, 0x025b, 0x0264, 0x026d, + 0x0276, 0x027f, 0x0288, 0x0291, 0x029a, 0x02a3, 0x02ac, 0x02b5, 0x02be, 0x02c7, 0x02d0 +}; +# endif +# endif + + +RAM_ALIGN const Word16 *const bands_offset_lin[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_16000_lpc_lin, + bands_offset_24000_lpc_lin, bands_offset_32000_lpc_lin, + bands_offset_48000_lpc_lin +# ifdef ENABLE_HR_MODE + , bands_offset_96000_lpc_lin +# endif + }; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 *const bands_offset_lin_7_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_16000_lpc_lin, + bands_offset_24000_lpc_lin, bands_offset_24000_lpc_lin, + bands_offset_48000_lpc_lin +# ifdef ENABLE_HR_MODE + , bands_offset_96000_lpc_lin_7_5ms +# endif + }; +# endif + +RAM_ALIGN const Word16 *const bands_offset_lin_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin, + bands_offset_24000_lpc_lin, bands_offset_16000_lpc_lin, + bands_offset_24000_lpc_lin +# ifdef ENABLE_HR_MODE + , bands_offset_48000_lpc_lin +# endif + }; +RAM_ALIGN const Word16 *const bands_offset_lin_2_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin, + bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin, + bands_offset_16000_lpc_lin +# ifdef ENABLE_HR_MODE + , bands_offset_24000_lpc_lin +# endif + }; + +RAM_ALIGN const Word16 bands_offset_with_one_max_lin[NUM_SAMP_FREQ] = {80, 0, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_lin[NUM_SAMP_FREQ] = {0, 80, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 bands_offset_with_one_max_lin_7_5ms[NUM_SAMP_FREQ] = {60, 0, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; + +RAM_ALIGN const Word16 bands_offset_with_two_max_lin_7_5ms[NUM_SAMP_FREQ] = {0, 60, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +#endif -const LC3_INT ACC_COEFF_PER_BAND_24_7_5ms[65] = { +RAM_ALIGN const Word16 bands_offset_with_one_max_lin_5ms[NUM_SAMP_FREQ] = {40, 80, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_lin_5ms[NUM_SAMP_FREQ] = {0, 0, 0, 80, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_one_max_lin_2_5ms[NUM_SAMP_FREQ] = {20, 40, 60, 80, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_lin_2_5ms[NUM_SAMP_FREQ] = {0, 0, 0, 0, 60 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +#ifdef CR8_G_ADD_75MS +# ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_7_5ms[61] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}; +# else +# define bands_offset_8000_lpc_warp_7_5ms NULL +# endif + +# ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_7_5ms[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, + 54, 56, 58, 60, 62, 65, 68, 71, 74, 77, 80, 83, 86, 90, 94, 98, 102, 106, 110, 115, 120}; +# else +# define bands_offset_16000_lpc_warp_7_5ms NULL +# endif + +# ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_7_5ms[65] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 52, 55, 58, 61, 64, 67, 70, 74, 78, 82, 86, 90, 95, 100, 105, 110, 115, 121, 127, 134, 141, 148, 155, 163, 171, 180}; +# else +# define bands_offset_24000_lpc_warp_7_5ms NULL +# endif -const LC3_INT ACC_COEFF_PER_BAND_32_7_5ms[65] = { +# ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_7_5ms[65] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 45, 48, 51, 54, 57, 60, 63, 67, 71, 75, 79, 84, 89, 94, 99, 105, 111, 117, 124, 131, 138, 146, 154, 163, 172, 182, 192, 203, 215, 227, 240}; +# else +# define bands_offset_32000_lpc_warp_7_5ms NULL +# endif -const LC3_INT ACC_COEFF_PER_BAND_48_7_5ms[65] = { +# ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_7_5ms[65] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, 71, 75, 80, 85, 90, 96, 102, 108, 115, 122, 129, 137, 146, 155, 165, 175, 186, 197, 209, 222, 236, 251, 266, 283, 300}; - -const LC3_INT ACC_COEFF_PER_BAND_48_7_5ms_HR[65] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, - 24, 26, 28, 30, 32, 34, 36, 38, 41, 44, 47, 50, 53, 56, 60, 64, 68, 73, 78, 83, 89, 95, - 101, 108, 115, 122, 130, 139, 148, 158, 168, 179, 191, 203, 217, 231, 246, 262, 279, 298, 317, 338, 360}; - -const LC3_INT ACC_COEFF_PER_BAND_96_7_5ms_HR[65] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, - 24, 26, 28, 30, 32, 35, 38, 41, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 97, 105, - 114, 123, 132, 143, 155, 167, 180, 195, 210, 227, 245, 265, 286, 309, 334, 360, 389, 420, 454, 490, - 529, 572, 617, 667, 720}; - -const LC3_INT* ACC_COEFF_PER_BAND_7_5ms_HR[6] = {NULL, NULL, - NULL, NULL, - ACC_COEFF_PER_BAND_48_7_5ms_HR, ACC_COEFF_PER_BAND_96_7_5ms_HR}; - -const LC3_INT* ACC_COEFF_PER_BAND_7_5ms[5] = {ACC_COEFF_PER_BAND_8_7_5ms , ACC_COEFF_PER_BAND_16_7_5ms, - ACC_COEFF_PER_BAND_24_7_5ms, ACC_COEFF_PER_BAND_32_7_5ms, - ACC_COEFF_PER_BAND_48_7_5ms}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_8_7_5ms[61] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_16_7_5ms[61] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, - 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, - 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_24_7_5ms[61] = { - 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, - 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, - 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_32_7_5ms[81] = { - 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, - 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, - 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, - 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_48_7_5ms[61] = { - 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, - 126, 132, 138, 144, 150, 156, 162, 168, 174, 180, 186, 192, 198, 204, 210, 216, 222, 228, 234, 240, 246, - 252, 258, 264, 270, 276, 282, 288, 294, 300, 306, 312, 318, 324, 330, 336, 342, 348, 354, 360}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_96_7_5ms[81] = { - 0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135, 144, 153, 162, 171, 180, - 189, 198, 207, 216, 225, 234, 243, 252, 261, 270, 279, 288, 297, 306, 315, 324, 333, 342, 351, 360, 369, - 378, 387, 396, 405, 414, 423, 432, 441, 450, 459, 468, 477, 486, 495, 504, 513, 522, 531, 540, 549, 558, - 567, 576, 585, 594, 603, 612, 621, 630, 639, 648, 657, 666, 675, 684, 693, 702, 711, 720}; - -const LC3_INT* ACC_COEFF_PER_BAND_PLC_7_5ms[] = { - ACC_COEFF_PER_BAND_PLC_8_7_5ms, ACC_COEFF_PER_BAND_PLC_16_7_5ms, ACC_COEFF_PER_BAND_PLC_24_7_5ms, - ACC_COEFF_PER_BAND_PLC_32_7_5ms, ACC_COEFF_PER_BAND_PLC_48_7_5ms, ACC_COEFF_PER_BAND_PLC_96_7_5ms}; +# else +# define bands_offset_48000_lpc_warp_7_5ms NULL +# endif + +RAM_ALIGN const Word16 *const bands_offset_7_5ms[5] = { + bands_offset_8000_lpc_warp_7_5ms, bands_offset_16000_lpc_warp_7_5ms, bands_offset_24000_lpc_warp_7_5ms, + bands_offset_32000_lpc_warp_7_5ms, bands_offset_48000_lpc_warp_7_5ms}; +# endif /* ifdef CR8_G_ADD_75MS */ + +RAM_ALIGN const Word32 inv_odft_twiddle_80_re[M] = { + 0x7ff9af04, 0x7fe6bcb0, 0x7fc72ae2, 0x7f9afcb9, 0x7f62368f, 0x7f1cde01, 0x7ecaf9e5, 0x7e6c9251, + 0x7e01b096, 0x7d8a5f40, 0x7d06aa16, 0x7c769e18, 0x7bda497d, 0x7b31bbb2, 0x7a7d055b, 0x79bc384d}; + +RAM_ALIGN const Word32 inv_odft_twiddle_80_im[M] = { + 0x02835b5a, 0x05067734, 0x07891418, 0x0a0af299, 0x0c8bd35e, 0x0f0b7727, 0x11899ed3, 0x14060b68, + 0x16807e15, 0x18f8b83c, 0x1b6e7b7a, 0x1de189a6, 0x2051a4dd, 0x22be8f87, 0x25280c5e, 0x278dde6e}; + +RAM_ALIGN const Word32 inv_odft_twiddle_60_re[16] = { + 0x7ff4c56f, 0x7fd317b4, 0x7f9afcb9, 0x7f4c7e54, 0x7ee7aa4c, 0x7e6c9251, 0x7ddb4bfc, 0x7d33f0ca, + 0x7c769e18, 0x7ba3751d, 0x7aba9ae6, 0x79bc384d, 0x78a879f4, 0x777f903c, 0x7641af3d, 0x74ef0ebc}; + +RAM_ALIGN const Word32 inv_odft_twiddle_60_im[16] = { + 0x0359c428, 0x06b2f1d2, 0x0a0af299, 0x0d61304e, 0x10b5150f, 0x14060b68, 0x17537e63, 0x1a9cd9ac, + 0x1de189a6, 0x2120fb83, 0x245a9d65, 0x278dde6e, 0x2aba2ee4, 0x2ddf0040, 0x30fbc54d, 0x340ff242}; + +RAM_ALIGN const Word32 inv_odft_twiddle_40_re[16] = { + 0x7fe6bcb0, 0x7f9afcb9, 0x7f1cde01, 0x7e6c9251, 0x7d8a5f40, 0x7c769e18, 0x7b31bbb2, 0x79bc384d, + 0x7816a759, 0x7641af3d, 0x743e0918, 0x720c8075, 0x6fadf2fc, 0x6d23501b, 0x6a6d98a4, 0x678dde6e}; + +RAM_ALIGN const Word32 inv_odft_twiddle_40_im[16] = { + 0x05067734, 0x0a0af299, 0x0f0b7727, 0x14060b68, 0x18f8b83c, 0x1de189a6, 0x22be8f87, 0x278dde6e, + 0x2c4d9050, 0x30fbc54d, 0x3596a46c, 0x3a1c5c57, 0x3e8b240e, 0x42e13ba4, 0x471cece7, 0x4b3c8c12}; + +RAM_ALIGN const Word32 inv_odft_twiddle_20_re[16] = { + 0x7f9afcb9, 0x7e6c9251, 0x7c769e18, 0x79bc384d, 0x7641af3d, 0x720c8075, 0x6d23501b, 0x678dde6e, + 0x6154fb91, 0x5a82799a, 0x53211d18, 0x4b3c8c12, 0x42e13ba4, 0x3a1c5c57, 0x30fbc54d, 0x278dde6e}; + +RAM_ALIGN const Word32 inv_odft_twiddle_20_im[16] = { + 0x0a0af299, 0x14060b68, 0x1de189a6, 0x278dde6e, 0x30fbc54d, 0x3a1c5c57, 0x42e13ba4, 0x4b3c8c12, + 0x53211d18, 0x5a82799a, 0x6154fb91, 0x678dde6e, 0x6d23501b, 0x720c8075, 0x7641af3d, 0x79bc384d}; + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 resamp_filt_8k[240] = { + 214, 417, -1052, -4529, 26233, -4529, -1052, 417, 214, 0, 212, 277, -1281, -3928, 26037, -4979, + -755, 550, 206, -8, 200, 136, -1439, -3214, 25456, -5243, -401, 668, 187, -18, 180, 0, + -1522, -2427, 24506, -5289, 0, 763, 156, -28, 154, -125, -1534, -1605, 23211, -5090, 432, 831, + 114, -39, 124, -234, -1478, -785, 21609, -4626, 877, 865, 61, -50, 92, -323, -1361, 0, + 19741, -3885, 1317, 861, 0, -61, 60, -391, -1194, 720, 17658, -2863, 1729, 815, -68, -69, + 29, -436, -987, 1351, 15414, -1563, 2093, 727, -140, -76, 0, -457, -752, 1873, 13068, 0, + 2389, 598, -213, -79, -25, -457, -501, 2274, 10677, 1803, 2597, 430, -282, -77, -46, -436, + -247, 2545, 8302, 3815, 2700, 229, -345, -72, -61, -398, 0, 2686, 5997, 5997, 2686, 0, + -398, -61, -72, -345, 229, 2700, 3815, 8302, 2545, -247, -436, -46, -77, -282, 430, 2597, + 1803, 10677, 2274, -501, -457, -25, -79, -213, 598, 2389, 0, 13068, 1873, -752, -457, 0, + -76, -140, 727, 2093, -1563, 15414, 1351, -987, -436, 29, -69, -68, 815, 1729, -2863, 17658, + 720, -1194, -391, 60, -61, 0, 861, 1317, -3885, 19741, 0, -1361, -323, 92, -50, 61, + 865, 877, -4626, 21609, -785, -1478, -234, 124, -39, 114, 831, 432, -5090, 23211, -1605, -1534, + -125, 154, -28, 156, 763, 0, -5289, 24506, -2427, -1522, 0, 180, -18, 187, 668, -401, + -5243, 25456, -3214, -1439, 136, 200, -8, 206, 550, -755, -4979, 26037, -3928, -1281, 277, 212}; +#else +#define resamp_filt_8k NULL #endif -/* Near Nyquist detector */ -const LC3_INT NN_thresh = 30; -/* Tone detector */ -#ifdef CR8_E_TONE_DETECTOR -const LC3_INT32 TD_HR_thresh_10ms = 83402; -const LC3_INT32 TD_HR_thresh_7_5ms = 743496; -const LC3_INT32 TD_HR_thresh_5ms = 382564; -const LC3_INT32 TD_HR_thresh_2_5ms = 301695; -#endif // CR8_E_TONE_DETECTOR +#ifdef SUBSET_WB +RAM_ALIGN const Word16 resamp_filt_16k[240] = { + -61, 214, -398, 417, 0, -1052, 2686, -4529, 5997, 26233, 5997, -4529, 2686, -1052, 0, 417, + -398, 214, -61, 0, -72, 212, -345, 277, 229, -1281, 2700, -3928, 3815, 26037, 8302, -4979, + 2545, -755, -247, 550, -436, 206, -46, -8, -77, 200, -282, 136, 430, -1439, 2597, -3214, + 1803, 25456, 10677, -5243, 2274, -401, -501, 668, -457, 187, -25, -18, -79, 180, -213, 0, + 598, -1522, 2389, -2427, 0, 24506, 13068, -5289, 1873, 0, -752, 763, -457, 156, 0, -28, + -76, 154, -140, -125, 727, -1534, 2093, -1605, -1563, 23211, 15414, -5090, 1351, 432, -987, 831, + -436, 114, 29, -39, -69, 124, -68, -234, 815, -1478, 1729, -785, -2863, 21609, 17658, -4626, + 720, 877, -1194, 865, -391, 61, 60, -50, -61, 92, 0, -323, 861, -1361, 1317, 0, + -3885, 19741, 19741, -3885, 0, 1317, -1361, 861, -323, 0, 92, -61, -50, 60, 61, -391, + 865, -1194, 877, 720, -4626, 17658, 21609, -2863, -785, 1729, -1478, 815, -234, -68, 124, -69, + -39, 29, 114, -436, 831, -987, 432, 1351, -5090, 15414, 23211, -1563, -1605, 2093, -1534, 727, + -125, -140, 154, -76, -28, 0, 156, -457, 763, -752, 0, 1873, -5289, 13068, 24506, 0, + -2427, 2389, -1522, 598, 0, -213, 180, -79, -18, -25, 187, -457, 668, -501, -401, 2274, + -5243, 10677, 25456, 1803, -3214, 2597, -1439, 430, 136, -282, 200, -77, -8, -46, 206, -436, + 550, -247, -755, 2545, -4979, 8302, 26037, 3815, -3928, 2700, -1281, 229, 277, -345, 212, -72}; +#else +#define resamp_filt_16k NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 resamp_filt_24k[240] = { + -50, 19, 143, -93, -290, 278, 485, -658, -701, 1396, 901, -3019, -1042, 10276, 17488, 10276, + -1042, -3019, 901, 1396, -701, -658, 485, 278, -290, -93, 143, 19, -50, 0, -46, 0, + 141, -45, -305, 185, 543, -501, -854, 1153, 1249, -2619, -1908, 8712, 17358, 11772, 0, -3319, + 480, 1593, -504, -796, 399, 367, -261, -142, 138, 40, -52, -5, -41, -17, 133, 0, + -304, 91, 574, -334, -959, 878, 1516, -2143, -2590, 7118, 16971, 13161, 1202, -3495, 0, 1731, + -267, -908, 287, 445, -215, -188, 125, 62, -52, -12, -34, -30, 120, 41, -291, 0, + 577, -164, -1015, 585, 1697, -1618, -3084, 5534, 16337, 14406, 2544, -3526, -523, 1800, 0, -985, + 152, 509, -156, -230, 104, 83, -48, -19, -26, -41, 103, 76, -265, -83, 554, 0, + -1023, 288, 1791, -1070, -3393, 3998, 15474, 15474, 3998, -3393, -1070, 1791, 288, -1023, 0, 554, + -83, -265, 76, 103, -41, -26, -19, -48, 83, 104, -230, -156, 509, 152, -985, 0, + 1800, -523, -3526, 2544, 14406, 16337, 5534, -3084, -1618, 1697, 585, -1015, -164, 577, 0, -291, + 41, 120, -30, -34, -12, -52, 62, 125, -188, -215, 445, 287, -908, -267, 1731, 0, + -3495, 1202, 13161, 16971, 7118, -2590, -2143, 1516, 878, -959, -334, 574, 91, -304, 0, 133, + -17, -41, -5, -52, 40, 138, -142, -261, 367, 399, -796, -504, 1593, 480, -3319, 0, + 11772, 17358, 8712, -1908, -2619, 1249, 1153, -854, -501, 543, 185, -305, -45, 141, 0, -46}; +#else +#define resamp_filt_24k NULL +#endif -const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 }; +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 resamp_filt_32k[240] = { + -30, -31, 46, 107, 0, -199, -162, 209, 430, 0, -681, -526, 658, 1343, 0, -2264, + -1943, 2999, 9871, 13116, 9871, 2999, -1943, -2264, 0, 1343, 658, -526, -681, 0, 430, 209, + -162, -199, 0, 107, 46, -31, -30, 0, -25, -36, 30, 106, 31, -173, -195, 139, + 432, 114, -597, -641, 439, 1350, 360, -1964, -2313, 1908, 8829, 13019, 10804, 4151, -1431, -2489, + -393, 1273, 864, -378, -739, -123, 408, 275, -117, -218, -34, 103, 62, -23, -35, -4, + -20, -39, 14, 100, 57, -141, -218, 68, 416, 215, -494, -719, 216, 1298, 676, -1607, + -2545, 902, 7707, 12728, 11606, 5339, -781, -2621, -803, 1137, 1047, -200, -767, -251, 364, 334, + -62, -228, -70, 94, 77, -13, -38, -9, -14, -39, 0, 90, 78, -106, -229, 0, + 382, 299, -376, -761, 0, 1194, 937, -1214, -2644, 0, 6534, 12253, 12253, 6534, 0, -2644, + -1214, 937, 1194, 0, -761, -376, 299, 382, 0, -229, -106, 78, 90, 0, -39, -14, + -9, -38, -13, 77, 94, -70, -228, -62, 334, 364, -251, -767, -200, 1047, 1137, -803, + -2621, -781, 5339, 11606, 12728, 7707, 902, -2545, -1607, 676, 1298, 216, -719, -494, 215, 416, + 68, -218, -141, 57, 100, 14, -39, -20, -4, -35, -23, 62, 103, -34, -218, -117, + 275, 408, -123, -739, -378, 864, 1273, -393, -2489, -1431, 4151, 10804, 13019, 8829, 1908, -2313, + -1964, 360, 1350, 439, -641, -597, 114, 432, 139, -195, -173, 31, 106, 30, -36, -25}; +#else +#define resamp_filt_32k NULL +#endif +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 resamp_filt_96k[240] = { + -3, -7, -10, -13, -13, -10, -4, 5, 15, 26, 33, 36, 31, 19, 0, -23, -47, -66, -76, + -73, -54, -21, 23, 70, 111, 139, 143, 121, 72, 0, -84, -165, -227, -256, -240, -175, -67, 72, + 219, 349, 433, 448, 379, 225, 0, -268, -536, -755, -874, -848, -648, -260, 301, 1000, 1780, 2569, 3290, + 3869, 4243, 4372, 4243, 3869, 3290, 2569, 1780, 1000, 301, -260, -648, -848, -874, -755, -536, -268, 0, 225, + 379, 448, 433, 349, 219, 72, -67, -175, -240, -256, -227, -165, -84, 0, 72, 121, 143, 139, 111, + 70, 23, -21, -54, -73, -76, -66, -47, -23, 0, 19, 31, 36, 33, 26, 15, 5, -4, -10, + -13, -13, -10, -7, -3, 0, -1, -5, -8, -12, -13, -12, -8, 0, 10, 21, 30, 35, 34, + 26, 10, -11, -35, -58, -73, -76, -65, -39, 0, 46, 92, 127, 144, 136, 100, 38, -41, -125, + -199, -246, -254, -214, -126, 0, 146, 288, 398, 450, 424, 312, 120, -131, -405, -655, -830, -881, -771, + -477, 0, 636, 1384, 2178, 2943, 3601, 4084, 4340, 4340, 4084, 3601, 2943, 2178, 1384, 636, 0, -477, -771, + -881, -830, -655, -405, -131, 120, 312, 424, 450, 398, 288, 146, 0, -126, -214, -254, -246, -199, -125, + -41, 38, 100, 136, 144, 127, 92, 46, 0, -39, -65, -76, -73, -58, -35, -11, 10, 26, 34, + 35, 30, 21, 10, 0, -8, -12, -13, -12, -8, -5, -1}; +#else +# define resamp_filt_96k NULL +#endif -const LC3_INT32 gwlpr[MAX_LGW+1] = { 1, 3*QUOT_LPR_LTR, 5*QUOT_LPR_LTR, 9*QUOT_LPR_LTR, 17*QUOT_LPR_LTR, 33*QUOT_LPR_LTR, 49*QUOT_LPR_LTR, 65*QUOT_LPR_LTR, 81*QUOT_LPR_LTR, 97*QUOT_LPR_LTR}; +#ifdef SUBSET_FB +RAM_ALIGN const Word16 resamp_filt_48k[240] = { + -13, -25, -20, 10, 51, 71, 38, -47, -133, -145, -42, 139, 277, 242, 0, -329, + -511, -351, 144, 698, 895, 450, -535, -1510, -1697, -521, 1999, 5138, 7737, 8744, 7737, 5138, + 1999, -521, -1697, -1510, -535, 450, 895, 698, 144, -351, -511, -329, 0, 242, 277, 139, + -42, -145, -133, -47, 38, 71, 51, 10, -20, -25, -13, 0, -9, -23, -24, 0, + 41, 71, 52, -23, -115, -152, -78, 92, 254, 272, 76, -251, -493, -427, 0, 576, + 900, 624, -262, -1309, -1763, -954, 1272, 4356, 7203, 8679, 8169, 5886, 2767, 0, -1542, -1660, + -809, 240, 848, 796, 292, -252, -507, -398, -82, 199, 288, 183, 0, -130, -145, -71, + 20, 69, 60, 20, -15, -26, -17, -3, -6, -20, -26, -8, 31, 67, 62, 0, + -94, -152, -108, 45, 223, 287, 143, -167, -454, -480, -134, 439, 866, 758, 0, -1071, + -1748, -1295, 601, 3559, 6580, 8485, 8485, 6580, 3559, 601, -1295, -1748, -1071, 0, 758, 866, + 439, -134, -480, -454, -167, 143, 287, 223, 45, -108, -152, -94, 0, 62, 67, 31, + -8, -26, -20, -6, -3, -17, -26, -15, 20, 60, 69, 20, -71, -145, -130, 0, + 183, 288, 199, -82, -398, -507, -252, 292, 796, 848, 240, -809, -1660, -1542, 0, 2767, + 5886, 8169, 8679, 7203, 4356, 1272, -954, -1763, -1309, -262, 624, 900, 576, 0, -427, -493, + -251, 76, 272, 254, 92, -78, -152, -115, -23, 52, 71, 41, 0, -24, -23, -9}; +#else +#define resamp_filt_48k NULL +#endif -#ifdef CR8_A_PLC_FADEOUT_TUNING -/* PLC_FADEOUT_TUNING, extended table ranging from 30 ms to 140 ms */ -const LC3_INT16 fade_scheme_tab[24 / 2][3] = { - /* tabled {att_per_frame_idx_p3dB , burst_att_thresh, beta_mute_thr } */ - { 1, 2, 0 + 2 + 2 }, /* 30 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=0 */ - { 1, 3, 0 + 3 + 2 }, /* 40 ms, 0.3 dB delta att in slow mutephase */ - { 3, 3, 1 + 3 + 1 }, /* 50 ms, 0.3 dB delta att in slow mutephase */ - { 3, 4, 1 + 4 + 1}, /* 60 ms, 0.3 dB delta att in slow mutephase */ - { 5, 4, 3 + 4 + 1 }, /* 70 ms, 0.3 dB delta att in slow mutephase */ - { 5, 5, 3 + 5 + 1 }, /* 80 ms, 0.3 dB delta att in slow mutephase */ - { 7, 5, 7 + 5 }, /* 90 ms, 0.3 dB delta att in slow mutephase */ - { 7, 5, 7 + 5 + 1}, /* 100 ms, 0.3 dB delta att in slow mutephase */ - { 9, 5, 9 + 5 }, /* 110 ms, 0.3 dB delta att in slow mutephase */ - { 9, 5, 9 + 5 + 1}, /* 120 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=1 */ - { 11, 5, 15 + 5 },/* 130 ms, 0.3 dB delta att in slow mutephase */ - { 11, 6, 15 + 6 },/* 140 ms, 0.3 dB delta att in slow mutephase nominal 3GPP */ +RAM_ALIGN const Word16 *const resamp_filts[NUM_SAMP_FREQ] = {resamp_filt_8k, + resamp_filt_16k, + resamp_filt_24k, + resamp_filt_32k, + resamp_filt_48k, + resamp_filt_96k +}; +RAM_ALIGN const Word16 resamp_params[NUM_SAMP_FREQ][4] = { +#ifdef SUBSET_NB + {24, 5, 0, 15}, +#else + {0}, +#endif +#ifdef SUBSET_WB + {12, 10, 1, 3}, +#else + {0}, +#endif +#ifdef SUBSET_SSWB + {8, 15, 1, 7}, +#else + {0}, +#endif +#ifdef SUBSET_SWB + {6, 20, 2, 3}, +#else + {0}, +#endif +#ifdef SUBSET_FB + {4, 30, 3, 3}, +#else + {0}, +#endif +#ifdef ENABLE_HR_MODE + {2, 60, 7, 1}, +#endif }; +RAM_ALIGN const Word16 highpass50_filt_num[3] = {32204, -32204, 32204}; +RAM_ALIGN const Word16 highpass50_filt_den[2] = {32199, -31650}; + +RAM_ALIGN const Word16 olpa_ac_weighting[98] = { + 32767, 32598, 32429, 32260, 32091, 31922, 31754, 31585, 31416, 31247, 31078, 30909, 30740, 30571, + 30402, 30233, 30065, 29896, 29727, 29558, 29389, 29220, 29051, 28882, 28713, 28544, 28376, 28207, + 28038, 27869, 27700, 27531, 27362, 27193, 27024, 26855, 26687, 26518, 26349, 26180, 26011, 25842, + 25673, 25504, 25335, 25166, 24998, 24829, 24660, 24491, 24322, 24153, 23984, 23815, 23646, 23477, + 23308, 23140, 22971, 22802, 22633, 22464, 22295, 22126, 21957, 21788, 21619, 21451, 21282, 21113, + 20944, 20775, 20606, 20437, 20268, 20099, 19930, 19762, 19593, 19424, 19255, 19086, 18917, 18748, + 18579, 18410, 18241, 18073, 17904, 17735, 17566, 17397, 17228, 17059, 16890, 16721, 16552, 16384}; + +RAM_ALIGN const Word16 ltpf_ac_interp_filt[7][9] = { + {90, 151, -2472, 26787, 10819, -3468, 940, -94, 0}, {-98, 967, -4270, 19769, 19769, -4270, 967, -98, 0}, + {-94, 940, -3468, 10819, 26787, -2472, 151, 90, 0}, {0, 503, -1550, 2739, 29447, 2739, -1550, 503, 0}, + {0, 90, 151, -2472, 26787, 10819, -3468, 940, -94}, {0, -98, 967, -4270, 19769, 19769, -4270, 967, -98}, + {0, -94, 940, -3468, 10819, 26787, -2472, 151, 90}}; + +RAM_ALIGN const Word16 inter_filter[5][4][12] = { + {{6877, 19121, 6877, 0}, {3506, 18025, 11000, 220}, {1300, 15048, 15048, 1300}, {220, 11000, 18025, 3506}}, + {{6877, 19121, 6877, 0}, {3506, 18025, 11000, 220}, {1300, 15048, 15048, 1300}, {220, 11000, 18025, 3506}}, + {{2072, 8216, 12170, 8216, 2072, 0}, + {1134, 6509, 11883, 9787, 3320, 140}, + {503, 4831, 11057, 11057, 4831, 503}, + {140, 3320, 9787, 11883, 6509, 1134}}, + {{950, 3702, 7248, 8926, 7248, 3702, 950, 0}, + {558, 2858, 6427, 8812, 7946, 4606, 1466, 102}, + {281, 2106, 5530, 8479, 8479, 5530, 2106, 281}, + {102, 1466, 4606, 7946, 8812, 6427, 2858, 558}}, + {{355, 1183, 2515, 4068, 5333, 5822, 5333, 4068, 2515, 1183, 355, 0}, + {231, 924, 2145, 3685, 5074, 5791, 5543, 4433, 2900, 1474, 510, 67}, + {136, 700, 1797, 3293, 4771, 5697, 5697, 4771, 3293, 1797, 700, 136}, + {67, 510, 1474, 2900, 4433, 5543, 5791, 5074, 3685, 2145, 924, 231}}}; +RAM_ALIGN const Word16 inter_filter_shift[5] = {1, 1, 2, 3, 5}; +RAM_ALIGN const Word16 inter_filter_len[5] = {4, 4, 6, 8, 12}; + +RAM_ALIGN const Word16 tilt_filter[5][4][11] = { + {{16777, 11692, -525}, {16697, 11692, -444}, {16622, 11692, -369}, {16551, 11692, -298}}, + {{16777, 11692, -525}, {16697, 11692, -444}, {16622, 11692, -369}, {16551, 11692, -298}}, + {{11112, 14323, 2797, -356, -44}, + {10998, 14271, 2906, -304, -38}, + {10890, 14222, 3008, -255, -32}, + {10788, 14175, 3104, -208, -26}}, + {{8307, 12959, 5866, 1049, -283, -71, -9}, + {8199, 12866, 5931, 1133, -242, -61, -8}, + {8098, 12777, 5992, 1212, -203, -51, -6}, + {8002, 12693, 6050, 1287, -166, -42, -5}}, + {{5519, 9817, 7001, 3967, 1589, 259, -201, -88, -31, -8, -1}, + {5433, 9706, 6991, 4014, 1651, 309, -172, -76, -27, -7, -1}, + {5353, 9601, 6981, 4058, 1710, 356, -145, -64, -23, -6, -1}, + {5277, 9501, 6970, 4100, 1767, 402, -118, -52, -19, -5, -1}}}; +RAM_ALIGN const Word16 tilt_filter_len[5] = {2, 2, 4, 6, 10}; + +RAM_ALIGN const Word16 gain_scale_fac[4] = {13108, 11468, 9832, 8192}; + +RAM_ALIGN const UWord16 pitch_scale[NUM_SAMP_FREQ] = {5120, + 10240, + 15360, + 20480, + 30720 +}; +RAM_ALIGN const Word16 ltpf_overlap_len[NUM_SAMP_FREQ] = {20, 40, 60, 80, 120 +}; -/*compressed ATH Abolute hearing THreshold function weights at band borders */ -const LC3_FLOAT scATHFx[MAX_LGW - 2] = { .455444335937500 , 0.930755615234375 , 0.973083496093750 , 0.999969482421875 , 0.908508300781250 , 0.775665283203125 , 0.5 }; +/* set up of SNS VQ stages 1 ( split VQ) and SNS stage 2(Transformed PVQ) for bit rate 38 bits */ + +/* trained gain set for DCT Q12 */ +RAM_ALIGN const Word16 sns_vq_reg_adj_gains[2] = {8915, 12054}; +RAM_ALIGN const Word16 sns_vq_reg_lf_adj_gains[4] = {6245, 15043, 17861, 21014}; +RAM_ALIGN const Word16 sns_vq_near_adj_gains[4] = {7099, 9132, 11253, 14808}; +RAM_ALIGN const Word16 sns_vq_far_adj_gains[8] = {4336, 5067, 5895, 8149, 10235, 12825, 16868, 19882}; + +RAM_ALIGN const Word16 *const sns_gaintabPtr[4] = {sns_vq_reg_adj_gains, sns_vq_reg_lf_adj_gains, sns_vq_near_adj_gains, + sns_vq_far_adj_gains}; +RAM_ALIGN const Word16 sns_gainSz[4] = {2, 4, 4, 8}; +RAM_ALIGN const Word16 sns_gainMSBbits[4] = {1, 1, 2, 2}; +RAM_ALIGN const Word16 sns_gainLSBbits[4] = {0, 1, 0, 1}; +RAM_ALIGN const Word16 sns_Kval[4][2] = {{10, 1}, {10, 0}, {8, 0}, {6, 0}}; +RAM_ALIGN const UWord32 sns_MPVQ_Sz[4][2] = { + {4780008U >> 1, (2U * 6U)}, {4780008U >> 1, (2U)}, {30316544U >> 1, 0U}, {MPVQ_SZ_OUTL_FAR, 0U}}; + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 st1SCF0_7_base5_32x8_Q27[256] = { + 303712392, 109160791, -71161366, -182086260, -214684177, -193406093, -153520450, -101361734, 395293327, + 323657083, 128910102, -59488852, -164971858, -208829415, -200908713, -149907762, -293414324, -264613117, + -239872071, -257518046, -240785425, -182185002, -94683128, -6417929, 93105259, 128259784, 77206169, + -15381811, -86711449, -127822437, -144156883, -101748810, -174150364, -99370653, -46355110, -42048494, + -54086690, -49931794, -10514807, 13025043, 122762518, 233932163, 256230537, 207243559, 146760322, + 86903234, 4855873, -39875122, -337462040, -388124479, -269040331, -100785739, 59217144, 161317613, + 178164447, 163811504, -123774032, 84892061, 145943568, 81688751, 17605952, -39748467, -27784884, + 18109316, 106075262, 84342590, 52763395, 64425544, 60104730, 28150050, 881397, -11559399, + 194314494, 365609026, 310154713, 125500457, -36875504, -121074819, -126256135, -85053377, 106482242, + 1931812, -76213503, -87880462, -64351897, -23339746, 9128989, 39611134, 365643112, 397214108, + 248240465, 75602822, 18779354, 48270210, 92537937, 85871184, -71246823, -28546860, 773918, + 57025285, 63502293, 115278828, 159868294, 133706314, 226463440, 326973859, 312753384, 238885783, + 193825560, 204004473, 197567682, 131222320, -396188282, -213934330, -14753048, 52158227, 68844655, + 84303846, 110410429, 117560157, 13673880, 79169310, 83087169, 170095890, 324754621, 302223766, + 70670604, -53229612, 360045196, 178157942, 17473172, -45437142, -49421549, -25728189, -20774539, + -31434755, 647866186, 418689256, 187252080, 33594069, -52829955, -86363494, -86244384, -97065351, + 11789953, -76448652, -153687373, -224101311, -247677903, -210007831, -149983961, -71669806, 186699958, + 265947702, 149338424, -29542330, -104014124, -79733903, 18379464, 109822702, 51618245, -21553862, + -72392588, -71042662, 25559558, 343681831, 378354941, 88136873, 259345425, 404035869, 411436250, + 335692175, 259160465, 76793185, -108950139, -157896166, 23498902, -100733469, -139511132, -152441152, + -139852059, -2040916, 277895647, 460298246, -159473505, 49230106, 175768625, 225929624, 167907618, + 126483532, 110897463, 59049457, 340003306, 283568025, 169501437, 102208613, 70077483, 15928969, + -60712963, -93999711, 536723054, 547476463, 378877401, 231669479, 86858248, -44446002, -118654185, + -151259810, 68169532, 213189358, 232061142, 135146824, 50616355, 63937402, 145968142, 145970189, + 425278032, 437353108, 325116396, 240848448, 204249734, 157298757, 65685431, -8359023, 254228196, + 167918047, 79249020, 81652507, 117866118, 150206430, 136711039, 83275912, 127356599, 286205131, + 365535742, 371764419, 341298198, 271181905, 111406869, -3698627, -252365241, -169692913, 41798753, + 246517983, 302841086, 274903406, 294643934, 272005129, 33067993, 128261383, 204073729, 265277850, + 260441270, 299809987, 266873132, 170768802 }; +RAM_ALIGN const Word32 st1SCF8_15_base5_32x8_Q27[256] = { + 31142327, -135412629, -287525918, -318812488, -299361815, -292052248, -307447065, -339955249, -173817241, + -241497912, -253273077, -242922894, -236679593, -246180047, -242237472, -233108740, 18694612, -34653021, + -87349511, -143365648, -217337078, -293618146, -354009441, -399831591, -42481669, -64122205, -73975722, + -65067182, -31995949, -19196424, 9169576, 11852254, 118046962, 40042530, -122861082, -296146014, + -367947407, -384049364, -387676629, -396187390, -39822658, -130862945, -182344850, -132032812, -87638397, + -132873805, -216717640, -323078583, 45765709, 36091119, 7560964, 6698995, -12806126, -102027773, + -312402661, -506209524, -189555374, -199343014, -159187030, -83886299, 20656444, 77361286, 106715523, + 80069550, -30714319, -44791015, -108625274, -219563932, -252982160, -220783722, -188597085, -196852406, + -143812455, -190276467, -207892204, -195013074, -138489838, -92696486, -57558441, -66432436, -79321135, + -9552782, 46401689, 40339066, -150142954, -327610913, -299110559, -254354980, -113874897, -78279377, + 12085282, 113417337, 143039033, 98996714, 34438988, -66030204, 153101016, 129388157, 51198856, + -64806941, -243783312, -376184794, -434040973, -464270818, -50503881, 5713319, 69329858, 33784868, + -29015184, -71682211, -86004854, -116735202, 89255342, 147358670, 185680385, 180291129, 110458350, + 28974493, -54348215, -143647337, -110899539, -90084420, -30668159, 69656431, 183505023, 292625568, + 340370914, 295441538, 189258173, 101259479, -175222029, -251166616, -166441640, -170071209, -273362338, + -388808843, 48504518, -2952679, -77761569, -118034823, -114177011, -104608901, -98271929, -119232119, + 58716127, 40995519, -991583, -66524997, -108266901, -164325304, -228381893, -301307946, 86986552, + 91576640, 33990299, 9876306, 42173453, 31504911, 19407902, -9155262, 150216257, 165712633, + 79077091, -184136602, -318224471, -269482063, -223725572, -258546087, 19038449, -14852543, -37960074, + -885587, 38376778, 6179995, -80879122, -304095400, 67652037, 110995667, 150298671, 158261551, + 144938274, 93621729, -122480229, -480076341, -67253289, -43711762, 3768810, 35172367, 48397679, + 85311972, 128716474, 175483179, 503277534, 204470792, -61433556, -107201177, -51918012, -50452587, + -88293374, -172018761, -154697999, -148714432, -75512923, -29603347, -46955117, -101124035, -132687189, + -172859645, 138012394, 147331497, 103165859, 27659855, -46010607, -101326252, -139849742, -201777098, + 17291535, 92534989, 150789463, 175737342, 181881080, 191007103, 155298567, 54535272, 179896088, + 186558381, 140214471, 85338684, -36874140, -207934631, -327812990, -405951728, 287015358, 570037814, + 388874539, 125188990, -39301937, -108770623, -105880084, -125540975, 75810265, 213654461, 321816127, + 407615675, 357588710, 186971315, 54201685, -88083199, -56701695, 43775062, 186792575, 299502316, + 350549113, 357744389, 322261535, 236116337 }; #endif -const LC3_FLOAT PhECU_whr16ms_NB[128]={ -8.000000000000002e-02, 8.393536376804722e-02, 9.567411990702857e-02, 1.150154150448081e-01, 1.416283142591582e-01, -1.750574634660318e-01, 2.147308806541882e-01, 2.599697426559885e-01, 3.099999999999999e-01, 3.639656211120587e-01, -4.209432392528405e-01, 4.799579515787762e-01, 5.400000000000000e-01, 6.000420484212237e-01, 6.590567607471596e-01, -7.160343788879413e-01, 7.699999999999999e-01, 8.200302573440115e-01, 8.652691193458119e-01, 9.049425365339682e-01, -9.383716857408418e-01, 9.649845849551919e-01, 9.843258800929715e-01, 9.960646362319528e-01, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -9.960646362319528e-01, 9.843258800929715e-01, 9.649845849551919e-01, 9.383716857408418e-01, 9.049425365339682e-01, -8.652691193458119e-01, 8.200302573440115e-01, 7.699999999999999e-01, 7.160343788879413e-01, 6.590567607471596e-01, -6.000420484212237e-01, 5.400000000000000e-01, 4.799579515787762e-01, 4.209432392528405e-01, 3.639656211120587e-01, -3.099999999999999e-01, 2.599697426559885e-01, 2.147308806541882e-01, 1.750574634660318e-01, 1.416283142591582e-01, -1.150154150448081e-01, 9.567411990702857e-02, 8.393536376804722e-02 -}; -const LC3_FLOAT PhECU_whr16ms_WB[256]={ -8.000000000000002e-02, 8.098489531024239e-02, 8.393536376804722e-02, 8.883877101451404e-02, 9.567411990702857e-02, -1.044121404322514e-01, 1.150154150448081e-01, 1.274385388949634e-01, 1.416283142591582e-01, 1.575239783408292e-01, -1.750574634660318e-01, 1.941536885596704e-01, 2.147308806541882e-01, 2.367009250539683e-01, 2.599697426559885e-01, -2.844376928109830e-01, 3.099999999999999e-01, 3.365472024992595e-01, 3.639656211120587e-01, 3.921378459605457e-01, -4.209432392528405e-01, 4.502584518725810e-01, 4.799579515787762e-01, 5.099145605541342e-01, 5.400000000000000e-01, -5.700854394458659e-01, 6.000420484212237e-01, 6.297415481274190e-01, 6.590567607471596e-01, 6.878621540394543e-01, -7.160343788879413e-01, 7.434527975007406e-01, 7.699999999999999e-01, 7.955623071890170e-01, 8.200302573440115e-01, -8.432990749460317e-01, 8.652691193458119e-01, 8.858463114403297e-01, 9.049425365339682e-01, 9.224760216591710e-01, -9.383716857408418e-01, 9.525614611050366e-01, 9.649845849551919e-01, 9.755878595677486e-01, 9.843258800929715e-01, -9.911612289854861e-01, 9.960646362319528e-01, 9.990151046897577e-01, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 9.990151046897577e-01, -9.960646362319528e-01, 9.911612289854861e-01, 9.843258800929715e-01, 9.755878595677486e-01, 9.649845849551919e-01, -9.525614611050366e-01, 9.383716857408418e-01, 9.224760216591710e-01, 9.049425365339682e-01, 8.858463114403297e-01, -8.652691193458119e-01, 8.432990749460317e-01, 8.200302573440115e-01, 7.955623071890170e-01, 7.699999999999999e-01, -7.434527975007406e-01, 7.160343788879413e-01, 6.878621540394543e-01, 6.590567607471596e-01, 6.297415481274190e-01, -6.000420484212237e-01, 5.700854394458659e-01, 5.400000000000000e-01, 5.099145605541342e-01, 4.799579515787762e-01, -4.502584518725810e-01, 4.209432392528405e-01, 3.921378459605457e-01, 3.639656211120587e-01, 3.365472024992595e-01, -3.099999999999999e-01, 2.844376928109830e-01, 2.599697426559885e-01, 2.367009250539683e-01, 2.147308806541882e-01, -1.941536885596704e-01, 1.750574634660318e-01, 1.575239783408292e-01, 1.416283142591582e-01, 1.274385388949634e-01, -1.150154150448081e-01, 1.044121404322514e-01, 9.567411990702857e-02, 8.883877101451404e-02, 8.393536376804722e-02, -8.098489531024239e-02 -}; -const LC3_FLOAT PhECU_whr16ms_SSWB[384]={ -8.000000000000002e-02, 8.043781807234540e-02, 8.175043887779704e-02, 8.393536376804722e-02, 8.698843361438435e-02, -9.090383672483066e-02, 9.567411990702857e-02, 1.012902026558156e-01, 1.077413944384821e-01, 1.150154150448081e-01, -1.230984179631410e-01, 1.319750167380180e-01, 1.416283142591582e-01, 1.520399349260726e-01, 1.631900596270638e-01, -1.750574634660318e-01, 1.876195561652702e-01, 2.008524250673430e-01, 2.147308806541882e-01, 2.292285044967963e-01, -2.443176995441919e-01, 2.599697426559885e-01, 2.761548392785189e-01, 2.928421801604610e-01, 3.099999999999999e-01, -3.275956379118843e-01, 3.455955995992783e-01, 3.639656211120587e-01, 3.826707340701924e-01, 4.016753322280344e-01, -4.209432392528405e-01, 4.404377775884727e-01, 4.601218382732121e-01, 4.799579515787762e-01, 4.999083583360772e-01, -5.199350818119455e-01, 5.400000000000000e-01, 5.600649181880546e-01, 5.800916416639228e-01, 6.000420484212237e-01, -6.198781617267880e-01, 6.395622224115274e-01, 6.590567607471596e-01, 6.783246677719657e-01, 6.973292659298076e-01, -7.160343788879413e-01, 7.344044004007217e-01, 7.524043620881156e-01, 7.699999999999999e-01, 7.871578198395390e-01, -8.038451607214812e-01, 8.200302573440115e-01, 8.356823004558082e-01, 8.507714955032037e-01, 8.652691193458119e-01, -8.791475749326572e-01, 8.923804438347298e-01, 9.049425365339682e-01, 9.168099403729364e-01, 9.279600650739274e-01, -9.383716857408418e-01, 9.480249832619820e-01, 9.569015820368590e-01, 9.649845849551919e-01, 9.722586055615179e-01, -9.787097973441844e-01, 9.843258800929715e-01, 9.890961632751694e-01, 9.930115663856157e-01, 9.960646362319528e-01, -9.982495611222031e-01, 9.995621819276547e-01, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 9.995621819276547e-01, 9.982495611222031e-01, -9.960646362319528e-01, 9.930115663856157e-01, 9.890961632751694e-01, 9.843258800929715e-01, 9.787097973441844e-01, -9.722586055615179e-01, 9.649845849551919e-01, 9.569015820368590e-01, 9.480249832619820e-01, 9.383716857408418e-01, -9.279600650739274e-01, 9.168099403729364e-01, 9.049425365339682e-01, 8.923804438347298e-01, 8.791475749326572e-01, -8.652691193458119e-01, 8.507714955032037e-01, 8.356823004558082e-01, 8.200302573440115e-01, 8.038451607214812e-01, -7.871578198395390e-01, 7.699999999999999e-01, 7.524043620881156e-01, 7.344044004007217e-01, 7.160343788879413e-01, -6.973292659298076e-01, 6.783246677719657e-01, 6.590567607471596e-01, 6.395622224115274e-01, 6.198781617267880e-01, -6.000420484212237e-01, 5.800916416639228e-01, 5.600649181880546e-01, 5.400000000000000e-01, 5.199350818119455e-01, -4.999083583360772e-01, 4.799579515787762e-01, 4.601218382732121e-01, 4.404377775884727e-01, 4.209432392528405e-01, -4.016753322280344e-01, 3.826707340701924e-01, 3.639656211120587e-01, 3.455955995992783e-01, 3.275956379118843e-01, -3.099999999999999e-01, 2.928421801604610e-01, 2.761548392785189e-01, 2.599697426559885e-01, 2.443176995441919e-01, -2.292285044967963e-01, 2.147308806541882e-01, 2.008524250673430e-01, 1.876195561652702e-01, 1.750574634660318e-01, -1.631900596270638e-01, 1.520399349260726e-01, 1.416283142591582e-01, 1.319750167380180e-01, 1.230984179631410e-01, -1.150154150448081e-01, 1.077413944384821e-01, 1.012902026558156e-01, 9.567411990702857e-02, 9.090383672483066e-02, -8.698843361438435e-02, 8.393536376804722e-02, 8.175043887779704e-02, 8.043781807234540e-02 -}; -const LC3_FLOAT PhECU_whr16ms_SWB[512]={ -8.000000000000002e-02, 8.024628976087178e-02, 8.098489531024239e-02, 8.221502573078943e-02, 8.393536376804722e-02, -8.614406724095569e-02, 8.883877101451404e-02, 9.201658953242653e-02, 9.567411990702857e-02, 9.980744556318394e-02, -1.044121404322514e-01, 1.094832736916302e-01, 1.150154150448081e-01, 1.210026405362591e-01, 1.274385388949634e-01, -1.343162183997567e-01, 1.416283142591582e-01, 1.493669964977737e-01, 1.575239783408292e-01, 1.660905250878570e-01, -1.750574634660318e-01, 1.844151914531410e-01, 1.941536885596704e-01, 2.042625265589956e-01, 2.147308806541882e-01, -2.255475410694793e-01, 2.367009250539683e-01, 2.481790892847231e-01, 2.599697426559885e-01, 2.720602594408110e-01, -2.844376928109830e-01, 2.970887887008307e-01, 3.099999999999999e-01, 3.231575010600410e-01, 3.365472024992595e-01, -3.501547662899784e-01, 3.639656211120587e-01, 3.779649779562326e-01, 3.921378459605457e-01, 4.064690484629473e-01, -4.209432392528405e-01, 4.355449190041883e-01, 4.502584518725810e-01, 4.650680822384892e-01, 4.799579515787762e-01, -4.949121154484021e-01, 5.099145605541342e-01, 5.249492219019830e-01, 5.400000000000000e-01, 5.550507780980171e-01, -5.700854394458659e-01, 5.850878845515979e-01, 6.000420484212237e-01, 6.149319177615109e-01, 6.297415481274190e-01, -6.444550809958116e-01, 6.590567607471596e-01, 6.735309515370527e-01, 6.878621540394543e-01, 7.020350220437674e-01, -7.160343788879413e-01, 7.298452337100215e-01, 7.434527975007406e-01, 7.568424989399589e-01, 7.699999999999999e-01, -7.829112112991693e-01, 7.955623071890170e-01, 8.079397405591890e-01, 8.200302573440115e-01, 8.318209107152770e-01, -8.432990749460317e-01, 8.544524589305209e-01, 8.652691193458119e-01, 8.757374734410044e-01, 8.858463114403297e-01, -8.955848085468591e-01, 9.049425365339682e-01, 9.139094749121430e-01, 9.224760216591710e-01, 9.306330035022263e-01, -9.383716857408418e-01, 9.456837816002432e-01, 9.525614611050366e-01, 9.589973594637410e-01, 9.649845849551919e-01, -9.705167263083698e-01, 9.755878595677486e-01, 9.801925544368162e-01, 9.843258800929715e-01, 9.879834104675735e-01, -9.911612289854861e-01, 9.938559327590444e-01, 9.960646362319528e-01, 9.977849742692106e-01, 9.990151046897577e-01, -9.997537102391283e-01, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 9.997537102391283e-01, 9.990151046897577e-01, 9.977849742692106e-01, -9.960646362319528e-01, 9.938559327590444e-01, 9.911612289854861e-01, 9.879834104675735e-01, 9.843258800929715e-01, -9.801925544368162e-01, 9.755878595677486e-01, 9.705167263083698e-01, 9.649845849551919e-01, 9.589973594637410e-01, -9.525614611050366e-01, 9.456837816002432e-01, 9.383716857408418e-01, 9.306330035022263e-01, 9.224760216591710e-01, -9.139094749121430e-01, 9.049425365339682e-01, 8.955848085468591e-01, 8.858463114403297e-01, 8.757374734410044e-01, -8.652691193458119e-01, 8.544524589305209e-01, 8.432990749460317e-01, 8.318209107152770e-01, 8.200302573440115e-01, -8.079397405591890e-01, 7.955623071890170e-01, 7.829112112991693e-01, 7.699999999999999e-01, 7.568424989399589e-01, -7.434527975007406e-01, 7.298452337100215e-01, 7.160343788879413e-01, 7.020350220437674e-01, 6.878621540394543e-01, -6.735309515370527e-01, 6.590567607471596e-01, 6.444550809958116e-01, 6.297415481274190e-01, 6.149319177615109e-01, -6.000420484212237e-01, 5.850878845515979e-01, 5.700854394458659e-01, 5.550507780980171e-01, 5.400000000000000e-01, -5.249492219019830e-01, 5.099145605541342e-01, 4.949121154484021e-01, 4.799579515787762e-01, 4.650680822384892e-01, -4.502584518725810e-01, 4.355449190041883e-01, 4.209432392528405e-01, 4.064690484629473e-01, 3.921378459605457e-01, -3.779649779562326e-01, 3.639656211120587e-01, 3.501547662899784e-01, 3.365472024992595e-01, 3.231575010600410e-01, -3.099999999999999e-01, 2.970887887008307e-01, 2.844376928109830e-01, 2.720602594408110e-01, 2.599697426559885e-01, -2.481790892847231e-01, 2.367009250539683e-01, 2.255475410694793e-01, 2.147308806541882e-01, 2.042625265589956e-01, -1.941536885596704e-01, 1.844151914531410e-01, 1.750574634660318e-01, 1.660905250878570e-01, 1.575239783408292e-01, -1.493669964977737e-01, 1.416283142591582e-01, 1.343162183997567e-01, 1.274385388949634e-01, 1.210026405362591e-01, -1.150154150448081e-01, 1.094832736916302e-01, 1.044121404322514e-01, 9.980744556318394e-02, 9.567411990702857e-02, -9.201658953242653e-02, 8.883877101451404e-02, 8.614406724095569e-02, 8.393536376804722e-02, 8.221502573078943e-02, -8.098489531024239e-02, 8.024628976087178e-02 +RAM_ALIGN const Word16 st1SCF0_7_base5_32x8_Q11[256] = { + 4634, 1666, -1086, -2778, -3276, -2951, -2343, -1547, 6032, 4939, 1967, -908, -2517, -3186, -3066, -2287, + -4477, -4038, -3660, -3929, -3674, -2780, -1445, -98, 1421, 1957, 1178, -235, -1323, -1950, -2200, -1553, + -2657, -1516, -707, -642, -825, -762, -160, 199, 1873, 3570, 3910, 3162, 2239, 1326, 74, -608, + -5149, -5922, -4105, -1538, 904, 2462, 2719, 2500, -1889, 1295, 2227, 1246, 269, -607, -424, 276, + 1619, 1287, 805, 983, 917, 430, 13, -176, 2965, 5579, 4733, 1915, -563, -1847, -1927, -1298, + 1625, 29, -1163, -1341, -982, -356, 139, 604, 5579, 6061, 3788, 1154, 287, 737, 1412, 1310, + -1087, -436, 12, 870, 969, 1759, 2439, 2040, 3456, 4989, 4772, 3645, 2958, 3113, 3015, 2002, + -6045, -3264, -225, 796, 1050, 1286, 1685, 1794, 209, 1208, 1268, 2595, 4955, 4612, 1078, -812, + 5494, 2718, 267, -693, -754, -393, -317, -480, 9886, 6389, 2857, 513, -806, -1318, -1316, -1481, + 180, -1167, -2345, -3420, -3779, -3204, -2289, -1094, 2849, 4058, 2279, -451, -1587, -1217, 280, 1676, + 788, -329, -1105, -1084, 390, 5244, 5773, 1345, 3957, 6165, 6278, 5122, 3954, 1172, -1662, -2409, + 359, -1537, -2129, -2326, -2134, -31, 4240, 7024, -2433, 751, 2682, 3447, 2562, 1930, 1692, 901, + 5188, 4327, 2586, 1560, 1069, 243, -926, -1434, 8190, 8354, 5781, 3535, 1325, -678, -1811, -2308, + 1040, 3253, 3541, 2062, 772, 976, 2227, 2227, 6489, 6673, 4961, 3675, 3117, 2400, 1002, -128, + 3879, 2562, 1209, 1246, 1798, 2292, 2086, 1271, 1943, 4367, 5578, 5673, 5208, 4138, 1700, -56, + -3851, -2589, 638, 3762, 4621, 4195, 4496, 4150, 505, 1957, 3114, 4048, 3974, 4575, 4072, 2606}; + +RAM_ALIGN const Word16 st1SCF8_15_base5_32x8_Q11[256] = { + 475, -2066, -4387, -4865, -4568, -4456, -4691, -5187, -2652, -3685, -3865, -3707, -3611, -3756, -3696, -3557, + 285, -529, -1333, -2188, -3316, -4480, -5402, -6101, -648, -978, -1129, -993, -488, -293, 140, 181, + 1801, 611, -1875, -4519, -5614, -5860, -5915, -6045, -608, -1997, -2782, -2015, -1337, -2027, -3307, -4930, + 698, 551, 115, 102, -195, -1557, -4767, -7724, -2892, -3042, -2429, -1280, 315, 1180, 1628, 1222, + -469, -683, -1657, -3350, -3860, -3369, -2878, -3004, -2194, -2903, -3172, -2976, -2113, -1414, -878, -1014, + -1210, -146, 708, 616, -2291, -4999, -4564, -3881, -1738, -1194, 184, 1731, 2183, 1511, 525, -1008, + 2336, 1974, 781, -989, -3720, -5740, -6623, -7084, -771, 87, 1058, 516, -443, -1094, -1312, -1781, + 1362, 2249, 2833, 2751, 1685, 442, -829, -2192, -1692, -1375, -468, 1063, 2800, 4465, 5194, 4508, + 2888, 1545, -2674, -3832, -2540, -2595, -4171, -5933, 740, -45, -1187, -1801, -1742, -1596, -1500, -1819, + 896, 626, -15, -1015, -1652, -2507, -3485, -4598, 1327, 1397, 519, 151, 644, 481, 296, -140, + 2292, 2529, 1207, -2810, -4856, -4112, -3414, -3945, 291, -227, -579, -14, 586, 94, -1234, -4640, + 1032, 1694, 2293, 2415, 2212, 1429, -1869, -7325, -1026, -667, 58, 537, 738, 1302, 1964, 2678, + 7679, 3120, -937, -1636, -792, -770, -1347, -2625, -2361, -2269, -1152, -452, -716, -1543, -2025, -2638, + 2106, 2248, 1574, 422, -702, -1546, -2134, -3079, 264, 1412, 2301, 2682, 2775, 2915, 2370, 832, + 2745, 2847, 2140, 1302, -563, -3173, -5002, -6194, 4380, 8698, 5934, 1910, -600, -1660, -1616, -1916, + 1157, 3260, 4911, 6220, 5456, 2853, 827, -1344, -865, 668, 2850, 4570, 5349, 5459, 4917, 3603}; + +/* tables for MPVQ pulse enumeration */ + +/* N=16, K=12 31.74 bits */ +RAM_ALIGN const UWord32 h_memN16K12[12 + 2] = { + 0U, 1U, 31U, 481U, 4991U, 39041U, 246047U, + 1303777U, 5984767U, 24331777U, 89129247U, 298199265U, 921406335U, /*U*/ 1326824512U}; + +/*N=16,K=8,h_memN16K8={0U,1U,31U,481U,4991U,39041U,246047U,1303777U,5984767U, 12165888U,}; */ + +/*N=10, K=20 +UWord32 h_memN10K20[20+2] = +{ + 0U,1U,19U,181U,1159U,5641U,22363U,75517U,224143U,598417U,1462563U, + 3317445U,7059735U,14218905U,27298155U,50250765U,89129247U,152951073U,254831667U,413442773U,654862247U, + 507444884U }; -const LC3_FLOAT PhECU_whr16ms_FB[768]={ -8.000000000000002e-02, 8.010946754324183e-02, 8.043781807234540e-02, 8.098489531024239e-02, 8.175043887779704e-02, -8.273408441773300e-02, 8.393536376804722e-02, 8.535370518483010e-02, 8.698843361438435e-02, 8.883877101451404e-02, -9.090383672483066e-02, 9.318264788589975e-02, 9.567411990702857e-02, 9.837706698247278e-02, 1.012902026558156e-01, -1.044121404322514e-01, 1.077413944384821e-01, 1.112763801299127e-01, 1.150154150448081e-01, 1.189567196050543e-01, -1.230984179631410e-01, 1.274385388949634e-01, 1.319750167380180e-01, 1.367056923745465e-01, 1.416283142591582e-01, -1.467405394904446e-01, 1.520399349260726e-01, 1.575239783408292e-01, 1.631900596270638e-01, 1.690354820369581e-01, -1.750574634660318e-01, 1.812531377772744e-01, 1.876195561652702e-01, 1.941536885596704e-01, 2.008524250673430e-01, -2.077125774525124e-01, 2.147308806541882e-01, 2.219039943401561e-01, 2.292285044967963e-01, 2.367009250539683e-01, -2.443176995441919e-01, 2.520752027953329e-01, 2.599697426559885e-01, 2.679975617527521e-01, 2.761548392785189e-01, -2.844376928109830e-01, 2.928421801604610e-01, 3.013643012461601e-01, 3.099999999999999e-01, 3.187451662970817e-01, -3.275956379118843e-01, 3.365472024992595e-01, 3.455955995992783e-01, 3.547365226649809e-01, 3.639656211120587e-01, -3.732785023894972e-01, 3.826707340701924e-01, 3.921378459605457e-01, 4.016753322280344e-01, 4.112786535457436e-01, -4.209432392528405e-01, 4.306644895299604e-01, 4.404377775884727e-01, 4.502584518725810e-01, 4.601218382732121e-01, -4.700232423526383e-01, 4.799579515787762e-01, 4.899212375680964e-01, 4.999083583360772e-01, 5.099145605541342e-01, -5.199350818119455e-01, 5.299651528841020e-01, 5.400000000000000e-01, 5.500348471158981e-01, 5.600649181880546e-01, -5.700854394458659e-01, 5.800916416639228e-01, 5.900787624319037e-01, 6.000420484212237e-01, 6.099767576473617e-01, -6.198781617267880e-01, 6.297415481274190e-01, 6.395622224115274e-01, 6.493355104700396e-01, 6.590567607471596e-01, -6.687213464542564e-01, 6.783246677719657e-01, 6.878621540394543e-01, 6.973292659298076e-01, 7.067214976105027e-01, -7.160343788879413e-01, 7.252634773350191e-01, 7.344044004007217e-01, 7.434527975007406e-01, 7.524043620881156e-01, -7.612548337029182e-01, 7.699999999999999e-01, 7.786356987538400e-01, 7.871578198395390e-01, 7.955623071890170e-01, -8.038451607214812e-01, 8.120024382472478e-01, 8.200302573440115e-01, 8.279247972046673e-01, 8.356823004558082e-01, -8.432990749460317e-01, 8.507714955032037e-01, 8.580960056598439e-01, 8.652691193458119e-01, 8.722874225474876e-01, -8.791475749326572e-01, 8.858463114403297e-01, 8.923804438347298e-01, 8.987468622227257e-01, 9.049425365339682e-01, -9.109645179630421e-01, 9.168099403729364e-01, 9.224760216591710e-01, 9.279600650739274e-01, 9.332594605095554e-01, -9.383716857408418e-01, 9.432943076254536e-01, 9.480249832619820e-01, 9.525614611050366e-01, 9.569015820368590e-01, -9.610432803949458e-01, 9.649845849551919e-01, 9.687236198700873e-01, 9.722586055615179e-01, 9.755878595677486e-01, -9.787097973441844e-01, 9.816229330175272e-01, 9.843258800929715e-01, 9.868173521141004e-01, 9.890961632751694e-01, -9.911612289854861e-01, 9.930115663856157e-01, 9.946462948151700e-01, 9.960646362319528e-01, 9.972659155822671e-01, -9.982495611222031e-01, 9.990151046897577e-01, 9.995621819276547e-01, 9.998905324567582e-01, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, -9.998905324567582e-01, 9.995621819276547e-01, 9.990151046897577e-01, 9.982495611222031e-01, 9.972659155822671e-01, -9.960646362319528e-01, 9.946462948151700e-01, 9.930115663856157e-01, 9.911612289854861e-01, 9.890961632751694e-01, -9.868173521141004e-01, 9.843258800929715e-01, 9.816229330175272e-01, 9.787097973441844e-01, 9.755878595677486e-01, -9.722586055615179e-01, 9.687236198700873e-01, 9.649845849551919e-01, 9.610432803949458e-01, 9.569015820368590e-01, -9.525614611050366e-01, 9.480249832619820e-01, 9.432943076254536e-01, 9.383716857408418e-01, 9.332594605095554e-01, -9.279600650739274e-01, 9.224760216591710e-01, 9.168099403729364e-01, 9.109645179630421e-01, 9.049425365339682e-01, -8.987468622227257e-01, 8.923804438347298e-01, 8.858463114403297e-01, 8.791475749326572e-01, 8.722874225474876e-01, -8.652691193458119e-01, 8.580960056598439e-01, 8.507714955032037e-01, 8.432990749460317e-01, 8.356823004558082e-01, -8.279247972046673e-01, 8.200302573440115e-01, 8.120024382472478e-01, 8.038451607214812e-01, 7.955623071890170e-01, -7.871578198395390e-01, 7.786356987538400e-01, 7.699999999999999e-01, 7.612548337029182e-01, 7.524043620881156e-01, -7.434527975007406e-01, 7.344044004007217e-01, 7.252634773350191e-01, 7.160343788879413e-01, 7.067214976105027e-01, -6.973292659298076e-01, 6.878621540394543e-01, 6.783246677719657e-01, 6.687213464542564e-01, 6.590567607471596e-01, -6.493355104700396e-01, 6.395622224115274e-01, 6.297415481274190e-01, 6.198781617267880e-01, 6.099767576473617e-01, -6.000420484212237e-01, 5.900787624319037e-01, 5.800916416639228e-01, 5.700854394458659e-01, 5.600649181880546e-01, -5.500348471158981e-01, 5.400000000000000e-01, 5.299651528841020e-01, 5.199350818119455e-01, 5.099145605541342e-01, -4.999083583360772e-01, 4.899212375680964e-01, 4.799579515787762e-01, 4.700232423526383e-01, 4.601218382732121e-01, -4.502584518725810e-01, 4.404377775884727e-01, 4.306644895299604e-01, 4.209432392528405e-01, 4.112786535457436e-01, -4.016753322280344e-01, 3.921378459605457e-01, 3.826707340701924e-01, 3.732785023894972e-01, 3.639656211120587e-01, -3.547365226649809e-01, 3.455955995992783e-01, 3.365472024992595e-01, 3.275956379118843e-01, 3.187451662970817e-01, -3.099999999999999e-01, 3.013643012461601e-01, 2.928421801604610e-01, 2.844376928109830e-01, 2.761548392785189e-01, -2.679975617527521e-01, 2.599697426559885e-01, 2.520752027953329e-01, 2.443176995441919e-01, 2.367009250539683e-01, -2.292285044967963e-01, 2.219039943401561e-01, 2.147308806541882e-01, 2.077125774525124e-01, 2.008524250673430e-01, -1.941536885596704e-01, 1.876195561652702e-01, 1.812531377772744e-01, 1.750574634660318e-01, 1.690354820369581e-01, -1.631900596270638e-01, 1.575239783408292e-01, 1.520399349260726e-01, 1.467405394904446e-01, 1.416283142591582e-01, -1.367056923745465e-01, 1.319750167380180e-01, 1.274385388949634e-01, 1.230984179631410e-01, 1.189567196050543e-01, -1.150154150448081e-01, 1.112763801299127e-01, 1.077413944384821e-01, 1.044121404322514e-01, 1.012902026558156e-01, -9.837706698247278e-02, 9.567411990702857e-02, 9.318264788589975e-02, 9.090383672483066e-02, 8.883877101451404e-02, -8.698843361438435e-02, 8.535370518483010e-02, 8.393536376804722e-02, 8.273408441773300e-02, 8.175043887779704e-02, -8.098489531024239e-02, 8.043781807234540e-02, 8.010946754324183e-02 -}; - -const LC3_FLOAT* PhECU_whr16ms_wins[5] = { - PhECU_whr16ms_NB,PhECU_whr16ms_WB,PhECU_whr16ms_SSWB,PhECU_whr16ms_SWB, PhECU_whr16ms_FB +*/ +/*N=10, K=22 31.84 bits */ +RAM_ALIGN const UWord32 h_memN10K22[22 + 2] = {0U, + 1U, + 19U, + 181U, + 1159U, + 5641U, + 22363U, + 75517U, + 224143U, + 598417U, + 1462563U, + 3317445U, + 7059735U, + 14218905U, + 27298155U, + 50250765U, + 89129247U, + 152951073U, + 254831667U, + 413442773U, + 654862247U, + 1014889769U, + 1541911931U, + /*U*/ 1150204814U}; +/* N=10,K=10,h_memN10K10={0U,1U,19U,181U,1159U,5641U,22363U,75517U,224143U,598417U,1462563U,1658722U,}; */ + +/* N=6,K=2,*/ +RAM_ALIGN const UWord32 h_memN6K2[2 + 2] = {0U, 1U, 11U, /*U*/ 30U}; +/*N=6,K=1, h_memN6K1={0U,1U, 5U,}; */ + +RAM_ALIGN const UWord32 *const MPVQ_offs_ptr[M + 1] = {NULL /*0*/, NULL, NULL, NULL, NULL, NULL, + h_memN6K2, NULL, NULL, NULL, h_memN10K22, NULL, + NULL, NULL, NULL, NULL, h_memN16K12}; + +/*maxK coefficents for MPVQ de-indexing lookup */ +RAM_ALIGN const Word16 tabledKMAX[M + 1] = { + 0, 0, 0, 0, 0, 0, 2 /*N=6*/, 0, 0, 0, 22 /*N=10*/, 0, 0, 0, 0, 0, 12 /*N=16*/ }; +RAM_ALIGN const Word16 isqrt_Q16tab[1 + 64] = {/*table generated using ISqrt16 function + shift to Q16 */ + 32767, 32767, 32767, 32767, 32766, 29308, 26754, 24770, 23169, 21844, + 20723, 19759, 18918, 18176, 17515, 16921, 16383, 15894, 15446, 15034, + 14654, 14300, 13972, 13665, 13377, 13107, 12852, 12612, 12385, 12169, + 11965, 11770, 11584, 11407, 11238, 11077, 10922, 10773, 10631, 10493, + 10361, 10234, 10112, 9993, 9879, 9769, 9662, 9559, 9459, 9362, + 9268, 9176, 9088, 9001, 8918, 8836, 8757, 8680, 8605, 8532, + 8460, 8390, 8323, 8256, 8191}; + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 isqrt_Q31tab[1 + 64] = {/* 2^31 / sqrt(idx) */ + 2147483647, 2147483647, 1518500249, 1239850262, 1073741824, 960383883, + 876706528, 811672525, 759250124, 715827882, 679093956, 647490682, + 619925131, 595604800, 573939146, 554477893, 536870912, 520841288, + 506166749, 492666537, 480191941, 468619350, 457845052, 447781294, + 438353264, 429496729, 421156193, 413283420, 405836262, 398777702, + 392075078, 385699449, 379625062, 373828919, 368290407, 362990988, + 357913941, 353044136, 348367849, 343872591, 339546978, 335380599, + 331363920, 327488186, 323745341, 320127961, 316629189, 313242684, + 309962565, 306783378, 303700049, 300707858, 297802400, 294979564, + 292235509, 289566636, 286969573, 284441157, 281978417, 279578557, + 277238946, 274957105, 272730696, 270557508, 268435456 }; +#endif -const LC3_FLOAT hannOla_8k[28 / 2 + 1] = { - 0.0000000000, 0.0125360439, 0.0495155660, 0.1090842588, 0.1882550991, 0.2830581304, 0.3887395330, 0.5000000000, 0.6112604670, 0.7169418696, 0.8117449009, 0.8909157412, 0.9504844340, - 0.9874639561, 1.0000000000 }; - -const LC3_FLOAT hannOla_16k[56 / 2 + 1] = { - 0.0000000000, 0.0031438951, 0.0125360439, 0.0280583348, 0.0495155660, 0.0766379004, 0.1090842588, 0.1464466094, 0.1882550991, 0.2339839617, 0.2830581304, 0.3348604690, 0.3887395330, - 0.4440177619, 0.5000000000, 0.5559822381, 0.6112604670, 0.6651395310, 0.7169418696, 0.7660160383, 0.8117449009, 0.8535533906, 0.8909157412, 0.9233620996, 0.9504844340, 0.9719416652, - 0.9874639561, 0.9968561049, 1.0000000000 }; - -const LC3_FLOAT hannOla_24k[84 / 2 + 1] = { - 0.0000000000, 0.0013981014, 0.0055845869, 0.0125360439, 0.0222135971, 0.0345631257, 0.0495155660, 0.0669872981, 0.0868806128, 0.1090842588, 0.1334740641, 0.1599136311, 0.1882550991, - 0.2183399710, 0.2500000000, 0.2830581304, 0.3173294878, 0.3526224128, 0.3887395330, 0.4254788669, 0.4626349532, 0.5000000000, 0.5373650468, 0.5745211331, 0.6112604670, 0.6473775872, - 0.6826705122, 0.7169418696, 0.7500000000, 0.7816600290, 0.8117449009, 0.8400863689, 0.8665259359, 0.8909157412, 0.9131193872, 0.9330127019, 0.9504844340, 0.9654368743, 0.9777864029, - 0.9874639561, 0.9944154131, 0.9986018986, 1.0000000000 }; - -const LC3_FLOAT hannOla_32k[112 / 2 + 1] = { - 0.0000000000, 0.0007865925, 0.0031438951, 0.0070644907, 0.0125360439, 0.0195413390, 0.0280583348, 0.0380602337, 0.0495155660, 0.0623882890, 0.0766379004, 0.0922195655, 0.1090842588, - 0.1271789176, 0.1464466094, 0.1668267110, 0.1882550991, 0.2106643519, 0.2339839617, 0.2581405564, 0.2830581304, 0.3086582838, 0.3348604690, 0.3615822443, 0.3887395330, 0.4162468883, - 0.4440177619, 0.4719647764, 0.5000000000, 0.5280352236, 0.5559822381, 0.5837531117, 0.6112604670, 0.6384177557, 0.6651395310, 0.6913417162, 0.7169418696, 0.7418594436, 0.7660160383, - 0.7893356481, 0.8117449009, 0.8331732890, 0.8535533906, 0.8728210824, 0.8909157412, 0.9077804345, 0.9233620996, 0.9376117110, 0.9504844340, 0.9619397663, 0.9719416652, 0.9804586610, - 0.9874639561, 0.9929355093, 0.9968561049, 0.9992134075, 1.0000000000 }; - -const LC3_FLOAT hannOla_48k[168 / 2 + 1] = { - 0.0000000000, 0.0003496476, 0.0013981014, 0.0031438951, 0.0055845869, 0.0087167634, 0.0125360439, 0.0170370869, 0.0222135971, 0.0280583348, 0.0345631257, 0.0417188721, 0.0495155660, - 0.0579423032, 0.0669872981, 0.0766379004, 0.0868806128, 0.0977011101, 0.1090842588, 0.1210141384, 0.1334740641, 0.1464466094, 0.1599136311, 0.1738562944, 0.1882550991, 0.2030899072, - 0.2183399710, 0.2339839617, 0.2500000000, 0.2663656859, 0.2830581304, 0.3000539878, 0.3173294878, 0.3348604690, 0.3526224128, 0.3705904774, 0.3887395330, 0.4070441964, 0.4254788669, - 0.4440177619, 0.4626349532, 0.4813044029, 0.5000000000, 0.5186955971, 0.5373650468, 0.5559822381, 0.5745211331, 0.5929558036, 0.6112604670, 0.6294095226, 0.6473775872, 0.6651395310, - 0.6826705122, 0.6999460122, 0.7169418696, 0.7336343141, 0.7500000000, 0.7660160383, 0.7816600290, 0.7969100928, 0.8117449009, 0.8261437056, 0.8400863689, 0.8535533906, 0.8665259359, - 0.8789858616, 0.8909157412, 0.9022988899, 0.9131193872, 0.9233620996, 0.9330127019, 0.9420576968, 0.9504844340, 0.9582811279, 0.9654368743, 0.9719416652, 0.9777864029, 0.9829629131, - 0.9874639561, 0.9912832366, 0.9944154131, 0.9968561049, 0.9986018986, 0.9996503524, 1.0000000000 }; - -const LC3_FLOAT *hannOla_wins[5] = { hannOla_8k, hannOla_16k, hannOla_24k, hannOla_32k, hannOla_48k }; - -const LC3_FLOAT plc_tdc_lpc_8[17] = {1, 0.998890285693703, 0.995568526105076, 0.990056789412169, 0.982391584470799, 0.972623458066693, 0.960816439805232, 0.947047343167065, 0.931404933402306, 0.913988974871173, 0.894909172128633, 0.874284020464791, 0.852239582727672, 0.828908210053904, 0.804427224606163, 0.778937582561901, 0.752582535420797}; - -const LC3_FLOAT plc_tdc_lpc_16[17] = {1, 0.999722455898711, 0.998890285693703, 0.997504874399492, 0.995568526105076, 0.993084457588532, 0.990056789412169, 0.986490534532745, 0.982391584470799, 0.977766693092529, 0.972623458066693, 0.966970300067793, 0.960816439805232, 0.954171872966123, 0.947047343167065, 0.939454313017299, 0.931404933402306}; - -const LC3_FLOAT plc_tdc_lpc_24[17] = {1, 0.999876637554759, 0.999506641521283, 0.998890285693703, 0.998028026020383, 0.996920500041823, 0.995568526105076, 0.993973102356048, 0.992135405511397, 0.990056789412169, 0.987738783361644, 0.985183090250255, 0.982391584470799, 0.979366309627507, 0.976109476042902, 0.972623458066693, 0.968910791191297}; - -const LC3_FLOAT plc_tdc_lpc_32[17] = {1, 0.999930606751878, 0.999722455898711, 0.999375634094057, 0.998890285693703, 0.998266612655538, 0.997504874399492, 0.996605387627705, 0.995568526105076, 0.994394720400431, 0.993084457588532, 0.991638280913245, 0.990056789412169, 0.988340637503103, 0.986490534532745, 0.984507244288062, 0.982391584470799}; - -const LC3_FLOAT plc_tdc_lpc_48[17] = {1, 0.999969157961872, 0.999876637554759, 0.999722455898711, 0.999506641521283, 0.999229234348730, 0.998890285693703, 0.998489858239427, 0.998028026020383, 0.997504874399492, 0.996920500041823, 0.996275010884819, 0.995568526105076, 0.994801176081669, 0.993973102356048, 0.993084457588532, 0.992135405511397}; - -const LC3_FLOAT plc_tdc_lpc_96[17] = {1, 0.999992289401289, 0.999969157961872, 0.999930606751878, 0.999876637554759, 0.999807252867157, 0.999722455898711, 0.999622250571809, 0.999506641521283, 0.999375634094057, 0.999229234348730, 0.999067449055113, 0.998890285693703, 0.998697752455111, 0.998489858239427, 0.998266612655538, 0.998028026020383}; - -const LC3_FLOAT *plc_tdc_lpc_all[6] = {plc_tdc_lpc_8, plc_tdc_lpc_16, plc_tdc_lpc_24, plc_tdc_lpc_32, plc_tdc_lpc_48, plc_tdc_lpc_96}; - -const LC3_FLOAT plc_tdc_lpc_8_25ms[9] = {1, 0.998890285693703, 0.995568526105076, 0.990056789412169, 0.982391584470799, 0.972623458066693, 0.960816439805232, 0.947047343167065, 0.931404933402306}; - -const LC3_FLOAT plc_preemph_fac[] = {0.62, 0.72, 0.82, 0.92, 0.92, 0.92}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_8_10ms[81] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80}; -const LC3_INT ACC_COEFF_PER_BAND_PLC_16_10ms[81] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, - 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, - 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, - 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160}; -const LC3_INT ACC_COEFF_PER_BAND_PLC_24_10ms[81] = { - 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, - 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, - 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, - 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240}; -const LC3_INT ACC_COEFF_PER_BAND_PLC_32_10ms[81] = { - 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, - 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, - 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, - 252, 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316, 320}; -const LC3_INT ACC_COEFF_PER_BAND_PLC_48_10ms[81] = { - 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, - 126, 132, 138, 144, 150, 156, 162, 168, 174, 180, 186, 192, 198, 204, 210, 216, 222, 228, 234, 240, 246, - 252, 258, 264, 270, 276, 282, 288, 294, 300, 306, 312, 318, 324, 330, 336, 342, 348, 354, 360, 366, 372, - 378, 384, 390, 396 , 402, 408, 414, 420, 426, 432, 438, 444, 450, 456, 462, 468, 474, 480}; -const LC3_INT ACC_COEFF_PER_BAND_PLC_96_10ms[81] = { - 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, - 252, 264, 276, 288, 300, 312, 324, 336, 348, 360, 372, 384, 396, 408, 420, 432, 444, 456, 468, 480, 492, - 504, 516, 528, 540, 552, 564, 576, 588, 600, 612, 624, 636, 648, 660, 672, 684, 696, 708, 720, 732, 744, - 756, 768, 780, 792, 804, 816, 828, 840, 852, 864, 876, 888, 900, 912, 924, 936, 948, 960}; - -const LC3_INT* ACC_COEFF_PER_BAND_PLC[] = { - ACC_COEFF_PER_BAND_PLC_8_10ms, ACC_COEFF_PER_BAND_PLC_16_10ms, ACC_COEFF_PER_BAND_PLC_24_10ms, - ACC_COEFF_PER_BAND_PLC_32_10ms, ACC_COEFF_PER_BAND_PLC_48_10ms, ACC_COEFF_PER_BAND_PLC_96_10ms}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_8_2_5ms[21] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_16_2_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_24_2_5ms[61] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_32_2_5ms[81] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_48_2_5ms[61] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, - 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, - 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_96_2_5ms[81] = { - 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, - 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, - 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, - 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240}; - -const LC3_INT* ACC_COEFF_PER_BAND_PLC_2_5ms[] = { - ACC_COEFF_PER_BAND_PLC_8_2_5ms, ACC_COEFF_PER_BAND_PLC_16_2_5ms, ACC_COEFF_PER_BAND_PLC_24_2_5ms, - ACC_COEFF_PER_BAND_PLC_32_2_5ms, ACC_COEFF_PER_BAND_PLC_48_2_5ms, ACC_COEFF_PER_BAND_PLC_96_2_5ms}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_8_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_16_5ms[81] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_24_5ms[41] = {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, - 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, - 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_32_5ms[81] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, - 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, - 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, - 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_48_5ms[81] = { - 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, - 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, - 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, - 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240}; - -const LC3_INT ACC_COEFF_PER_BAND_PLC_96_5ms[81] = { - 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, - 126, 132, 138, 144, 150, 156, 162, 168, 174, 180, 186, 192, 198, 204, 210, 216, 222, 228, 234, 240, 246, - 252, 258, 264, 270, 276, 282, 288, 294, 300, 306, 312, 318, 324, 330, 336, 342, 348, 354, 360, 366, 372, - 378, 384, 390, 396, 402, 408, 414, 420, 426, 432, 438, 444, 450, 456, 462, 468, 474, 480}; - -const LC3_INT* ACC_COEFF_PER_BAND_PLC_5ms[] = { - ACC_COEFF_PER_BAND_PLC_8_5ms, ACC_COEFF_PER_BAND_PLC_16_5ms, ACC_COEFF_PER_BAND_PLC_24_5ms, - ACC_COEFF_PER_BAND_PLC_32_5ms, ACC_COEFF_PER_BAND_PLC_48_5ms, ACC_COEFF_PER_BAND_PLC_96_5ms}; - -const LC3_INT32 mdct_grp_bins[10] = { 4, 14, 24, 44, 84, 164, 244, 324, 404, 484 }; +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ] = {{80, 230, 380, 530, 680, 830}, + {500, 1025, 1550, 2075, 2600, 3125}, + {850, 1700, 2550, 3400, 4250, 5100}, + {189, 164, 155, 151, 148, 146}, + {1310, 3241, 5268, 7326, 9400, 11482}}; +# else +RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ] = {{80, 230, 380, 530, 680}, + {500, 1025, 1550, 2075, 2600}, + {850, 1700, 2550, 3400, 4250}, + {189, 164, 155, 151, 148}, + {1310, 3241, 5268, 7326, 9400}}; +# endif #if defined(CR8_A_PLC_FADEOUT_TUNING) -const LC3_INT16 plc_fadeout_param_maxlen[4] = {800, 400, 266, 200}; -const LC3_INT16 plc_fadeout_param_maxbytes[4] = {27, 14, 9, 7}; +const Word16 plc_fadeout_param_maxlen[4] = {800, 400, 266, 200}; +const Word16 plc_fadeout_param_maxbytes[4] = {27, 14, 9, 7}; #endif diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h index ace0f9383..8dee7e6eb 100644 --- a/lib_lc3plus/constants.h +++ b/lib_lc3plus/constants.h @@ -1,238 +1,402 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef CONSTANTS_H #define CONSTANTS_H -#include "options.h" -#include "wmc_auto.h" #include "defines.h" -#include "structs.h" - -/* DCT */ -extern const Complex dct2_16[16]; - -/* Ari coder */ -extern const LC3_INT16 ari_tns_order_cf[2][9]; -extern const LC3_INT16 ari_tns_freq_cf[8][18]; -extern const LC3_INT ari_spec_lookup_fl[4096]; -extern const LC3_INT16 ari_spec_cumfreq_fl[64][18]; -extern const LC3_INT ari_spec_bits_fl[64][17]; - -/* SNS */ -extern const LC3_FLOAT sns_W[6]; -extern const LC3_FLOAT *sns_preemph_all[6]; -extern const LC3_FLOAT sns_LFCB[8][32]; -extern const LC3_FLOAT sns_HFCB[8][32]; -extern const LC3_INT pvq_enc_A[16][11]; -extern const LC3_FLOAT idct_lookup[M][M]; - -/* 12.8 kHz resampler */ -extern const LC3_FLOAT lp_scale_factors[6]; - -extern const LC3_INT32 resamp_params[][4]; -extern const LC3_FLOAT *lp_filter[6]; -extern const LC3_FLOAT highpass50_filt_b[3]; -extern const LC3_FLOAT highpass50_filt_a[3]; -extern const LC3_INT up_fac[6]; - -/* TNS */ -extern const LC3_FLOAT quants_pts_tns[17]; -extern const LC3_INT huff_bits_tns[8][17]; -extern const LC3_INT order1_tns[8]; -extern const LC3_INT order2_tns[8]; -extern const LC3_FLOAT lagw_tns[9]; -extern const LC3_FLOAT quants_pts_tns[17]; -extern const LC3_FLOAT quants_thr_tns[18]; - -/* SNS */ -extern const LC3_FLOAT sns_vq_far_adj_gains_fl[8]; -extern const LC3_FLOAT sns_vq_near_adj_gains_fl[4]; -extern const LC3_FLOAT sns_vq_reg_lf_adj_gains_fl[4]; -extern const LC3_FLOAT q_g_sns[6]; -extern const LC3_FLOAT sns_vq_reg_adj_gains_fl[2]; -extern const LC3_FLOAT sns_dec_gains[4][8]; - -/* Global Gain */ -extern const LC3_INT gg_p1[6]; -extern const LC3_INT gg_p2[6]; -extern const LC3_INT gg_p3[6]; -extern const LC3_FLOAT gg_c[6]; -extern const LC3_FLOAT gg_d[6]; - -/* Olpa */ -extern const LC3_FLOAT olpa_down2[5]; -extern const LC3_FLOAT olpa_acw[98]; - -/* LTPF */ -extern const LC3_FLOAT conf_inter_filter_48[4][12]; -extern const LC3_FLOAT conf_inter_filter_32[4][8]; -extern const LC3_FLOAT conf_inter_filter_24[4][6]; -extern const LC3_FLOAT conf_inter_filter_16[4][4]; -extern const LC3_FLOAT conf_tilt_filter_48[4][11]; -extern const LC3_FLOAT conf_tilt_filter_32[4][7]; -extern const LC3_FLOAT conf_tilt_filter_24[4][5]; -extern const LC3_FLOAT conf_tilt_filter_16[4][3]; -extern const LC3_FLOAT inter4_1[33]; -extern const LC3_FLOAT enc_inter_filter[4][4]; - -/* Bandwidth Detector */ -extern const LC3_INT threshold_quiet[4]; -extern const LC3_INT threshold_brickwall[4]; -extern const LC3_INT brickwall_dist[4]; -extern const LC3_INT BW_warp_idx_start_16k[4]; -extern const LC3_INT BW_warp_idx_stop_16k[4]; -extern const LC3_INT BW_warp_idx_start_24k[4]; -extern const LC3_INT BW_warp_idx_stop_24k[4]; -extern const LC3_INT BW_warp_idx_start_32k[4]; -extern const LC3_INT BW_warp_idx_stop_32k[4]; -extern const LC3_INT BW_warp_idx_start_48k[4]; -extern const LC3_INT BW_warp_idx_stop_48k[4]; -extern const LC3_INT* BW_warp_idx_start_all[4]; -extern const LC3_INT* BW_warp_idx_stop_all[4]; - -extern const LC3_INT BW_warp_idx_start_16k_2_5ms[4]; -extern const LC3_INT BW_warp_idx_stop_16k_2_5ms[4]; -extern const LC3_INT BW_warp_idx_start_24k_2_5ms[4]; -extern const LC3_INT BW_warp_idx_stop_24k_2_5ms[4]; -extern const LC3_INT BW_warp_idx_start_32k_2_5ms[4]; -extern const LC3_INT BW_warp_idx_stop_32k_2_5ms[4]; -extern const LC3_INT BW_warp_idx_start_48k_2_5ms[4]; -extern const LC3_INT BW_warp_idx_stop_48k_2_5ms[4]; -extern const LC3_INT* BW_warp_idx_start_all_2_5ms[4]; -extern const LC3_INT* BW_warp_idx_stop_all_2_5ms[4]; -extern const LC3_INT BW_cutoff_bin_all_2_5ms_HR[MAX_BW_BANDS_NUMBER]; -extern const LC3_INT bands_number_2_5ms_HR[6]; - -extern const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER]; -extern const LC3_INT bands_number_2_5ms[5]; - - -extern const LC3_INT BW_warp_idx_start_16k_5ms[4]; -extern const LC3_INT BW_warp_idx_stop_16k_5ms[4]; -extern const LC3_INT BW_warp_idx_start_24k_5ms[4]; -extern const LC3_INT BW_warp_idx_stop_24k_5ms[4]; -extern const LC3_INT BW_warp_idx_start_32k_5ms[4]; -extern const LC3_INT BW_warp_idx_stop_32k_5ms[4]; -extern const LC3_INT BW_warp_idx_start_48k_5ms[4]; -extern const LC3_INT BW_warp_idx_stop_48k_5ms[4]; -extern const LC3_INT* BW_warp_idx_start_all_5ms[4]; -extern const LC3_INT* BW_warp_idx_stop_all_5ms[4]; -extern const LC3_INT BW_cutoff_bin_all_5ms[MAX_BW_BANDS_NUMBER]; -extern const LC3_INT bands_number_5ms[6]; -extern const LC3_INT BW_cutoff_bin_all_HR[MAX_BW_BANDS_NUMBER]; -extern const LC3_INT BW_cutoff_bin_all_5ms_HR[MAX_BW_BANDS_NUMBER]; -extern const LC3_INT BW_cutoff_bin_all[MAX_BW_BANDS_NUMBER]; -extern const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER]; + +#include "basop_util_lc3plus.h" + + +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 BW_cutoff_bin_all_HR[]; + +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_2_5ms[2]; +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_5ms[2]; +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_7_5ms[2]; +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA[2]; +#endif + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len[6]; +# else +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len[5]; +# endif +extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes[NUM_SAMP_FREQ]; +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960[6]; +# else +extern RAM_ALIGN const Word16 *const LowDelayShapes_n960[6]; +# endif + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[6]; +# else +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[5]; +# endif +extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_5ms[NUM_SAMP_FREQ]; +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_5ms[6]; +# else +extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_5ms[6]; +# endif +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[6]; +#else +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[5]; +#endif +extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_2_5ms[NUM_SAMP_FREQ]; +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_2_5ms[6]; +# else +extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_2_5ms[6]; +# endif + +# ifdef CR8_G_ADD_75MS +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_7_5ms[5]; +# else +extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_7_5ms[5]; +# endif + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_7_5ms[6]; +# else +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_7_5ms[5]; +# endif +extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_7_5ms[NUM_SAMP_FREQ]; +# endif + +extern RAM_ALIGN const Word16 NN_thresh; +extern RAM_ALIGN const Word16 NN_thresh_exp; +#ifdef CR8_E_TONE_DETECTOR +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 TD_HR_thresh_10ms; +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word32 TD_HR_thresh_7_5ms; +# endif +extern RAM_ALIGN const Word32 TD_HR_thresh_5ms; +extern RAM_ALIGN const Word32 TD_HR_thresh_2_5ms; +# endif /* ENABLE_HR_MODE */ +#endif /* CR8_E_TONE_DETECTOR */ +extern RAM_ALIGN const Word32 BW_thresh_quiet[4]; +extern RAM_ALIGN const Word16 BW_thresh_quiet_exp; +extern RAM_ALIGN const Word16 BW_thresh_brickwall[4]; + +extern RAM_ALIGN const Word16 BW_cutoff_bin_all[]; +extern RAM_ALIGN const Word16 BW_cutoff_bits_all[]; + +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 bands_number_2_5ms_HR[]; +#endif + +extern RAM_ALIGN const Word16 BW_brickwall_dist[4]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all[MAX_BW_BANDS_NUMBER - 1]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all[MAX_BW_BANDS_NUMBER - 1]; + +extern RAM_ALIGN const Word16 BW_brickwall_dist_5ms[4]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_5ms[MAX_BW_BANDS_NUMBER - 1]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_5ms[MAX_BW_BANDS_NUMBER - 1]; +extern RAM_ALIGN const Word16 BW_brickwall_dist_2_5ms[4]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_2_5ms[MAX_BW_BANDS_NUMBER - 1]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_2_5ms[MAX_BW_BANDS_NUMBER - 1]; #ifdef CR8_G_ADD_75MS -extern const LC3_INT BW_cutoff_bin_all_7_5ms[MAX_BW_BANDS_NUMBER]; -extern const LC3_INT bands_number_7_5ms[6]; -extern const LC3_INT bands_number_7_5ms_HR[6]; -extern const LC3_INT* BW_warp_idx_start_all_7_5ms[4]; -extern const LC3_INT* BW_warp_idx_stop_all_7_5ms[4]; -extern const LC3_INT brickwall_dist_7_5ms[4]; -extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_7_5ms[]; -#endif - -/* Arithmetic coding */ -extern const LC3_INT tns_cf[8][18]; -extern const LC3_INT tns_freq_cf[2][9]; - -/* MDCT Windows */ -extern const LC3_FLOAT MDCT_WINDOW_80[160]; -extern const LC3_FLOAT MDCT_WINDOW_160[320]; -extern const LC3_FLOAT MDCT_WINDOW_240[480]; -extern const LC3_FLOAT MDCT_WINDOW_320[640]; -extern const LC3_FLOAT MDCT_WINDOW_480[960]; -extern const LC3_FLOAT MDCT_WINDOW_960[1920]; -extern const LC3_FLOAT* MDCT_WINS_10ms[2][6]; -extern const LC3_INT MDCT_la_zeroes[6]; - -extern const LC3_FLOAT MDCT_WINDOW_80_2_5ms[40]; -extern const LC3_FLOAT MDCT_WINDOW_160_2_5ms[80]; -extern const LC3_FLOAT MDCT_WINDOW_240_2_5ms[120]; -extern const LC3_FLOAT MDCT_WINDOW_320_2_5ms[160]; -extern const LC3_FLOAT MDCT_WINDOW_480_2_5ms[240]; -extern const LC3_FLOAT* MDCT_WINS_2_5ms[2][6]; -extern const LC3_INT MDCT_la_zeroes_2_5ms[6]; - -extern const LC3_FLOAT MDCT_WINDOW_80_5ms[80]; -extern const LC3_FLOAT MDCT_WINDOW_160_5ms[160]; -extern const LC3_FLOAT MDCT_WINDOW_240_5ms[240]; -extern const LC3_FLOAT MDCT_WINDOW_320_5ms[320]; -extern const LC3_FLOAT MDCT_WINDOW_480_5ms[480]; -extern const LC3_FLOAT* MDCT_WINS_5ms[2][6]; -extern const LC3_INT MDCT_la_zeroes_5ms[6]; +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 BW_brickwall_dist_7_5ms[4]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_7_5ms[]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_7_5ms[]; +# endif +#endif + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq[MAX_BW_BANDS_NUMBER]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq[MAX_BW_BANDS_NUMBER]; + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_HR[2]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_HR[2]; + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms_HR[2]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms_HR[2]; + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms_HR[2]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms_HR[2]; +# endif + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms[MAX_BW_BANDS_NUMBER]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms[MAX_BW_BANDS_NUMBER]; + + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms[MAX_BW_BANDS_NUMBER]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms[MAX_BW_BANDS_NUMBER]; #ifdef CR8_G_ADD_75MS -extern const LC3_FLOAT* MDCT_WINS_7_5ms[2][6]; -extern const LC3_INT32 MDCT_la_zeroes_7_5ms[6]; +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_7_5ms[]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_7_5ms[]; +# endif #endif -extern const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6]; -extern const LC3_INT MDCT_WINDOWS_LENGTHS_7_5ms[6]; -extern const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6]; -extern const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6]; +extern RAM_ALIGN const Word16 Tab_esc_nb[4]; -/* Per band energy */ -extern const LC3_INT* ACC_COEFF_PER_BAND[6]; -extern const LC3_INT* ACC_COEFF_PER_BAND_HR[6]; +extern RAM_ALIGN const Word8 ari_spec_lookup[4096]; +extern RAM_ALIGN const UWord16 ari_spec_cumfreq[64][17]; +extern RAM_ALIGN const UWord16 ari_spec_freq[64][17]; +extern RAM_ALIGN const UWord16 ari_spec_bits[64][17]; -extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6]; -extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5]; +extern RAM_ALIGN const Word32 tnsAcfWindow_lc3plus[MAXLAG]; +extern RAM_ALIGN const Word16 ac_tns_order_bits[2][MAXLAG]; +extern RAM_ALIGN const Word16 ac_tns_order_freq[2][MAXLAG]; +extern RAM_ALIGN const Word16 ac_tns_order_cumfreq[2][MAXLAG]; +extern RAM_ALIGN const Word16 ac_tns_coef_bits[MAXLAG][TNS_COEF_RES]; +extern RAM_ALIGN const Word16 ac_tns_coef_freq[MAXLAG][TNS_COEF_RES]; +extern RAM_ALIGN const Word16 ac_tns_coef_cumfreq[MAXLAG][TNS_COEF_RES]; +extern RAM_ALIGN const Word16 tnsQuantPts[TNS_COEF_RES]; +extern RAM_ALIGN const Word16 tnsQuantThr[TNS_COEF_RES - 1]; + +extern RAM_ALIGN const Word16 *const lpc_pre_emphasis[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_pre_emphasis_e[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_2_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_2_5ms[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis_e[NUM_SAMP_FREQ]; #ifdef CR8_G_ADD_75MS -extern const LC3_INT* ACC_COEFF_PER_BAND_7_5ms_HR[6]; -extern const LC3_INT* ACC_COEFF_PER_BAND_7_5ms[5]; +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_7_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_7_5ms[NUM_SAMP_FREQ]; +# endif #endif -extern const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6]; -extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5]; +extern RAM_ALIGN const Word16 bands_nrg_scale[32]; + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 *const bands_offset_2_5ms_HR[2]; +extern RAM_ALIGN const Word16 *const bands_offset_5ms_HR[2]; +extern RAM_ALIGN const Word16 *const bands_offset_HR[2]; +# endif + +extern RAM_ALIGN const Word16 *const bands_offset[6]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max[NUM_OFFSETS]; + +extern RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const bands_offset_5ms[6]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_number_2_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const bands_offset_2_5ms[6]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_2_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_2_5ms[NUM_OFFSETS]; + +#ifdef CR8_G_ADD_75MS +#ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 bands_number_7_5ms[]; +# ifndef GENERATE_BAND_TABLES +extern RAM_ALIGN const Word16 *const bands_offset_7_5ms[5]; +# endif +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 bands_number_7_5ms_HR[]; +# ifndef GENERATE_BAND_TABLES +extern RAM_ALIGN const Word16 *const bands_offset_7_5ms_HR[2]; +# endif +# endif +#endif +#endif + +extern RAM_ALIGN const Word16 pitch_max[5]; +extern RAM_ALIGN const Word16 plc_preemph_fac[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 TDC_high_16[11]; +extern RAM_ALIGN const Word16 TDC_high_32[11]; +extern RAM_ALIGN const Word16 TDC_high_16_harm[11]; +extern RAM_ALIGN const Word16 TDC_high_32_harm[11]; + +extern RAM_ALIGN const Word32 *const lag_win[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 *const bands_offset_lin[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const bands_offset_lin_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const bands_offset_lin_2_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_2_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_2_5ms[NUM_SAMP_FREQ]; + +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 bands_offset_with_one_max_7_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_7_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 *const bands_offset_lin_7_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_7_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_7_5ms[NUM_SAMP_FREQ]; +# endif +#endif + +extern RAM_ALIGN const Word32 inv_odft_twiddle_80_re[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_80_im[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_60_re[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_60_im[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_40_re[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_40_im[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_20_re[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_20_im[M]; + +#ifdef SUBSET_WB +extern RAM_ALIGN const Word16 resamp_filt_16k[240]; +#else +extern RAM_ALIGN const Word16 resamp_filt_16k[1]; +#endif +#ifdef SUBSET_SSWB +extern RAM_ALIGN const Word16 resamp_filt_24k[240]; +#else +extern RAM_ALIGN const Word16 resamp_filt_24k[1]; +#endif +#ifdef SUBSET_SWB +extern RAM_ALIGN const Word16 resamp_filt_32k[240]; +#else +extern RAM_ALIGN const Word16 resamp_filt_32k[1]; +#endif +#ifdef SUBSET_FB +extern RAM_ALIGN const Word16 resamp_filt_48k[240]; +#else +extern RAM_ALIGN const Word16 resamp_filt_48k[1]; +#endif + +extern RAM_ALIGN const Word16 resamp_params[NUM_SAMP_FREQ][4]; +extern RAM_ALIGN const Word16 *const resamp_filts[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 highpass50_filt_num[3]; +extern RAM_ALIGN const Word16 highpass50_filt_den[2]; + +extern RAM_ALIGN const Word16 olpa_ac_weighting[98]; + +extern RAM_ALIGN const Word16 ltpf_ac_interp_filt[7][9]; +extern RAM_ALIGN const Word16 inter_filter[5][4][12]; +extern RAM_ALIGN const Word16 inter_filter_shift[5]; +extern RAM_ALIGN const Word16 inter_filter_len[5]; +extern RAM_ALIGN const Word16 tilt_filter[5][4][11]; +extern RAM_ALIGN const Word16 tilt_filter_len[5]; +extern RAM_ALIGN const Word16 gain_scale_fac[4]; +extern RAM_ALIGN const UWord16 pitch_scale[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 ltpf_overlap_len[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 sns_vq_reg_adj_scf[2]; +extern RAM_ALIGN const Word16 sns_vq_reg_lf_adj_scf[4]; +extern RAM_ALIGN const Word16 sns_vq_near_adj_scf[4]; +extern RAM_ALIGN const Word16 sns_vq_far_adj_scf[8]; +extern RAM_ALIGN const Word16 *const sns_gaintabPtr[4]; +extern RAM_ALIGN const Word16 sns_gainSz[4]; +extern RAM_ALIGN const Word16 sns_gainMSBbits[4]; +extern RAM_ALIGN const Word16 sns_gainLSBbits[4]; +extern RAM_ALIGN const Word16 sns_Kval[4][2]; +extern RAM_ALIGN const UWord32 sns_MPVQ_Sz[4][2]; + +extern RAM_ALIGN const Word16 st1SCF0_7_base5_32x8_Q11[256]; +extern RAM_ALIGN const Word16 st1SCF8_15_base5_32x8_Q11[256]; + +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 st1SCF0_7_base5_32x8_Q27[256]; +extern RAM_ALIGN const Word32 st1SCF8_15_base5_32x8_Q27[256]; +#endif + +/* PVQ deindexing tables */ +extern RAM_ALIGN const UWord32 h_memN16K12[12 + 2]; +extern RAM_ALIGN const UWord32 h_memN10K22[22 + 2]; +extern RAM_ALIGN const UWord32 h_memN6K2[2 + 2]; +extern RAM_ALIGN const Word16 tabledKMAX[16 + 1]; +extern RAM_ALIGN const UWord32 *const MPVQ_offs_ptr[16 + 1]; + +extern RAM_ALIGN const Word16 isqrt_Q16tab[1 + SQRT_EN_MAX_FX]; +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 isqrt_Q31tab[1 + SQRT_EN_MAX_FX]; +#endif + +extern RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 sqrt_table_phecu[]; +extern RAM_ALIGN const Word16 POW_ATT_TABLE0[]; +extern RAM_ALIGN const Word16 POW_ATT_TABLE1[]; +#ifdef PLC2_FADEOUT_IN_MS +#if PLC2_FADEOUT_IN_MS == 0 +extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[3]; +#else +#ifdef CR8_A_PLC_FADEOUT_TUNING +extern RAM_ALIGN const Word16 fade_scheme_tab_fx[24 / 2][3]; +extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[1+24/2]; +#else +extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[11]; +#endif + +#endif +#else +extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[3]; +#endif -/* Near Nyquist detector */ -extern const LC3_INT NN_thresh; -/* Tone detector */ -#ifdef CR8_E_TONE_DETECTOR -extern const LC3_INT32 TD_HR_thresh_10ms; -extern const LC3_INT32 TD_HR_thresh_7_5ms; -extern const LC3_INT32 TD_HR_thresh_5ms; -extern const LC3_INT32 TD_HR_thresh_2_5ms; -#endif // CR8_E_TONE_DETECTOR - -extern const LC3_INT32 xavg_N_grp[5]; -extern const LC3_FLOAT *hannOla_wins[5]; -extern const LC3_INT32 gwlpr[MAX_LGW+1]; #ifdef CR8_A_PLC_FADEOUT_TUNING -extern const LC3_INT16 fade_scheme_tab[24 / 2][3]; -extern const LC3_FLOAT scATHFx[MAX_LGW - 2]; -#endif -extern const LC3_INT32 mdct_grp_bins[10]; -extern const LC3_FLOAT* PhECU_whr16ms_wins[5]; - -extern const LC3_FLOAT plc_preemph_fac[]; -extern const LC3_INT* ACC_COEFF_PER_BAND_PLC[]; -extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_2_5ms[]; -extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_5ms[]; -extern const LC3_FLOAT *plc_tdc_lpc_all[6]; -extern const LC3_FLOAT plc_tdc_lpc_8[17]; -extern const LC3_FLOAT plc_tdc_lpc_16[17]; -extern const LC3_FLOAT plc_tdc_lpc_24[17]; -extern const LC3_FLOAT plc_tdc_lpc_32[17]; -extern const LC3_FLOAT plc_tdc_lpc_48[17]; -extern const LC3_FLOAT plc_tdc_lpc_96[17]; -extern const LC3_FLOAT plc_tdc_lpc_8_25ms[9]; +extern RAM_ALIGN const Word16 scATHFx[7]; +#endif + +extern RAM_ALIGN const Word16 e_tot_headroom[]; +extern RAM_ALIGN const Word16 xfp_wE_MDCT2FFTQ11[]; + +extern RAM_ALIGN const Word16 num_FsByResQ0[5]; +extern RAM_ALIGN const Word16 *const LprotSzPtr; +extern RAM_ALIGN const Word16 InvLprot_Q22[5]; +extern RAM_ALIGN const Word16 PhEcuFftScale[5]; +extern RAM_ALIGN const Word16 oneOverFrameQ15Tab[5]; +extern RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxDnShift[]; +extern RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxScaleQ15[]; +extern RAM_ALIGN const Word16 PhEcu_frac_thr_rise_lin_Q15[]; +extern RAM_ALIGN const Word16 PhEcu_frac_thr_decay_lin_Q15[]; + +extern RAM_ALIGN const Word16 mdct_grp_bins_fx[]; +extern RAM_ALIGN const Word16 xavg_N_grp_fx[]; +extern RAM_ALIGN const Word16 spec_shape_headroom[]; +extern RAM_ALIGN const Word16 rectLengthTab[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 hamm_len2Tab[]; + +#ifndef CR10_A_ATTENUATION_CURVE_SELECTOR +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH +extern RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_5MS[30]; +extern RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_2_5MS[60]; +#endif +#endif +extern RAM_ALIGN const Word16 gw_len_inv_shift_fx[]; +extern RAM_ALIGN const Word16 gwlpr_fx[]; + +extern RAM_ALIGN const Word16 sin_quarterQ15_fx[]; +extern RAM_ALIGN const Word16 sincos_lowres_tab_sinQ15_fx[]; + +extern RAM_ALIGN const Word16 *const PhECU_wins[5][3]; + +extern RAM_ALIGN const Word16 *const w_new[]; +extern RAM_ALIGN const Word16 *const w_old[]; + +/* extern RAM_ALIGN const Word16 WORK_LEN[]; */ +extern RAM_ALIGN const Word16 COPY_LEN[]; +extern RAM_ALIGN const Word16 OLA_LEN[]; #if defined(CR8_A_PLC_FADEOUT_TUNING) -extern const LC3_INT16 plc_fadeout_param_maxlen[4]; -extern const LC3_INT16 plc_fadeout_param_maxbytes[4]; +extern const Word16 plc_fadeout_param_maxlen[4]; +extern const Word16 plc_fadeout_param_maxbytes[4]; +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +extern RAM_ALIGN const Word16 PLC_FADEOUT_TYPE_2_SELECTOR; #endif #endif /* CONSTANTS_H */ diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c index c0ee62c62..05f7cce49 100644 --- a/lib_lc3plus/cutoff_bandwidth.c +++ b/lib_lc3plus/cutoff_bandwidth.c @@ -1,28 +1,26 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" #include "functions.h" -void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin) +void process_cutoff_bandwidth(Word32 d_fx[], Word16 len, Word16 bw_bin) { - LC3_INT i; - + Counter i = 0; if (len > bw_bin){ + /* roll off */ for (i = -1; i < 3; i++) { - d_fl[bw_bin + i] = d_fl[bw_bin + i] * LC3_POW(2, -(i + 2)); + d_fx[bw_bin + i] = L_shr(d_fx[bw_bin + i], add(i, 2)); } for (i = bw_bin + 3; i < len; i++) { - d_fl[i] = 0; + d_fx[i] = 0; move32(); } } } + diff --git a/lib_lc3plus/dct2_fx.c b/lib_lc3plus/dct2_fx.c new file mode 100644 index 000000000..c301c2aeb --- /dev/null +++ b/lib_lc3plus/dct2_fx.c @@ -0,0 +1,473 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void idct16_fx(const Word16 *in, Word16 *out) +{ + Dyn_Mem_Deluxe_In( + Word16 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; + Word16 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15; + ); + + a8 = add(mult_r(in[1], 1136), mult_r(in[15], -11529)); /* Sπ/32/√8 -S15π/32/√8 */ + a9 = add(mult_r(in[9], 8956), mult_r(in[7], -7350)); /* S9π/32/√8 -S7π/32/√8 */ + a10 = add(mult_r(in[5], 5461), mult_r(in[11], -10217)); /* S5π/32/√8 -S11π/32/√8 */ + a11 = add(mult_r(in[13], 11086), mult_r(in[3], -3363)); /* S13π/32/√8 -S3π/32/√8 */ + a12 = add(mult_r(in[3], 11086), mult_r(in[13], 3363)); /* C3π/32/√8 C13π/32/√8 */ + a13 = add(mult_r(in[11], 5461), mult_r(in[5], 10217)); /* C11π/32/√8 C5π/32/√8 */ + a14 = add(mult_r(in[7], 8956), mult_r(in[9], 7350)); /* C7π/32/√8 C9π/32/√8 */ + a15 = add(mult_r(in[15], 1136), mult_r(in[1], 11529)); /* C15π/32/√8 Cπ/32/√8 */ + + b4 = add(mult_r(in[2], 2260), mult_r(in[14], -11363)); /* Sπ/16/√8 -S7π/16/√8 */ + b5 = add(mult_r(in[10], 9633), mult_r(in[6], -6436)); /* S5π/16/√8 -S3π/16/√8 */ + b6 = add(mult_r(in[6], 9633), mult_r(in[10], 6436)); /* C3π/16/√8 C5π/16/√8 */ + b7 = add(mult_r(in[14], 2260), mult_r(in[2], 11363)); /* C7π/16/√8 Cπ/16/√8 */ + b8 = add(a9, a8); + b9 = sub(a8, a9); + b10 = sub(a11, a10); + b11 = add(a10, a11); + b12 = add(a13, a12); + b13 = sub(a12, a13); + b14 = sub(a15, a14); + b15 = add(a14, a15); + + a0 = add(mult_r(in[0], 8192), mult_r(in[8], 8192)); /* Cπ/4/√8 Cπ/4/√8 */ + a1 = add(mult_r(in[8], -8192), mult_r(in[0], 8192)); /* -Cπ/4/√8 Cπ/4/√8 */ + a2 = add(mult_r(in[4], 4433), mult_r(in[12], -10703)); /* Sπ/8/√8 -S3π/8/√8 */ + a3 = add(mult_r(in[12], 4433), mult_r(in[4], 10703)); /* C3π/8/√8 Cπ/8/√8 */ + a4 = add(b5, b4); + a5 = sub(b4, b5); + a6 = sub(b7, b6); + a7 = add(b6, b7); + a8 = b8; move16(); + a9 = add(mult_r(b9, -30274), mult_r(b14, 12540)); /* -Cπ/8 C3π/8 */ + a10 = add(mult_r(b10, -12540), mult_r(b13, -30274)); /* -Sπ/8 -S3π/8 */ + a11 = b11; move16(); + a12 = b12; move16(); + a13 = add(mult_r(b13, 12540), mult_r(b10, -30274)); /* C3π/8 -Cπ/8 */ + a14 = add(mult_r(b14, 30274), mult_r(b9, 12540)); /* S3π/8 Sπ/8 */ + a15 = b15; move16(); + + b0 = add(a3, a0); + b1 = add(a2, a1); + b2 = sub(a1, a2); + b3 = sub(a0, a3); + b4 = a4; move16(); + b5 = add(mult_r(a5, -23170), mult_r(a6, 23170)); /* -Cπ/4 Cπ/4 */ + b6 = add(mult_r(a6, 23170), mult_r(a5, 23170)); /* Cπ/4 Cπ/4 */ + b7 = a7; move16(); + b8 = add(a11, a8); + b9 = add(a10, a9); + b10 = sub(a9, a10); + b11 = sub(a8, a11); + b12 = sub(a15, a12); + b13 = sub(a14, a13); + b14 = add(a13, a14); + b15 = add(a12, a15); + + a0 = add(b7, b0); + a1 = add(b6, b1); + a2 = add(b5, b2); + a3 = add(b4, b3); + a4 = sub(b3, b4); + a5 = sub(b2, b5); + a6 = sub(b1, b6); + a7 = sub(b0, b7); + a10 = add(mult_r(b10, -23170), mult_r(b13, 23170)); /* -Cπ/4 Cπ/4 */ + a11 = add(mult_r(b11, -23170), mult_r(b12, 23170)); /* -Cπ/4 Cπ/4 */ + a12 = add(mult_r(b12, 23170), mult_r(b11, 23170)); /* Cπ/4 Cπ/4 */ + a13 = add(mult_r(b13, 23170), mult_r(b10, 23170)); /* Cπ/4 Cπ/4 */ + + out[0] = add(b15, a0); move16(); + out[1] = add(b14, a1); move16(); + out[2] = add(a13, a2); move16(); + out[3] = add(a12, a3); move16(); + out[4] = add(a11, a4); move16(); + out[5] = add(a10, a5); move16(); + out[6] = add(b9, a6); move16(); + out[7] = add(b8, a7); move16(); + out[8] = sub(a7, b8); move16(); + out[9] = sub(a6, b9); move16(); + out[10] = sub(a5, a10); move16(); + out[11] = sub(a4, a11); move16(); + out[12] = sub(a3, a12); move16(); + out[13] = sub(a2, a13); move16(); + out[14] = sub(a1, b14); move16(); + out[15] = sub(a0, b15); move16(); + + Dyn_Mem_Deluxe_Out(); +} + +void dct32_fx(const Word32 *in, Word32 *out) +{ + Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; + Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;); + + a0 = L_add(in[15], in[0]); + a1 = L_add(in[14], in[1]); + a2 = L_add(in[13], in[2]); + a3 = L_add(in[12], in[3]); + a4 = L_add(in[11], in[4]); + a5 = L_add(in[10], in[5]); + a6 = L_add(in[9], in[6]); + a7 = L_add(in[8], in[7]); + a10 = L_sub(in[5], in[10]); + a11 = L_sub(in[4], in[11]); + a12 = L_sub(in[3], in[12]); + a13 = L_sub(in[2], in[13]); + + b0 = L_add(a7, a0); + b1 = L_add(a6, a1); + b2 = L_add(a5, a2); + b3 = L_add(a4, a3); + b4 = L_sub(a3, a4); +#ifdef CR9_C_FIX_DCT2_OVERFLOW + b5 = L_sub_sat(a2, a5); +#else + b5 = L_sub(a2, a5); +#endif +#ifdef CR9_C_FIX_DCT2_OVERFLOW + b6 = L_sub_sat(a1, a6); +#else + b6 = L_sub(a1, a6); +#endif + b7 = L_sub(a0, a7); + b8 = L_sub(in[7], in[8]); + b9 = L_sub(in[6], in[9]); + b10 = L_add(Mpy_32_16_lc3plus(a10, -23170), Mpy_32_16_lc3plus(a13, 23170)); /* -Cπ/4 Cπ/4 */ + b11 = L_add(Mpy_32_16_lc3plus(a11, -23170), Mpy_32_16_lc3plus(a12, 23170)); /* -Cπ/4 Cπ/4 */ + b12 = L_add(Mpy_32_16_lc3plus(a12, 23170), Mpy_32_16_lc3plus(a11, 23170)); /* Cπ/4 Cπ/4 */ + b13 = L_add(Mpy_32_16_lc3plus(a13, 23170), Mpy_32_16_lc3plus(a10, 23170)); /* Cπ/4 Cπ/4 */ + b14 = L_sub(in[1], in[14]); + b15 = L_sub(in[0], in[15]); + + a0 = L_add(b3, b0); + a1 = L_add(b2, b1); + a2 = L_sub(b1, b2); + a3 = L_sub_sat(b0, b3); + a4 = b4; + move16(); + a5 = L_add(Mpy_32_16_lc3plus(b5, -23170), Mpy_32_16_lc3plus(b6, 23170)); /* -Cπ/4 Cπ/4 */ + a6 = L_add(Mpy_32_16_lc3plus(b6, 23170), Mpy_32_16_lc3plus(b5, 23170)); /* Cπ/4 Cπ/4 */ + a7 = b7; + move16(); + a8 = L_add(b11, b8); + a9 = L_add(b10, b9); + a10 = L_sub(b9, b10); + a11 = L_sub(b8, b11); + a12 = L_sub(b15, b12); + a13 = L_sub(b14, b13); + a14 = L_add(b13, b14); + a15 = L_add(b12, b15); + + out[0] = L_add(Mpy_32_16_lc3plus(a0, 8192), Mpy_32_16_lc3plus(a1, 8192)); + move16(); /* Cπ/4/√8 Cπ/4/√8 */ + out[8] = L_add(Mpy_32_16_lc3plus(a1, -8192), Mpy_32_16_lc3plus(a0, 8192)); + move16(); /* -Cπ/4/√8 Cπ/4/√8 */ + out[4] = L_add(Mpy_32_16_lc3plus(a2, 4433), Mpy_32_16_lc3plus(a3, 10703)); + move16(); /* Sπ/8/√8 Cπ/8/√8 */ + out[12] = L_add(Mpy_32_16_lc3plus(a3, 4433), Mpy_32_16_lc3plus(a2, -10703)); + move16(); /* C3π/8/√8 -S3π/8/√8 */ + b4 = L_add(a5, a4); + b5 = L_sub(a4, a5); + b6 = L_sub_sat(a7, a6); + b7 = L_add(a6, a7); + b8 = a8; + move16(); + b9 = L_add(Mpy_32_16_lc3plus(a9, -30274), Mpy_32_16_lc3plus(a14, 12540)); /* -Cπ/8 Sπ/8 */ + b10 = L_add(Mpy_32_16_lc3plus(a10, -12540), Mpy_32_16_lc3plus(a13, -30274)); /* -Sπ/8 -Cπ/8 */ + b11 = a11; + move16(); + b12 = a12; + move16(); + b13 = L_add(Mpy_32_16_lc3plus(a13, 12540), Mpy_32_16_lc3plus(a10, -30274)); /* C3π/8 -S3π/8 */ + b14 = L_add(Mpy_32_16_lc3plus(a14, 30274), Mpy_32_16_lc3plus(a9, 12540)); /* S3π/8 C3π/8 */ + b15 = a15; + move16(); + + out[2] = L_add(Mpy_32_16_lc3plus(b4, 2260), Mpy_32_16_lc3plus(b7, 11363)); + move16(); /* Sπ/16/√8 Cπ/16/√8 */ + out[10] = L_add(Mpy_32_16_lc3plus(b5, 9633), Mpy_32_16_lc3plus(b6, 6436)); + move16(); /* S5π/16/√8 C5π/16/√8 */ + out[6] = L_add(Mpy_32_16_lc3plus(b6, 9633), Mpy_32_16_lc3plus(b5, -6436)); + move16(); /* C3π/16/√8 -S3π/16/√8 */ + out[14] = L_add(Mpy_32_16_lc3plus(b7, 2260), Mpy_32_16_lc3plus(b4, -11363)); + move16(); /* C7π/16/√8 -S7π/16/√8 */ + + a8 = L_add_sat(b9, b8); + a9 = L_sub_sat(b8, b9); + a10 = L_sub_sat(b11, b10); + a11 = L_add_sat(b10, b11); + a12 = L_add_sat(b13, b12); + a13 = L_sub_sat(b12, b13); + a14 = L_sub_sat(b15, b14); + a15 = L_add_sat(b14, b15); + + out[1] = L_add(Mpy_32_16_lc3plus(a8, 1136), Mpy_32_16_lc3plus(a15, 11529)); + move16(); /* Sπ/32/√8 Cπ/32/√8 */ + out[9] = L_add(Mpy_32_16_lc3plus(a9, 8956), Mpy_32_16_lc3plus(a14, 7350)); + move16(); /* S9π/32/√8 C9π/32/√8 */ + out[5] = L_add(Mpy_32_16_lc3plus(a10, 5461), Mpy_32_16_lc3plus(a13, 10217)); + move16(); /* S5π/32/√8 C5π/32/√8 */ + out[13] = L_add(Mpy_32_16_lc3plus(a11, 11086), Mpy_32_16_lc3plus(a12, 3363)); + move16(); /* S13π/32/√8 C13π/32/√8 */ + out[3] = L_add(Mpy_32_16_lc3plus(a12, 11086), Mpy_32_16_lc3plus(a11, -3363)); + move16(); /* C3π/32/√8 -S3π/32/√8 */ + out[11] = L_add(Mpy_32_16_lc3plus(a13, 5461), Mpy_32_16_lc3plus(a10, -10217)); + move16(); /* C11π/32/√8 -S11π/32/√8 */ + out[7] = L_add(Mpy_32_16_lc3plus(a14, 8956), Mpy_32_16_lc3plus(a9, -7350)); + move16(); /* C7π/32/√8 -S7π/32/√8 */ + out[15] = L_add(Mpy_32_16_lc3plus(a15, 1136), Mpy_32_16_lc3plus(a8, -11529)); + move16(); /* C15π/32/√8 -S15/32/√8 */ + + Dyn_Mem_Deluxe_Out(); +} + +void idct32_fx(const Word32 *in, Word32 *out) +{ + Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; + Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;); + + a8 = L_add(Mpy_32_16_lc3plus(in[1], 1136), Mpy_32_16_lc3plus(in[15], -11529)); /* Sπ/32/√8 -S15π/32/√8 */ + a9 = L_add(Mpy_32_16_lc3plus(in[9], 8956), Mpy_32_16_lc3plus(in[7], -7350)); /* S9π/32/√8 -S7π/32/√8 */ + a10 = L_add(Mpy_32_16_lc3plus(in[5], 5461), Mpy_32_16_lc3plus(in[11], -10217)); /* S5π/32/√8 -S11π/32/√8 */ + a11 = L_add(Mpy_32_16_lc3plus(in[13], 11086), Mpy_32_16_lc3plus(in[3], -3363)); /* S13π/32/√8 -S3π/32/√8 */ + a12 = L_add(Mpy_32_16_lc3plus(in[3], 11086), Mpy_32_16_lc3plus(in[13], 3363)); /* C3π/32/√8 C13π/32/√8 */ + a13 = L_add(Mpy_32_16_lc3plus(in[11], 5461), Mpy_32_16_lc3plus(in[5], 10217)); /* C11π/32/√8 C5π/32/√8 */ + a14 = L_add(Mpy_32_16_lc3plus(in[7], 8956), Mpy_32_16_lc3plus(in[9], 7350)); /* C7π/32/√8 C9π/32/√8 */ + a15 = L_add(Mpy_32_16_lc3plus(in[15], 1136), Mpy_32_16_lc3plus(in[1], 11529)); /* C15π/32/√8 Cπ/32/√8 */ + + b4 = L_add(Mpy_32_16_lc3plus(in[2], 2260), Mpy_32_16_lc3plus(in[14], -11363)); /* Sπ/16/√8 -S7π/16/√8 */ + b5 = L_add(Mpy_32_16_lc3plus(in[10], 9633), Mpy_32_16_lc3plus(in[6], -6436)); /* S5π/16/√8 -S3π/16/√8 */ + b6 = L_add(Mpy_32_16_lc3plus(in[6], 9633), Mpy_32_16_lc3plus(in[10], 6436)); /* C3π/16/√8 C5π/16/√8 */ + b7 = L_add(Mpy_32_16_lc3plus(in[14], 2260), Mpy_32_16_lc3plus(in[2], 11363)); /* C7π/16/√8 Cπ/16/√8 */ + b8 = L_add(a9, a8); + b9 = L_sub(a8, a9); + b10 = L_sub(a11, a10); + b11 = L_add(a10, a11); + b12 = L_add(a13, a12); + b13 = L_sub(a12, a13); + b14 = L_sub(a15, a14); + b15 = L_add(a14, a15); + + a0 = L_add(Mpy_32_16_lc3plus(in[0], 8192), Mpy_32_16_lc3plus(in[8], 8192)); /* Cπ/4/√8 Cπ/4/√8 */ + a1 = L_add(Mpy_32_16_lc3plus(in[8], -8192), Mpy_32_16_lc3plus(in[0], 8192)); /* -Cπ/4/√8 Cπ/4/√8 */ + a2 = L_add(Mpy_32_16_lc3plus(in[4], 4433), Mpy_32_16_lc3plus(in[12], -10703)); /* Sπ/8/√8 -S3π/8/√8 */ + a3 = L_add(Mpy_32_16_lc3plus(in[12], 4433), Mpy_32_16_lc3plus(in[4], 10703)); /* C3π/8/√8 Cπ/8/√8 */ + a4 = L_add(b5, b4); + a5 = L_sub(b4, b5); + a6 = L_sub(b7, b6); + a7 = L_add(b6, b7); + a8 = b8; + move32(); + a9 = L_add(Mpy_32_16_lc3plus(b9, -30274), Mpy_32_16_lc3plus(b14, 12540)); /* -Cπ/8 C3π/8 */ + a10 = L_add(Mpy_32_16_lc3plus(b10, -12540), Mpy_32_16_lc3plus(b13, -30274)); /* -Sπ/8 -S3π/8 */ + a11 = b11; + move32(); + a12 = b12; + move32(); + a13 = L_add(Mpy_32_16_lc3plus(b13, 12540), Mpy_32_16_lc3plus(b10, -30274)); /* C3π/8 -Cπ/8 */ + a14 = L_add(Mpy_32_16_lc3plus(b14, 30274), Mpy_32_16_lc3plus(b9, 12540)); /* S3π/8 Sπ/8 */ + a15 = b15; + move32(); + + b0 = L_add(a3, a0); + b1 = L_add(a2, a1); + b2 = L_sub(a1, a2); + b3 = L_sub(a0, a3); + b4 = a4; + move32(); + b5 = L_add(Mpy_32_16_lc3plus(a5, -23170), Mpy_32_16_lc3plus(a6, 23170)); /* -Cπ/4 Cπ/4 */ + b6 = L_add(Mpy_32_16_lc3plus(a6, 23170), Mpy_32_16_lc3plus(a5, 23170)); /* Cπ/4 Cπ/4 */ + b7 = a7; + move32(); + b8 = L_add(a11, a8); + b9 = L_add(a10, a9); + b10 = L_sub(a9, a10); + b11 = L_sub(a8, a11); + b12 = L_sub(a15, a12); + b13 = L_sub(a14, a13); + b14 = L_add(a13, a14); + b15 = L_add(a12, a15); + + a0 = L_add(b7, b0); + a1 = L_add(b6, b1); + a2 = L_add(b5, b2); + a3 = L_add(b4, b3); + a4 = L_sub(b3, b4); + a5 = L_sub(b2, b5); + a6 = L_sub(b1, b6); + a7 = L_sub(b0, b7); + a10 = L_add(Mpy_32_16_lc3plus(b10, -23170), Mpy_32_16_lc3plus(b13, 23170)); /* -Cπ/4 Cπ/4 */ + a11 = L_add(Mpy_32_16_lc3plus(b11, -23170), Mpy_32_16_lc3plus(b12, 23170)); /* -Cπ/4 Cπ/4 */ + a12 = L_add(Mpy_32_16_lc3plus(b12, 23170), Mpy_32_16_lc3plus(b11, 23170)); /* Cπ/4 Cπ/4 */ + a13 = L_add(Mpy_32_16_lc3plus(b13, 23170), Mpy_32_16_lc3plus(b10, 23170)); /* Cπ/4 Cπ/4 */ + + out[0] = L_add(b15, a0); + move32(); + out[1] = L_add(b14, a1); + move32(); + out[2] = L_add(a13, a2); + move32(); + out[3] = L_add(a12, a3); + move32(); + out[4] = L_add(a11, a4); + move32(); + out[5] = L_add(a10, a5); + move32(); + out[6] = L_add(b9, a6); + move32(); + out[7] = L_add(b8, a7); + move32(); + out[8] = L_sub(a7, b8); + move32(); + out[9] = L_sub(a6, b9); + move32(); + out[10] = L_sub(a5, a10); + move32(); + out[11] = L_sub(a4, a11); + move32(); + out[12] = L_sub(a3, a12); + move32(); + out[13] = L_sub(a2, a13); + move32(); + out[14] = L_sub(a1, b14); + move32(); + out[15] = L_sub(a0, b15); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +void idct32_32_fx(const Word32 *in, Word32 *out) +{ + Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; + Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;); + + /*round(sin(pi*(1:16)/32)/sqrt(8)*2^31) = + 74419526 148122351 220398677 290552444 357908031 421816769 481663180 536870912 + 586908283 631293407 669598830 701455651 726557070 744661347 755594128 759250125 + */ + /*ound(cos(pi*(1:16)/32)/sqrt(8)*2^31) = + 755594128 744661347 726557070 701455651 669598830 631293407 586908283 536870912 + 481663180 421816769 357908031 290552444 220398677 148122351 74419526 0 + */ + + a8 = L_add(Mpy_32_32_lc3plus(in[1], 74419526), Mpy_32_32_lc3plus(in[15], -755594128)); /* Sπ/32/√8 -S15π/32/√8 */ + a9 = L_add(Mpy_32_32_lc3plus(in[9], 586908283), Mpy_32_32_lc3plus(in[7], -481663180)); /* S9π/32/√8 -S7π/32/√8 */ + a10 = L_add(Mpy_32_32_lc3plus(in[5], 357908031), Mpy_32_32_lc3plus(in[11], -669598830)); /* S5π/32/√8 -S11π/32/√8 */ + a11 = L_add(Mpy_32_32_lc3plus(in[13], 726557070), Mpy_32_32_lc3plus(in[3], -220398677)); /* S13π/32/√8 -S3π/32/√8 */ + + a12 = L_add(Mpy_32_32_lc3plus(in[3], 726557070), Mpy_32_32_lc3plus(in[13], 220398677)); /* C3π/32/√8 C13π/32/√8 */ + a13 = L_add(Mpy_32_32_lc3plus(in[11], 357908031), Mpy_32_32_lc3plus(in[5], 669598830)); /* C11π/32/√8 C5π/32/√8 */ + a14 = L_add(Mpy_32_32_lc3plus(in[7], 586908283), Mpy_32_32_lc3plus(in[9], 481663180)); /* C7π/32/√8 C9π/32/√8 */ + a15 = L_add(Mpy_32_32_lc3plus(in[15], 74419526), Mpy_32_32_lc3plus(in[1], 755594128)); /* C15π/32/√8 Cπ/32/√8 */ + + b4 = L_add(Mpy_32_32_lc3plus(in[2], 148122351), Mpy_32_32_lc3plus(in[14], -744661347)); /* Sπ/16/√8 -S7π/16/√8 */ + b5 = L_add(Mpy_32_32_lc3plus(in[10], 631293407), Mpy_32_32_lc3plus(in[6], -421816769)); /* S5π/16/√8 -S3π/16/√8 */ + b6 = L_add(Mpy_32_32_lc3plus(in[6], 631293407), Mpy_32_32_lc3plus(in[10], 421816769)); /* C3π/16/√8 C5π/16/√8 */ + b7 = L_add(Mpy_32_32_lc3plus(in[14], 148122351), Mpy_32_32_lc3plus(in[2], 744661347)); /* C7π/16/√8 Cπ/16/√8 */ + b8 = L_add(a9, a8); + b9 = L_sub(a8, a9); + b10 = L_sub(a11, a10); + b11 = L_add(a10, a11); + b12 = L_add(a13, a12); + b13 = L_sub(a12, a13); + b14 = L_sub(a15, a14); + b15 = L_add(a14, a15); + + a0 = L_add(Mpy_32_32_lc3plus(in[0], 536870912), Mpy_32_32_lc3plus(in[8], 536870912)); /* Cπ/4/√8 Cπ/4/√8 */ + a1 = L_add(Mpy_32_32_lc3plus(in[8], -536870912), Mpy_32_32_lc3plus(in[0], 536870912)); /* -Cπ/4/√8 Cπ/4/√8 */ + a2 = L_add(Mpy_32_32_lc3plus(in[4], 290552444), Mpy_32_32_lc3plus(in[12], -701455651)); /* Sπ/8/√8 -S3π/8/√8 */ + a3 = L_add(Mpy_32_32_lc3plus(in[12], 290552444), Mpy_32_32_lc3plus(in[4], 701455651)); /* C3π/8/√8 Cπ/8/√8 */ + a4 = L_add(b5, b4); + a5 = L_sub(b4, b5); + a6 = L_sub(b7, b6); + a7 = L_add(b6, b7); + a8 = b8; + move32(); + a9 = L_add(Mpy_32_32_lc3plus(b9, -1984016189), Mpy_32_32_lc3plus(b14, 821806413)); /* -Cπ/8 C3π/8 */ + a10 = L_add(Mpy_32_32_lc3plus(b10, -821806413), Mpy_32_32_lc3plus(b13, -1984016189)); /* -Sπ/8 -S3π/8 */ + a11 = b11; + move32(); + a12 = b12; + move32(); + a13 = L_add(Mpy_32_32_lc3plus(b13, 821806413), Mpy_32_32_lc3plus(b10, -1984016189)); /* C3π/8 -Cπ/8 */ + a14 = L_add(Mpy_32_32_lc3plus(b14, 1984016189), Mpy_32_32_lc3plus(b9, 821806413)); /* S3π/8 Sπ/8 */ + a15 = b15; + move32(); + + b0 = L_add(a3, a0); + b1 = L_add(a2, a1); + b2 = L_sub(a1, a2); + b3 = L_sub(a0, a3); + b4 = a4; + move32(); + b5 = L_add(Mpy_32_32_lc3plus(a5, -1518500250), Mpy_32_32_lc3plus(a6, 1518500250)); /* -Cπ/4 Cπ/4 */ + b6 = L_add(Mpy_32_32_lc3plus(a6, 1518500250), Mpy_32_32_lc3plus(a5, 1518500250)); /* Cπ/4 Cπ/4 */ + b7 = a7; + move32(); + b8 = L_add(a11, a8); + b9 = L_add(a10, a9); + b10 = L_sub(a9, a10); + b11 = L_sub(a8, a11); + b12 = L_sub(a15, a12); + b13 = L_sub(a14, a13); + b14 = L_add(a13, a14); + b15 = L_add(a12, a15); + + a0 = L_add(b7, b0); + a1 = L_add(b6, b1); + a2 = L_add(b5, b2); + a3 = L_add(b4, b3); + a4 = L_sub(b3, b4); + a5 = L_sub(b2, b5); + a6 = L_sub(b1, b6); + a7 = L_sub(b0, b7); + a10 = L_add(Mpy_32_32_lc3plus(b10, -1518500250), Mpy_32_32_lc3plus(b13, 1518500250)); /* -Cπ/4 Cπ/4 */ + a11 = L_add(Mpy_32_32_lc3plus(b11, -1518500250), Mpy_32_32_lc3plus(b12, 1518500250)); /* -Cπ/4 Cπ/4 */ + a12 = L_add(Mpy_32_32_lc3plus(b12, 1518500250), Mpy_32_32_lc3plus(b11, 1518500250)); /* Cπ/4 Cπ/4 */ + a13 = L_add(Mpy_32_32_lc3plus(b13, 1518500250), Mpy_32_32_lc3plus(b10, 1518500250)); /* Cπ/4 Cπ/4 */ + + out[0] = L_add(b15, a0); + move32(); + out[1] = L_add(b14, a1); + move32(); + out[2] = L_add(a13, a2); + move32(); + out[3] = L_add(a12, a3); + move32(); + out[4] = L_add(a11, a4); + move32(); + out[5] = L_add(a10, a5); + move32(); + out[6] = L_add(b9, a6); + move32(); + out[7] = L_add(b8, a7); + move32(); + out[8] = L_sub(a7, b8); + move32(); + out[9] = L_sub(a6, b9); + move32(); + out[10] = L_sub(a5, a10); + move32(); + out[11] = L_sub(a4, a11); + move32(); + out[12] = L_sub(a3, a12); + move32(); + out[13] = L_sub(a2, a13); + move32(); + out[14] = L_sub(a1, b14); + move32(); + out[15] = L_sub(a0, b15); + move32(); + + Dyn_Mem_Deluxe_Out(); +} diff --git a/lib_lc3plus/dct4.c b/lib_lc3plus/dct4.c deleted file mode 100644 index 055db02cb..000000000 --- a/lib_lc3plus/dct4.c +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void dct2_init(Dct2* dct, int length) -{ - assert(length <= MAX_LEN); - dct->length = length; - fft_init(&dct->fft, length); -} - -void dct2_free(Dct2* dct) -{ - if (dct) { - fft_free(&dct->fft); - memset(dct, 0, sizeof(*dct)); - } -} - -void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) -{ - Complex tmp1[MAX_LEN]; - Complex tmp2[MAX_LEN]; - int i; - assert(input != output); - - for (i = 0; i < 8; i++) { - tmp1[i] = cmplx(input[i * 2], 0); - tmp1[16 - i - 1] = cmplx(input[i * 2 + 1], 0); - } - - fft_apply(&dct->fft, tmp1, tmp2); - - for (i = 0; i < 16; i++) { - output[i] = cmul(tmp2[i], dct2_16[i]).r; - } - output[0] /= (LC3_FLOAT)1.414213562373095; /* SQRT(2) */ -} - - -void dct4_init(Dct4* dct, int length) -{ - int i; - assert(length <= MAX_LEN); - dct->length = length; - dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); - dct->twid2 = calloc(sizeof(*dct->twid2), length / 2); - for (i = 0; i < length / 2; i++) { - dct->twid1[i] = cexpi(-(LC3_FLOAT)M_PI * (i + (LC3_FLOAT)0.25) / length); - dct->twid2[i] = cexpi(-(LC3_FLOAT)M_PI * i / length); - } - fft_init(&dct->fft, length / 2); -} - -void dct4_free(Dct4* dct) -{ - if (dct) { - free(dct->twid1); - free(dct->twid2); - fft_free(&dct->fft); - memset(dct, 0, sizeof(*dct)); - } -} - -void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output) -{ - Complex tmp2[MAX_LEN / 2]; - int i = 0; - Complex* tmp1 = (Complex*)output; - const int len = dct->length; - const LC3_FLOAT norm = (LC3_FLOAT)1.0 / LC3_SQRT((LC3_FLOAT)(len >> 1)); - assert(input != output); - - for (i = 0; i < len >> 1; i++) { - tmp1[i] = cmul(cmplx(input[i * 2], input[len - i * 2 - 1]), dct->twid1[i]); - } - - fft_apply(&dct->fft, tmp1, tmp2); - - for (i = 0; i < len >> 1; i++) { - Complex t = cmul(tmp2[i], dct->twid2[i]); - output[i * 2] = t.r * norm; - output[len - i * 2 - 1] = -t.i * norm; - } -} diff --git a/lib_lc3plus/dct4_fx.c b/lib_lc3plus/dct4_fx.c new file mode 100644 index 000000000..af98a395d --- /dev/null +++ b/lib_lc3plus/dct4_fx.c @@ -0,0 +1,228 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" +#include "rom_basop_util.h" + + +void dct_IV(Word32 *pDat, /* i/o: pointer to data buffer */ + Word16 *pDat_e, /* i/o: pointer to data exponent */ + Word16 L, /* i : length of block */ +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION +# ifdef ENABLE_HR_MODE + Word16 hrmode, /* indicate high precision usage */ +# endif +#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + Word32 *workBuffer) /* : size of L */ + +{ + Word16 sin_step; + Word16 idx; + Word16 M_var; + Word16 M2; + + Word32 *pDat_0; + Word32 *pDat_1; + + Word32 accu1; + Word32 accu2; + Word32 accu3; + Word32 accu4; + + Counter i; + +#ifdef ENABLE_HR_MODE + const PWord32 *twiddle; + const PWord32 *sin_twiddle; +#else + const PWord16 *twiddle; + const PWord16 *sin_twiddle; +#endif + +#ifdef ENABLE_DCTIV_RESCALE + Word16 scale; +#endif + +#ifdef DYNMEM_COUNT +#ifdef ENABLE_HR_MODE + Dyn_Mem_In("dct_IV", sizeof(struct { + Word16 sin_step; + Word16 idx; + Counter i; + Word16 M_var; + Word16 M2; + + Word32 *pDat_0; + Word32 *pDat_1; + + Word32 accu1; + Word32 accu2; + Word32 accu3; + Word32 accu4; + + const PWord32 *twiddle; + const PWord32 *sin_twiddle; + })); + +#else + Dyn_Mem_In("dct_IV", sizeof(struct { + Word16 sin_step; + Word16 idx; + Counter i; + Word16 M_var; + Word16 M2; + + Word32 *pDat_0; + Word32 *pDat_1; + + Word32 accu1; + Word32 accu2; + Word32 accu3; + Word32 accu4; + + const PWord16 *twiddle; + const PWord16 *sin_twiddle; + })); +#endif /* ENABLE_HR_MODE */ +#endif /* DYNMEM_COUNT */ + + M_var = shr_pos_pos(L, 1); + M2 = sub(M_var, 1); + + BASOP_getTables(&twiddle, &sin_twiddle, &sin_step, L); + + pDat_0 = &pDat[0]; + pDat_1 = &pDat[L - 2]; + + FOR (i = 0; i < M2; i += 2) + { +#ifdef ENABLE_HR_MODE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + if (hrmode) { + cplxMpy32_32_32_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im); + cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im); + } else { + cplxMpy32_32_16_2(accu1, accu2, pDat_1[1], pDat_0[0], round_fx_sat(twiddle[i].v.re), round_fx_sat(twiddle[i].v.im)); + cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_0[1], round_fx_sat(twiddle[i + 1].v.re), round_fx_sat(twiddle[i + 1].v.im)); + } +# else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + cplxMpy32_32_32_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im); + cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im); +# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + +#else + cplxMpy32_32_16_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im); + cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im); +#endif + + pDat_0[0] = accu2; move32(); + pDat_0[1] = accu1; move32(); + pDat_1[0] = accu4; move32(); + pDat_1[1] = L_negate(accu3); move32(); + + pDat_0 = pDat_0 + 2; + pDat_1 = pDat_1 - 2; + } + +#ifdef ENABLE_DCTIV_RESCALE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + if (hrmode) +# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + { + + scale = s_max(getScaleFactor32_lc3plus(pDat, L), 0); move16(); + + FOR (i = 0; i < L; i++) + { + pDat[i] = L_shl_pos(pDat[i], scale); move32(); + } + + *pDat_e = sub(*pDat_e, scale); move16(); + } +#endif + + BASOP_cfft_lc3plus(&pDat[0], &pDat[1], M_var, 2, pDat_e, workBuffer); + + pDat_0 = &pDat[0]; + pDat_1 = &pDat[L - 2]; + + idx = sin_step; + M2 = sub(shr_pos_pos(add(M_var, 1), 1), 1); + + /* Sin and Cos values are 0.0f and 1.0f */ +#ifdef ENABLE_HR_MODE + cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#else + cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#endif + + pDat_1[1] = L_negate(L_shr_pos(pDat_0[1], 1)); move32(); + pDat_0[0] = L_shr_pos(pDat_0[0], 1); move32(); + + FOR (i = 1; i < M2; i++) + { + pDat_0[1] = accu3; move32(); + pDat_1[0] = accu4; move32(); + + pDat_0 = pDat_0 + 2; + pDat_1 = pDat_1 - 2; + +#ifdef ENABLE_HR_MODE + cplxMpy32_32_32_2(accu1, accu2, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#else + cplxMpy32_32_16_2(accu1, accu2, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#endif + + idx += sin_step; + +#ifdef ENABLE_HR_MODE + cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#else + cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#endif + + pDat_1[1] = L_negate(accu1); move32(); + pDat_0[0] = accu2; move32(); + } + + pDat_0[1] = accu3; move32(); + pDat_1[0] = accu4; move32(); + + pDat_0 = pDat_0 + 2; + pDat_1 = pDat_1 - 2; + +#ifdef ENABLE_HR_MODE + cplxMpy32_32_32_2(accu3, accu4, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#else + cplxMpy32_32_16_2(accu3, accu4, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#endif + +/* Last Sin and Cos value pair are the same */ +#ifdef ENABLE_HR_MODE + accu1 = L_shr_pos(Mpy_32_32_lc3plus(pDat_1[0], TWIDDLE), 1); + accu2 = L_shr_pos(Mpy_32_32_lc3plus(pDat_1[1], TWIDDLE), 1); +#else + accu1 = L_shr_pos(Mpy_32_16_lc3plus(pDat_1[0], TWIDDLE), 1); + accu2 = L_shr_pos(Mpy_32_16_lc3plus(pDat_1[1], TWIDDLE), 1); +#endif + + pDat_1[0] = L_add(accu1, accu2); move32(); + pDat_0[1] = L_sub(accu1, accu2); move32(); + + pDat_1[1] = L_negate(accu3); move32(); + pDat_0[0] = accu4; move32(); + + /* twiddeling scale is 2 */ + *pDat_e = add(*pDat_e, 2); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/dec_entropy.c b/lib_lc3plus/dec_entropy.c index 4e1f830a2..48512f9fe 100644 --- a/lib_lc3plus/dec_entropy.c +++ b/lib_lc3plus/dec_entropy.c @@ -1,278 +1,387 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" #include "functions.h" -static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit); -static void read_uint_fl(LC3_INT nbits, LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* val); +static Word16 read_indice(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 numbits); -void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit) +static Word16 ac_dec_split_st2VQ_CW( /* local BER flag */ + const Word32 L_cwRx, /* max 25 bits */ + const Word32 L_szA, const Word32 L_szB, Word32 *L_cwA, Word32 *L_cwB, + Word16 *submodeLSB); + +void processDecoderEntropy_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, + Word16 L_spec, Word16 fs_idx, Word16 BW_cutoff_bits, Word16 *tns_numfilters, + Word16 *lsbMode, Word16 *lastnz, Word16 *bfi, Word16 *tns_order, Word16 *fac_ns_idx, + Word16 *gg_idx, Word16 *BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, + Word16 frame_dms) { - if (ptr[*bp_side] & *mask_side) { - *bit = 1; - } else { - *bit = 0; + Dyn_Mem_Deluxe_In( + Word16 L, submodeLSB; + Word32 tmp32, tmp32lim; + Word16 gain_e, gain, submodeMSB, BER_detect; + Counter n; + UWord8 *ptr; + ); + + ptr = bytes; + *bp_side = shr_pos(sub(nbbits, 1), 3); + *mask_side = shl(1, sub(8, sub(nbbits, shl_pos(*bp_side, 3)))); + + /* Cutoff-detection */ + IF (BW_cutoff_bits > 0) + { + *BW_cutoff_idx = read_indice(ptr, bp_side, mask_side, BW_cutoff_bits); + /* check for bitflips */ + IF (sub(fs_idx, *BW_cutoff_idx) < 0) + { + *BW_cutoff_idx = fs_idx; + *bfi = 1; move16(); + Dyn_Mem_Deluxe_Out(); + return; + } + } + ELSE + { + *BW_cutoff_idx = fs_idx; } - if (*mask_side == 128) { - *mask_side = 1; - *bp_side = *bp_side - 1; - } else { - *mask_side = *mask_side * 2; + /* Number of TNS filters */ + IF (sub(*BW_cutoff_idx, 3) >= 0 && frame_dms >= 50) + { + *tns_numfilters = 2; move16(); + } + ELSE + { + *tns_numfilters = 1; move16(); } -} -void read_uint_fl(LC3_INT nbits, LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* val) -{ - LC3_INT bit, i; + /* Decode number of ntuples */ + L = sub(14, norm_s(negate(L_spec))); + n = read_indice(ptr, bp_side, mask_side, L); + n = add(n, 1); + *lastnz = shl_pos(n, 1); + IF (sub(*lastnz, L_spec) > 0) + { + *bfi = 1; move16(); + Dyn_Mem_Deluxe_Out(); + return; + } - read_bit_fl(ptr, mask_side, bp_side, val); + /* Mode bit */ + *lsbMode = read_bit(ptr, bp_side, mask_side); + + /* Decode global-gain */ + *gg_idx = read_indice(ptr, bp_side, mask_side, 8); move16(); + tmp32 = L_shl_pos(L_mult0(*gg_idx, 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */ + gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); /* get exponent */ + gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000))); + assert(gain >= 0); /* JSv, check if shr_pos(gain,1) is more appropriate) */ + gain = shr_r(gain, 1); + gain_e = add(gain_e, 1); + + /* Decode TNS on/off flag */ + tns_order[1] = 0; move16(); /* fix problem with uninitialized memory */ + FOR (n = 0; n < *tns_numfilters; n++) + { + tns_order[n] = read_bit(ptr, bp_side, mask_side); move16(); + } - for (i = 1; i < nbits; i++) { - read_bit_fl(ptr, mask_side, bp_side, &bit); - *val = *val + (bit << i); + /* LTPF on/off */ +#ifdef ENABLE_HR_MODE + ltpf_idx[0] = read_bit(ptr, bp_side, mask_side); move16(); +#else + ltpf_idx[0] = read_indice(ptr, bp_side, mask_side, 1); move16(); +#endif + + /* Decode SNS VQ parameters - 1st stage (10 bits) */ +#ifdef ENABLE_HR_MODE + L = read_indice(ptr, bp_side, mask_side, 5 + 5); + L_scf_idx[0] = L_deposit_l(s_and(L, 0x1F)); /* stage1 LF 5 bits */ + L_scf_idx[1] = L_deposit_l(shr_pos(L, 5)); /* stage1 HF 5 bits */ +#else + L_scf_idx[0] = L_deposit_l(read_indice(ptr, bp_side, mask_side, 5)); /* stage1 LF 5 bits */ + L_scf_idx[1] = L_deposit_l(read_indice(ptr, bp_side, mask_side, 5)); /* stage1 HF 5 bits */ +#endif + + /* Decode SNS VQ parameters - 2nd stage side-info (3-4 bits) */ + submodeMSB = read_bit(ptr, bp_side, mask_side); /* submodeMSB 1 bit */ + L_scf_idx[2] = L_deposit_l(shl_pos(submodeMSB, 1)); + ASSERT(sns_gainMSBbits[L_scf_idx[2]] > 0); + L_scf_idx[3] = L_deposit_l( + read_indice(ptr, bp_side, mask_side, sns_gainMSBbits[L_scf_idx[2]])); /* gains or gain MSBs 1-2 bits */ + L_scf_idx[4] = read_bit(ptr, bp_side, mask_side); /* shape LS 1 bit */ + + /* Decode SNS VQ parameters - 2nd stage data (24-25 bits) */ + IF (submodeMSB == 0) + { /* shape_j = 0, or 1 */ + /* regular mode A,B indexes integer multiplexed, total 24.x bits MPVQ codeword section A and codeword for + * section B */ + /* regular mode mode shape index total 24.9999 bits MPVQ codeword */ + tmp32 = L_deposit_l(read_indice(ptr, bp_side, mask_side, 13)); + tmp32 = L_or(tmp32, L_shl_pos(read_indice(ptr, bp_side, mask_side, 12), 13)); move16(); /*for ber state */ + BER_detect = + ac_dec_split_st2VQ_CW( /* local BER flag */ + tmp32, /* L_cwRx max 25 bits */ + sns_MPVQ_Sz[0][0], UL_addNsD(sns_MPVQ_Sz[0][1], sns_MPVQ_Sz[1][1]), /* 12+2 = 14 */ + (&L_scf_idx[5]), /* shape A */ + (&L_scf_idx[6]), /* shape B or gain LSB */ + &submodeLSB /* total submode update below */ + ); + IF (submodeLSB != 0) + { /* add gainLSB bit */ + L_scf_idx[3] = L_add(L_shl_pos(L_scf_idx[3], 1), L_scf_idx[6]); + L_scf_idx[6] = -2L; + } + } + ELSE + { /* shape_j = 2 or 3 */ + ASSERT(submodeMSB == 1); + /* outlier mode shape index total 23.8536 + 19.5637 (19.5637 < (log2(2.^24 -2.^23.8537)) bits MPVQ + * codeword */ + tmp32 = L_deposit_l(read_indice(ptr, bp_side, mask_side, 12)); + tmp32 = L_or(tmp32, L_shl_pos(read_indice(ptr, bp_side, mask_side, 12), 12)); + L_scf_idx[5] = tmp32; move32(); /*shape outl_near or outl_far */ + submodeLSB = 0; move16(); + BER_detect = 0; move16(); + tmp32lim = L_add(sns_MPVQ_Sz[2][0], L_shl_pos(sns_MPVQ_Sz[3][0], 1)); + IF (L_sub(tmp32, tmp32lim) >= 0) + { + BER_detect = 1; move16(); + } + ELSE + { + tmp32 = L_sub(tmp32, sns_MPVQ_Sz[2][0]); /* a potential high index is computed */ + IF (tmp32 >= 0) + { + submodeLSB = 1; move16(); + ASSERT(tmp32 >= 0 && tmp32 < (Word32)(2 * sns_MPVQ_Sz[3][0])); + L_scf_idx[3] = L_add(L_shl_pos(L_scf_idx[3], 1), L_and(tmp32, 0x1)); /* add LSB_gain bit to gain MSBs */ + L_scf_idx[5] = L_shr_pos(tmp32, 1); /* MPVQ index with offset and gainLSB removed */ + L_scf_idx[6] = -2L; move32(); + } + ELSE + { + L_scf_idx[6] = -1L; move32(); + } + } + } + L_scf_idx[2] = + L_add(L_scf_idx[2], L_deposit_l(submodeLSB)); /* decoder internal signal shape_j = submode 0..3 to VQ */ + + IF (BER_detect > 0) + { + *bfi = 1; move16(); + Dyn_Mem_Deluxe_Out(); + return; } + + /* LTPF data */ + IF (ltpf_idx[0] != 0) + { +#ifdef ENABLE_HR_MODE + L = read_indice(ptr, bp_side, mask_side, 1+9); move16(); + ltpf_idx[1] = s_and(L, 1); move16(); + ltpf_idx[2] = shr_pos(L, 1); move16(); +#else + ltpf_idx[1] = read_indice(ptr, bp_side, mask_side, 1); move16(); + ltpf_idx[2] = read_indice(ptr, bp_side, mask_side, 9); move16(); + +#endif + } + ELSE + { + ltpf_idx[1] = 0; move16(); + ltpf_idx[2] = 0; move16(); + } + + /* Decode noise-fac */ + *fac_ns_idx = read_indice(ptr, bp_side, mask_side, 3); move16(); + + Dyn_Mem_Deluxe_Out(); } #ifdef ENABLE_PADDING -LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT bw_cutoff_bits, LC3_INT ep_enabled, LC3_INT* total_padding, LC3_INT *np_zero) +int paddingDec_fx(UWord8 *bytes, Word16 nbbits, Word16 L_spec, Word16 BW_cutoff_bits, Word16 ep_enabled, + Word16 *total_padding, Word16 *np_zero) { - LC3_INT lastnz_threshold; - LC3_INT val, padding_len_bits, padding_len; - LC3_INT bp_side; - LC3_INT mask_side; - LC3_UINT8* ptr = bytes; - - LC3_INT nbbytes = nbbits >> 3; - LC3_INT lastnz; - LC3_INT bw_cutoff_idx; - LC3_INT nbits = ceil(LC3_LOGTWO(L_spec / 2)); - - if (nbits > nbbits) + Word16 lastnz_threshold; + Word16 padding_len_bits, padding_len; + + Word16 bp_side; + Word16 nbbytes = shr(nbbits,3); + + Word16 mask_side; + UWord8 *ptr = bytes; + + Word16 lastnz; + Word16 nbits = sub(14, norm_s(negate(L_spec))); + if (sub(nbbits, nbits) < 0) { return 1; } - - *np_zero = 0; + *np_zero = 0; *total_padding = 0; - bp_side = (nbbits - 1) >> 3; - mask_side = 1 << (8 - (nbbits - (bp_side << 3))); + bp_side = shr_pos(sub(nbbits, 1), 3); + mask_side = shl(1, sub(8, sub(nbbits, shl_pos(bp_side, 3)))); - if (bp_side < 19 || bp_side >= LC3PLUS_MAX_BYTES) { + test(); + IF (sub(bp_side, 19) < 0 || sub(bp_side, LC3PLUS_MAX_BYTES ) >= 0) { return 1; } - + ptr = bytes; - if (bw_cutoff_bits > 0) { - read_uint_fl(bw_cutoff_bits, ptr, &mask_side, &bp_side, &bw_cutoff_idx); + IF (BW_cutoff_bits > 0) + { + read_indice(ptr, &bp_side, &mask_side, BW_cutoff_bits); + move16(); } - read_uint_fl(nbits, ptr, &mask_side, &bp_side, &lastnz); + lastnz = read_indice(ptr, &bp_side, &mask_side, nbits); + move16(); - lastnz_threshold = (1 << nbits) - 1 - 1; + lastnz_threshold = sub(shl(1, nbits), 2); - while (lastnz == lastnz_threshold) { - padding_len_bits = 16 - nbits - bw_cutoff_bits - 4; + WHILE (lastnz == lastnz_threshold) + { + padding_len_bits = sub(sub(12, nbits), BW_cutoff_bits); /*Read padding length*/ - read_uint_fl(padding_len_bits, ptr, &mask_side, &bp_side, &padding_len); + padding_len = read_indice(ptr, &bp_side, &mask_side, padding_len_bits); + move16(); /* Read 4 reserved bits */ - read_uint_fl(4, ptr, &mask_side, &bp_side, &val); - - if (ep_enabled == 0) + read_indice(ptr, &bp_side, &mask_side, 4); + move16(); + + IF (ep_enabled == 0) { /* Discard padding length bytes */ - bp_side = bp_side - padding_len; - *total_padding = *total_padding + padding_len + 2; + bp_side = sub(bp_side, padding_len); + *total_padding = add(add(*total_padding, padding_len), 2); move16(); } - else + ELSE { - *total_padding = *total_padding + 2; - *np_zero = *np_zero + padding_len; + *total_padding = add(*total_padding, 2); move16(); + *np_zero = add(*np_zero, padding_len); move16(); } - /* check if minimum payload size is reached */ - if ((nbbytes - (*total_padding + *np_zero)) < 20) { + /* test if we have less than 20 bytes left; if so frame is broken */ + IF (sub(sub(nbbytes,add(*total_padding,*np_zero)),20) < 0) { return 1; } /* Read bandwidth bits */ - if (bw_cutoff_bits > 0) { - read_uint_fl(bw_cutoff_bits, ptr, &mask_side, &bp_side, &bw_cutoff_idx); + IF (BW_cutoff_bits > 0) + { + read_indice(ptr, &bp_side, &mask_side, BW_cutoff_bits); + move16(); } - read_uint_fl(nbits, ptr, &mask_side, &bp_side, &lastnz); + lastnz = read_indice(ptr, &bp_side, &mask_side, nbits); + move16(); } - - if (ep_enabled != 0) + + IF (ep_enabled != 0) { - *total_padding = *total_padding + *np_zero; + *total_padding = add(*total_padding, *np_zero); move16(); } - return 0; } #endif -void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT N, LC3_INT fs_idx, - LC3_INT bw_cutoff_bits, LC3_INT* bfi, LC3_INT* gg_idx, LC3_INT* scf_idx, LC3_INT* fac_ns_idx, - LC3_INT* tns_numfilters, LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* bw_cutoff_idx, LC3_INT* lastnz, - LC3_INT* lsbMode, LC3_INT frame_dms) +static __forceinline Word16 read_indice(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 numbits) { + Dyn_Mem_Deluxe_In( + Word16 indice, bit; + Counter i; + ); - LC3_INT plc_trigger_bw, plc_trigger_last_nz, plc_trigger_SNS1, plc_trigger_SNS2, tmp, bit, - submodeMSB, i, ltpf_tmp[3], ind, submodeLSB, bp_side_local, mask_side_local; - LC3_UINT8* ptr; - LC3_INT gainMSBbits[4] = {1, 1, 2, 2}; - - *bp_side = -1; - bp_side_local = numbytes - 1; /* Matlab offset by 1 */ - mask_side_local = 1; - *mask_side = -1; - ptr = bytes; - *lsbMode = -1; - *lastnz = -1; - - plc_trigger_bw = 1; /* Bandwidth */ - plc_trigger_last_nz = 1; /* Last non-zero tuple */ - plc_trigger_SNS1 = 1; /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */ - plc_trigger_SNS2 = 1; /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */ - - - - /* Bandwidth */ - if (bw_cutoff_bits > 0) { - read_uint_fl(bw_cutoff_bits, ptr, &mask_side_local, &bp_side_local, bw_cutoff_idx); + indice = read_bit(ptr, bp, mask); - if (fs_idx < *bw_cutoff_idx) { - *bfi = plc_trigger_bw; - - if (*bfi) { - return; - } - } - } else { - *bw_cutoff_idx = fs_idx; - } - - /* Number of TNS filters */ - if (*bw_cutoff_idx < 3 || frame_dms == 25) { - *tns_numfilters = 1; - } else { - *tns_numfilters = 2; + FOR (i = 1; i < numbits; i++) + { + bit = read_bit(ptr, bp, mask); + indice = add(indice, lshl_pos(bit, i)); } - /* Last non-zero tuple */ - read_uint_fl(ceil(LC3_LOGTWO(N >> 1)), ptr, &mask_side_local, &bp_side_local, lastnz); - *lastnz = (*lastnz + 1) * 2; - - if (*lastnz > N) { - *bfi = plc_trigger_last_nz; - if (*bfi) { - return; - } - } + Dyn_Mem_Deluxe_Out(); + return indice; +} - /* LSB mode bit */ - read_bit_fl(ptr, &mask_side_local, &bp_side_local, lsbMode); +static __forceinline Word16 ac_dec_split_st2VQ_CW( /* local BER flag */ + const Word32 L_cwRx, /* max 25 bits */ + const Word32 L_szA, const Word32 L_szB, Word32 *L_cwA, Word32 *L_cwB, + Word16 *submodeLSB) +{ + /* demultiplex: L_cwRx = L_cwB(21.z bits) * L_szA(3.y bits) + L_cwA(21.x bits)); */ + Word16 start, fin, ind; + Word32 L_tmp, L_max_size; + Counter i; - /* Global gain */ - read_uint_fl(8, ptr, &mask_side_local, &bp_side_local, gg_idx); + L_max_size = (Word32)UL_Mpy_32_32((UWord32)L_szB, (UWord32)L_szA); /* may be tabled */ - /* TNS activation flag */ - for (i = 0; i < *tns_numfilters; i++) { - read_bit_fl(ptr, &mask_side_local, &bp_side_local, &bit); - tns_order[i] = bit; + /* section B ind larger than 13 out of the possible 14 = 0..13 */ + IF (L_sub(L_cwRx, L_max_size) >= 0) + { + *L_cwA = L_deposit_l(0); + *L_cwB = L_deposit_l(0); + *submodeLSB = 0; move16(); + return (Word16)1; /* set berFlag and exit */ } - /* LTPF activation flag */ - read_bit_fl(ptr, &mask_side_local, &bp_side_local, <pf_tmp[0]); - - /* SNS-VQ 1st stage */ - read_uint_fl(5, ptr, &mask_side_local, &bp_side_local, &scf_idx[0]); - read_uint_fl(5, ptr, &mask_side_local, &bp_side_local, &scf_idx[1]); - - /* SNS-VQ 2nd stage side-info (3-4 bits) */ - read_bit_fl(ptr, &mask_side_local, &bp_side_local, &submodeMSB); - scf_idx[2] = submodeMSB * 2; - - read_uint_fl(gainMSBbits[scf_idx[2]], ptr, &mask_side_local, &bp_side_local, &scf_idx[3]); - read_bit_fl(ptr, &mask_side_local, &bp_side_local, &scf_idx[4]); - - /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */ - if (submodeMSB == 0) { - read_uint_fl(25, ptr, &mask_side_local, &bp_side_local, &tmp); - if (tmp >= 33460056) { - *bfi = plc_trigger_SNS1; - if (*bfi) { - return; - } - } + /*initial binary split of cw, select top or low half */ + start = 0; move16(); - ind = floor(tmp / 2390004); - scf_idx[5] = tmp - ind * 2390004; + ASSERT((L_szB & 0x1L) == 0); /* this middle split only works if L_szB is even */ + if (L_sub(L_cwRx, L_shr_pos(L_max_size, 1)) >= 0) + { + start = L_shr_pos(L_szB, 1); /* top half start index */ + } - if (ind < 2) { - submodeLSB = 1; - scf_idx[3] = scf_idx[3] * 2 + ind; - scf_idx[6] = -2; - } else { - submodeLSB = 0; - scf_idx[6] = ind - 2; - } + /*linear loop over a low or a high section */ + ind = start; move16(); + L_tmp = L_negate(L_cwRx); /* search from negative side */ - } else { - read_uint_fl(24, ptr, &mask_side_local, &bp_side_local, &tmp); + L_tmp = L_add(L_tmp, (Word32)UL_Mpy_32_32(UL_deposit_l((UWord16)start), (UWord32)L_szA)); + /* start is 0 or 7 */ /*non-fractional mult is (int)start * L_szA */ - if (tmp >= 16708096) { - *bfi = plc_trigger_SNS2; - if (*bfi) { - return; - } - } + /* a short linear run over ceil(szB/2) = 7 values */ - if (tmp >= 15158272) { - submodeLSB = 1; - scf_idx[3] = scf_idx[3] * 2 + ((tmp - 15158272) & 1); - scf_idx[5] = floor((tmp - 15158272) / 2); - scf_idx[6] = -2; - } else { - submodeLSB = 0; - scf_idx[5] = tmp; - scf_idx[6] = -1; + fin = add(start, shr_pos(L_szB, 1)); + FOR (i = start; i < fin; i++) + { + ind = add(ind, 1); + L_tmp = L_add(L_tmp, L_szA); + if (L_tmp > 0) + { + ind = sub(ind, 1); /* passed criteria point, keep index */ } } - scf_idx[2] = scf_idx[2] + submodeLSB; + *L_cwB = L_deposit_l(ind); + *L_cwA = L_sub(L_cwRx, (Word32)UL_Mpy_32_32(UL_deposit_l((UWord16)ind), + (UWord32)L_szA)); /* non-fractional mult; (int)ind * L_szA */ - /* LTPF data */ - if (ltpf_tmp[0] == 1) { - read_bit_fl(ptr, &mask_side_local, &bp_side_local, <pf_tmp[1]); - read_uint_fl(9, ptr, &mask_side_local, &bp_side_local, <pf_tmp[2]); - } else { - ltpf_tmp[1] = 0; - ltpf_tmp[2] = 0; - } + ASSERT(*L_cwA >= 0 && *L_cwA < L_szA); + ASSERT(*L_cwB >= 0 && *L_cwB < L_szB); - for (i = 0; i < 3; i++) { - ltpf_idx[i] = ltpf_tmp[i]; + *submodeLSB = 0; + *L_cwB = L_sub(*L_cwB, 2); + if (*L_cwB < 0) + { + *submodeLSB = 1; move16(); } + *L_cwB = L_mac0(*L_cwB, 2, *submodeLSB); /* add back gain ind if needed */ - /* Noise factor */ - read_uint_fl(3, ptr, &mask_side_local, &bp_side_local, fac_ns_idx); - - *bp_side = bp_side_local; - *mask_side = mask_side_local; + return 0; /* no BER */ } diff --git a/lib_lc3plus/dec_lc3.c b/lib_lc3plus/dec_lc3.c new file mode 100644 index 000000000..40818106e --- /dev/null +++ b/lib_lc3plus/dec_lc3.c @@ -0,0 +1,788 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +static int Dec_LC3PLUS_Channel(LC3PLUS_Dec *decoder, int channel, int bits_per_sample, UWord8 *bs_in, void *s_out, Word16 bfi, + Word8 *scratchBuffer) +{ + Word16 scale; + Word32 offset; + Word16 fill_bits; + Word16 nf_seed, gg_idx, fac_ns_idx, q_fx_exp = 0; + Word16 bp_side, mask_side; + Word16 tns_numfilters, lsbMode, lastnz, BW_cutoff_idx, BW_cutoff_idx_nf; + Word16 zero_frame = 0; +#ifdef ENABLE_RFRAME + Word16 rframe = 0; +#endif + Word16 ltpf_idx[3]; + Word16 spec_inv_idx = 0; + Counter i; + + /* Buffers */ + Word16 *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX]; + UWord8 *resBitBuf; +#ifdef ENABLE_HR_MODE + Word32 *sqQdec; +#else + Word16 * sqQdec; + Word16 * int_scf_fx; +#endif + Word16 * x_fx, *indexes; + Word16 scf_q[M]; + Word32 * L_scf_idx; + Word32 * q_d_fx; + Word8 * currentScratch; + DecSetup *h_DecSetup = decoder->channel_setup[channel]; +#ifdef ENABLE_HR_MODE + Word32 *x_fx_ip; + Word32 *int_scf_fx_ip; + Word32 scf_q_ip[M]; +#endif + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Counter i; + Word16 scale; + Word32 offset; + Word16 fill_bits; + Word16 nf_seed, gg_idx, fac_ns_idx, q_fx_exp; + Word16 bp_side, mask_side; + Word16 tns_numfilters, lsbMode, lastnz, BW_cutoff_idx, BW_cutoff_idx_nf; + Word16 zero_frame; + Word16 ltpf_idx[3]; +#ifdef ENABLE_RFRAME + Word16 rframe; +#endif + Word16 spec_inv_idx; + + /* Buffers */ + Word16 *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX]; + UWord8 *resBitBuf; +#ifdef ENABLE_HR_MODE + Word32 *sqQdec; +#else + Word16 *sqQdec; +#endif + Word16 *int_scf_fx, *x_fx, *indexes; + Word32 *L_scf_idx; + Word32 *q_d_fx; + Word8 * currentScratch; + Word16 scf_q[M]; +#ifdef ENABLE_HR_MODE + Word32 scf_q_ip[M]; +#endif + }; + Dyn_Mem_In("Dec_LC3_Channel", sizeof(struct _dynmem)); +#endif + +#ifdef DISABLE_PLC + UNUSED(decoder->plcMeth); +#endif + + + /* BUFFER INITIALISATION. Some buffers may overlap since they are not used in the whole decoding process */ + q_d_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */ +#ifdef ENABLE_HR_MODE + /* allocate memory for residual bits */ + if (decoder->hrmode) + { + resBitBuf = scratchAlign(q_d_fx, sizeof(*q_d_fx) * + decoder->frame_length); + basop_memset(resBitBuf, 0, sizeof(*resBitBuf) * MAX_RESBITS_LEN); + } + else +#endif + { + resBitBuf = scratchAlign(q_d_fx, sizeof(*q_d_fx) * + decoder->frame_length); /* Size = 2 * NPRM_RESQ = 2 * MAX_LEN bytes for + normal case and 2*MAX_RESBITS_LEN for hrmode */ + basop_memset(resBitBuf, 0, sizeof(*resBitBuf) * 2 * decoder->frame_length); + } + +#ifdef ENABLE_HR_MODE + indexes = scratchAlign(resBitBuf, sizeof(*resBitBuf) * MAX_RESBITS_LEN); +#else + indexes = scratchAlign(resBitBuf, sizeof(*resBitBuf) * 2 * decoder->frame_length); +#endif + memset(indexes, 0, sizeof(*indexes) * TNS_NUMFILTERS_MAX * MAXLAG); + + /* indexes Size = 2 * TNS_NUMFILTERS_MAX * MAXLAG = 32 bytes */ + + L_scf_idx = scratchAlign(indexes, sizeof(*indexes) * TNS_NUMFILTERS_MAX * + MAXLAG); /* Size = 4 * SCF_MAX_PARAM = 28 bytes -> aligned to 32 bytes */ + sqQdec = scratchAlign(L_scf_idx, sizeof(*L_scf_idx) * (SCF_MAX_PARAM)); /* Size = 2 * MAX_LEN bytes */ + int_scf_fx_exp = scratchAlign(sqQdec, sizeof(*sqQdec) * decoder->frame_length); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ +#ifndef ENABLE_HR_MODE + int_scf_fx = scratchAlign(int_scf_fx_exp, + sizeof(*int_scf_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ +#endif +#ifdef ENABLE_HR_MODE + x_fx = + scratchAlign(int_scf_fx_exp, sizeof(*int_scf_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * (MAX_LEN + MDCT_MEM_LEN_MAX) = 2 + * MAX_LEN + 1.25 * MAX_LEN = 3.25 * MAX_LEN */ +#else + x_fx = + scratchAlign(q_d_fx, sizeof(*q_d_fx) * decoder->frame_length); /* Size = 2 * (MAX_LEN + MDCT_MEM_LEN_MAX) = 2 + * MAX_LEN + 1.25 * MAX_LEN = 3.25 * MAX_LEN */ +#endif + +#ifdef ENABLE_HR_MODE + x_fx_ip = scratchAlign(x_fx, sizeof(*x_fx) * (decoder->frame_length + decoder->stDec_ola_mem_fx_len)); + int_scf_fx_ip = scratchAlign(x_fx_ip, sizeof(*x_fx_ip) * (decoder->frame_length + decoder->stDec_ola_mem_fx_len)); + + currentScratch = scratchAlign(int_scf_fx_ip, sizeof(*int_scf_fx_ip) * 2 * MAX_BANDS_NUMBER); /* Size = 4 * MAX_LEN */ +#else + currentScratch = scratchAlign(x_fx, sizeof(*x_fx) * 4 * MAX_LEN); /* Size = 4 * MAX_LEN */ +#endif + +#ifdef DISABLE_PLC + memset(q_d_fx, 0, decoder->frame_length * sizeof(*q_d_fx)); +#endif + +#ifdef WMOPS + BASOP_sub_start("Decoder"); +#endif + +#ifdef ENABLE_RFRAME + IF (sub(bfi, 3) == 0) + { + bfi = 2; + move16(); + rframe = 1; + move16(); + } +#endif + + if (bfi != 1) + { +#ifdef WMOPS + BASOP_sub_sub_start("Dec(bfi=0)"); +#endif + } + else + { +#ifdef WMOPS + BASOP_sub_sub_start("Dec(bfi=1)"); +#endif + } + +#ifdef WMOPS + BASOP_sub_start("Entropy dec"); +#endif + IF (sub(bfi, 1) != 0) + { + processDecoderEntropy_fx(bs_in, &bp_side, &mask_side, h_DecSetup->total_bits, decoder->yLen, decoder->fs_idx, + decoder->BW_cutoff_bits, &tns_numfilters, &lsbMode, &lastnz, &bfi, tns_order, + &fac_ns_idx, &gg_idx, &BW_cutoff_idx, ltpf_idx, L_scf_idx, decoder->frame_dms); + BW_cutoff_idx_nf = BW_cutoff_idx; + move16(); + } +#ifdef WMOPS + BASOP_sub_end(); /* Entropy dec */ +#endif + +#ifdef WMOPS + BASOP_sub_start("Ari dec"); +#endif + IF (sub(bfi, 1) != 0) + { + processAriDecoder_fx(bs_in, &bp_side, &mask_side, h_DecSetup->total_bits, decoder->yLen, decoder->fs_idx, + h_DecSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &bfi, tns_order, + fac_ns_idx, gg_idx, decoder->frame_dms, + decoder->n_pc, decoder->be_bp_left, decoder->be_bp_right, 0, &spec_inv_idx, &scale, + &fill_bits, sqQdec, &nf_seed, resBitBuf, indexes, &zero_frame, currentScratch +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); + +#ifdef ENABLE_RFRAME + test();test(); + IF (sub(rframe, 1) == 0 && zero_frame == 0 && sub(bfi, 1) != 0) + { + bfi = 2; + move16(); + Word16 max_bw_stopband = BW_cutoff_bin_all[BW_cutoff_idx]; + SWITCH (decoder->frame_dms) + { +#ifdef ENABLE_025_DMS_MODE + case 25: + max_bw_stopband = shr_pos(max_bw_stopband, 2); + BREAK; +#endif +#ifdef ENABLE_050_DMS_MODE + case 50: + max_bw_stopband = shr_pos(max_bw_stopband, 1); + BREAK; +#endif +#ifdef CR8_G_ADD_75MS + case 75: + max_bw_stopband = add(shr_pos(max_bw_stopband, 2), add(shr_pos(max_bw_stopband, 2), shr_pos(max_bw_stopband, 2))); + BREAK; +#endif + case 100: + BREAK; + } + + spec_inv_idx = s_max(lastnz, max_bw_stopband); + move16(); + } +#endif + + IF (bfi == 0) + { + processAriDecoderScaling_fx(sqQdec, decoder->yLen, q_d_fx, &q_fx_exp); + } + } +#ifdef WMOPS + BASOP_sub_end(); /* Ari dec */ +#endif + +#ifdef WMOPS + BASOP_sub_start("SnsQuantScfDec"); +#endif + IF (sub(bfi, 1) != 0) + { + /* currentScratch Size = 96 bytes */ +#ifdef ENABLE_HR_MODE + processSnsQuantizeScfDecoder_fx(L_scf_idx, scf_q_ip, currentScratch); + downshift_w32_arr(scf_q_ip, scf_q, 15, M); /* required for PLC */ +#else + processSnsQuantizeScfDecoder_fx(L_scf_idx, scf_q, currentScratch); +#endif + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("PLC::ComputeStabFac"); +#endif + if (h_DecSetup->plcAd) + { + processPLCcomputeStabFac_main(scf_q, h_DecSetup->plcAd->old_scf_q, h_DecSetup->plcAd->old_old_scf_q, bfi, + h_DecSetup->prev_bfi, h_DecSetup->prev_prev_bfi, &h_DecSetup->plcAd->stab_fac); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Partial Concealment"); +#endif + IF (sub(bfi, 1) != 0) + { + scale = 32767; + move16(); + + IF (h_DecSetup->plcAd) + { + scale = h_DecSetup->plcAd->stab_fac; + } + + processPCmain_fx(rframe, &bfi, decoder->yLen, decoder->frame_dms, h_DecSetup->q_old_res_fx, + &h_DecSetup->q_old_res_fx_exp, sqQdec, h_DecSetup->q_old_d_fx, spec_inv_idx, ltpf_idx[0], + scale, q_d_fx, &q_fx_exp, gg_idx, h_DecSetup->quantizedGainOff, &h_DecSetup->prev_gg, + &h_DecSetup->prev_gg_e, &BW_cutoff_idx_nf, &h_DecSetup->prev_BW_cutoff_idx_nf, fac_ns_idx, + &h_DecSetup->prev_fac_ns_fx, &h_DecSetup->pc_nbLostFramesInRow); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + + IF (sub(bfi, 1) != 0) + { +#ifdef WMOPS + BASOP_sub_start("Residual dec"); +#endif + processResidualDecoding_fx(q_d_fx, q_fx_exp, decoder->yLen, resBitBuf, fill_bits +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Noisefill"); +#endif + /* currentScratch Size = 2 * MAX_LEN bytes */ + IF (zero_frame == 0) + { + processNoiseFilling_fx(q_d_fx, nf_seed, q_fx_exp, fac_ns_idx, BW_cutoff_idx_nf, decoder->frame_dms, + h_DecSetup->prev_fac_ns_fx, spec_inv_idx, currentScratch +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("applyGlobalGain"); +#endif + processApplyGlobalGain_fx(q_d_fx, &q_fx_exp, decoder->yLen, gg_idx, h_DecSetup->quantizedGainOff); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Tns_dec"); +#endif + /* currentScratch Size = 48 bytes */ + processTnsDecoder_fx(indexes, q_d_fx, decoder->yLen, tns_order, &q_fx_exp, BW_cutoff_idx, decoder->frame_dms, + currentScratch +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef ENABLE_HR_MODE +#ifdef WMOPS + BASOP_sub_start("SnsInterpScfDec"); +#endif + processSnsInterpolateScf_fx(scf_q_ip, int_scf_fx_ip, int_scf_fx_exp, 0, decoder->bands_number, currentScratch); + +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Mdct shaping_dec"); +#endif + processScfScaling(int_scf_fx_exp, decoder->bands_number, &q_fx_exp); + + processMdctShaping_fx(q_d_fx, int_scf_fx_ip, int_scf_fx_exp, decoder->bands_offset, decoder->bands_number); +#ifdef WMOPS + BASOP_sub_end(); +#endif +#else +#ifdef WMOPS + BASOP_sub_start("SnsInterpScfDec"); +#endif + /* currentScratch Size = 128 bytes */ + processSnsInterpolateScf_fx(scf_q, int_scf_fx, int_scf_fx_exp, 0, decoder->bands_number, currentScratch); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Mdct shaping_dec"); +#endif + processScfScaling(int_scf_fx_exp, decoder->bands_number, &q_fx_exp); + processMdctShaping_fx(q_d_fx, int_scf_fx, int_scf_fx_exp, decoder->bands_offset, decoder->bands_number); +#ifdef WMOPS + BASOP_sub_end(); +#endif + /* end int_scf_fx */ +#endif /* ENABLE_HR_MODE */ + } + + /* x_fx_ip will be used to store h_DecSetup->stDec_ola_mem_fx returned by PLCmain_fx*/ + /* This will be upshifted to 32 bit overlap buffer outside of the PLCmain function */ +#ifdef ENABLE_HR_MODE + Word16 *plc_ola_mem = (Word16 *)x_fx_ip; + IF(sub(bfi, 1) == 0) + { + FOR(i = 0; i < decoder->stDec_ola_mem_fx_len; i++) + { + plc_ola_mem[i] = round_fx(h_DecSetup->stDec_ola_mem_fx[i]); + } + } +#endif + +#ifdef WMOPS + BASOP_sub_start("PLC::Main"); +#endif + /* currentScratch Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */ + processPLCmain_fx(decoder->plcMeth, &h_DecSetup->concealMethod, &h_DecSetup->nbLostFramesInRow, bfi, + h_DecSetup->prev_bfi, decoder->frame_length, decoder->la_zeroes, decoder->W_fx, x_fx, +#ifdef ENABLE_HR_MODE + plc_ola_mem, +#else + h_DecSetup->stDec_ola_mem_fx, +#endif + &h_DecSetup->stDec_ola_mem_fx_exp, h_DecSetup->q_old_d_fx, + &h_DecSetup->q_old_fx_exp, q_d_fx, &q_fx_exp, decoder->yLen, decoder->fs_idx, + decoder->bands_offset, decoder->bands_number, &h_DecSetup->plc_damping, h_DecSetup->ltpf_mem_pitch_int, + h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ns_cum_alpha, &h_DecSetup->ns_seed, h_DecSetup->plcAd, + decoder->frame_dms, currentScratch, &h_DecSetup->pc_nbLostFramesInRow +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , h_DecSetup->rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , decoder->alpha_type_2_table +#endif + ); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef ENABLE_HR_MODE + IF(sub(bfi, 1) == 0) + { + FOR(i = 0; i < decoder->stDec_ola_mem_fx_len; i++) + { + h_DecSetup->stDec_ola_mem_fx[i] = L_deposit_h(plc_ola_mem[i]); + } + } +#endif + +#ifdef WMOPS + BASOP_sub_start("PLC/PC::DampingScrambling"); +#endif + if (h_DecSetup->plcAd) + { + processPLCDampingScrambling_main_fx( + bfi, h_DecSetup->concealMethod, h_DecSetup->nbLostFramesInRow, &h_DecSetup->plcAd->cum_fflcAtten, + h_DecSetup->pc_nbLostFramesInRow, &h_DecSetup->ns_seed, &h_DecSetup->pc_seed, + h_DecSetup->ltpf_mem_pitch_int, ltpf_idx[0], q_d_fx, &q_fx_exp, h_DecSetup->q_old_d_fx, + &h_DecSetup->q_old_fx_exp, decoder->yLen, h_DecSetup->plcAd->stab_fac, decoder->frame_dms, + &h_DecSetup->plcAd->cum_fading_slow, &h_DecSetup->plcAd->cum_fading_fast, spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , h_DecSetup->plcAd->plc_fadeout_type +#endif + ); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Imdct"); +#endif + /* currentScratch Size = 4 * MAX_LEN */ + ProcessingIMDCT(q_d_fx, &q_fx_exp, decoder->W_fx, h_DecSetup->stDec_ola_mem_fx, &h_DecSetup->stDec_ola_mem_fx_exp, +#ifdef ENABLE_HR_MODE + x_fx_ip, +#else + x_fx, +#endif + decoder->W_size, decoder->frame_length, decoder->stDec_ola_mem_fx_len, decoder->frame_dms, + h_DecSetup->concealMethod, bfi, h_DecSetup->prev_bfi, h_DecSetup->nbLostFramesInRow, + h_DecSetup->plcAd, + currentScratch +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); + +#ifdef ENABLE_HR_MODE + IF(sub(bfi, 1) != 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_NS_STD) == 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_FREQ_MUTING) == 0) + { + round_w32tow16_arr(x_fx_ip, x_fx, decoder->frame_length); + } + ELSE + { + FOR(i = 0; i < decoder->frame_length; i++) + { + x_fx_ip[i] = L_deposit_h(x_fx[i]); + } + } +#endif /* ENABLE_HR_MODE */ + +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("PLC::Update"); +#endif + + processPLCupdate_fx(h_DecSetup->plcAd, x_fx, q_fx_exp, h_DecSetup->concealMethod, decoder->frame_length, + decoder->fs_idx, &h_DecSetup->nbLostFramesInRow, &h_DecSetup->prev_prev_bfi, + &h_DecSetup->prev_bfi, bfi, scf_q, &h_DecSetup->ns_cum_alpha +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("LtpfDec"); +#endif + /* currentScratch Size = 0.5 * MAX_LEN + 20 bytes */ + process_ltpf_decoder_fx(&q_fx_exp, decoder->frame_length, decoder->ltpf_mem_x_len, decoder->fs_idx, + decoder->ltpf_mem_y_len, &h_DecSetup->ltpf_mem_e, x_fx, h_DecSetup->ltpf_mem_x, x_fx, + h_DecSetup->ltpf_mem_y, ltpf_idx[0], ltpf_idx[1], ltpf_idx[2], + &h_DecSetup->ltpf_mem_pitch_int, &h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ltpf_mem_gain, + &h_DecSetup->ltpf_mem_active, h_DecSetup->ltpf_scale_fac_idx, bfi, + h_DecSetup->concealMethod, + h_DecSetup->plc_damping, &h_DecSetup->ltpf_mem_scale_fac_idx, +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + &h_DecSetup->rel_pitch_change, decoder->hrmode, decoder->frame_dms, +#endif + currentScratch); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef ENABLE_HR_MODE + IF (!(decoder->hrmode)) + { + FOR (i = 0; i < decoder->frame_length; i++) + { + x_fx_ip[i] = L_deposit_h(x_fx[i]); + } + } +#endif + +#ifdef WMOPS + BASOP_sub_start("Output scaling"); +#endif + { + scale = sub(sub(31 + 16, bits_per_sample), q_fx_exp); + offset = L_shr_sat(32768, sub(16, scale)); + IF (bits_per_sample == 16) + { + scale = sub(15, q_fx_exp); + FOR (i = 0; i < decoder->frame_length; i++) + { +#ifdef ENABLE_HR_MODE + ((Word16 *)s_out)[i] = round_fx_sat(L_shr_sat(x_fx_ip[i], scale)); +#else + ((Word16 *)s_out)[i] = round_fx_sat(L_shr_sat(L_deposit_h(x_fx[i]), scale)); +#endif + move16(); + } + } + ELSE + { + FOR (i = 0; i < decoder->frame_length; i++) + { +#ifdef ENABLE_HR_MODE + ((Word32 *)s_out)[i] = L_shr_sat(L_add_sat(x_fx_ip[i], offset), scale); +#else + ((Word32 *)s_out)[i] = L_shr_sat(L_add_sat(L_deposit_h(x_fx[i]), offset), scale); +#endif + move32(); + } + } + } +#ifdef WMOPS + BASOP_sub_end(); /* Output scaling */ +#endif + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_end(); /* Decoder */ +#endif + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return bfi; +} + +/* num_bytes = 0 -> bad frame */ +LC3PLUS_Error Dec_LC3PLUS(LC3PLUS_Dec *decoder, UWord8 *input, int num_bytes, void **output, int bits_per_sample, void *scratch, + int bfi_ext) +{ + int ch = 0, bfi = bfi_ext; + LC3PLUS_Error err = LC3PLUS_OK; + int fec_num_bytes; + int lc3_num_bytes; + int lc3_channel_num_bytes; + int channel_bfi, out_bfi; + Word16 channel_epmr; + + if (bfi == 0) + { + bfi = !num_bytes; + } + + if (decoder->ep_enabled) + { + decoder->combined_channel_coding = decoder->channels > 1 && num_bytes <= 160; + + if (decoder->combined_channel_coding) + { + fec_num_bytes = num_bytes; + +#ifdef WMOPS + BASOP_sub_start("fec_dec"); +#endif + + decoder->error_report = + fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &decoder->epmr, decoder->combined_channel_coding, + &decoder->n_pccw, &bfi, &decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc, + &decoder->m_fec, scratch); + +#ifdef WMOPS + BASOP_sub_end(); +#endif + + for (ch = 0; ch < decoder->channels; ch++) + { + lc3_channel_num_bytes = lc3_num_bytes / decoder->channels + (ch < (lc3_num_bytes % decoder->channels)); + + + if (bfi != 1 && lc3_channel_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_channel_num_bytes); + + if (err) + { + bfi = 1; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_channel_num_bytes; + } + } + + bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], bfi, scratch); + input += decoder->channel_setup[ch]->targetBytes; + } + } + else + { + decoder->epmr = 12; + out_bfi = 0; + + for (ch = 0; ch < decoder->channels; ch++) + { + fec_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels)); + +#ifdef WMOPS + BASOP_sub_start("fec_dec"); +#endif + + channel_bfi = bfi; + + decoder->error_report = + fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &channel_epmr, decoder->combined_channel_coding, + &decoder->n_pccw, &channel_bfi, &decoder->be_bp_left, &decoder->be_bp_right, + &decoder->n_pc, &decoder->m_fec, scratch); + +#ifdef WMOPS + BASOP_sub_end(); +#endif + + decoder->epmr = MIN(decoder->epmr, channel_epmr); + + +#ifdef ENABLE_PADDING + if (channel_bfi != 1) + { + Word16 padding_len, np_zero; + + if (paddingDec_fx(input, shl(lc3_num_bytes, 3), decoder->yLen, decoder->BW_cutoff_bits, + decoder->ep_enabled, &padding_len, &np_zero)) + { + channel_bfi = 1; + } + + input = input + np_zero; + decoder->n_pc = s_max(decoder->n_pc - (2 * np_zero), 0); + + if (channel_bfi == 2) + { + if (decoder->be_bp_right < (8 * np_zero)) + { + channel_bfi = 0; + decoder->be_bp_left = -1; + decoder->be_bp_right = -1; + } + else + { + decoder->be_bp_right = decoder->be_bp_right - (8 * np_zero); + decoder->be_bp_left = s_max(decoder->be_bp_left - (8 * np_zero), 0); + } + } + + lc3_num_bytes = lc3_num_bytes - padding_len; + } +#endif + + if (channel_bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_num_bytes); + if (err) + { + channel_bfi = 1; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_num_bytes; + } + } + + channel_bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], channel_bfi, scratch); + + out_bfi |= channel_bfi; + input += fec_num_bytes; + } + + bfi = out_bfi & 1; + } + } + else + { + for (ch = 0; ch < decoder->channels; ch++) + { + lc3_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels)); + +#ifdef ENABLE_PADDING + if (bfi != 1) + { + Word16 padding_len, np_zero; + + if (paddingDec_fx(input, shl(lc3_num_bytes, 3), decoder->yLen, decoder->BW_cutoff_bits, + decoder->ep_enabled, &padding_len, &np_zero)) + { + bfi = 1; + } + + lc3_num_bytes = lc3_num_bytes - padding_len; + if (lc3_num_bytes < 20 || lc3_num_bytes > LC3PLUS_MAX_BYTES) + { + bfi = 1; /* mark frame as broken if frame sizeif below the minimum of 20 bytes */ + } + } +#endif + + if (bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_num_bytes); + if (err) + { + bfi = 1; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_num_bytes; + } + } + + bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], bfi, scratch); + input += decoder->channel_setup[ch]->targetBytes; + } + } + + return bfi == 1 ? LC3PLUS_DECODE_ERROR : LC3PLUS_OK; +} diff --git a/lib_lc3plus/dec_lc3_fl.c b/lib_lc3plus/dec_lc3_fl.c deleted file mode 100644 index 648326567..000000000 --- a/lib_lc3plus/dec_lc3_fl.c +++ /dev/null @@ -1,373 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs_in, void* s_out, int bps, int bfi_ext) -{ - DecSetup* h_DecSetup; - LC3_INT mask_side = 0, bp_side = 0, bfi = 0, gg_idx = 0, fac_ns_idx = 0, tns_numfilters = 0, bw_cutoff_idx = 0, - lastnz = 0, lsbMode = 0, nf_seed = 0, zero_frame = 0, residualPresent = 0, nbits_residual = 0, bitsRead = 0, - i = 0, tns_order[2] = {0}, sqQdec[MAX_LEN] = {0}; - LC3_INT b_left; - LC3_FLOAT stab_fac = 0; - - h_DecSetup = decoder->channel_setup[channel]; - - memset(h_DecSetup->tns_idx, 0, sizeof(*h_DecSetup->tns_idx) * TNS_NUMFILTERS_MAX * MAXLAG); - - bfi = bfi_ext; - - decoder->rframe = 0; - if (bfi == 3) - { - bfi = 2; - decoder->rframe = 1; - } - - /* Entropy decoding */ - if (bfi != 1) { - processDecoderEntropy_fl(bs_in, h_DecSetup->targetBytes, &mask_side, &bp_side, decoder->yLen, decoder->fs_idx, - decoder->BW_cutoff_bits, &bfi, &gg_idx, h_DecSetup->scf_idx, &fac_ns_idx, - &tns_numfilters, tns_order, h_DecSetup->ltpf_param, &bw_cutoff_idx, &lastnz, &lsbMode, decoder->frame_dms - ); - h_DecSetup->BW_cutoff_idx_nf = bw_cutoff_idx; - } - - /* Arithmetic decoding */ - if (bfi != 1) { - processAriDecoder_fl(bs_in, bp_side, mask_side, decoder->yLen, decoder->fs_idx, - h_DecSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &bfi, tns_order, fac_ns_idx, gg_idx, h_DecSetup->resBits, - sqQdec, &nf_seed, h_DecSetup->tns_idx, &zero_frame, h_DecSetup->targetBytes, &nbits_residual, &residualPresent, decoder->frame_dms, - decoder->n_pc, decoder->be_bp_left, decoder->be_bp_right, 0, &b_left, &h_DecSetup->spec_inv_idx, - decoder->hrmode - ); - - if (decoder->rframe == 1 && zero_frame == 0 && bfi != 1) - { - LC3_INT32 max_bw_stopband = BW_cutoff_bin_all[bw_cutoff_idx]; - bfi = 2; - switch (decoder->frame_dms) - { - case 25: - max_bw_stopband = max_bw_stopband >> 2; - break; - case 50: - max_bw_stopband = max_bw_stopband >> 1; - break; -#ifdef CR8_G_ADD_75MS - case 75: - max_bw_stopband = 3 * (max_bw_stopband >> 2); - break; -#endif - case 100: - break; - } - - h_DecSetup->spec_inv_idx = MAX(lastnz, max_bw_stopband); - } - - /* Cast from int to float */ - for (i = 0; i < decoder->yLen; i++) { - h_DecSetup->sqQdec_fl[i] = (LC3_FLOAT)sqQdec[i]; - } - } - - if (bfi != 1) - { - /* SNS Quantize Decoder */ - process_snsQuantizesScf_Dec(h_DecSetup->scf_idx, h_DecSetup->scf_q); - } - if (h_DecSetup->PlcAdvSetup) - { - processPlcComputeStabFacMain_fl(h_DecSetup->scf_q, h_DecSetup->PlcAdvSetup->scf_q_old, h_DecSetup->PlcAdvSetup->scf_q_old_old, bfi, h_DecSetup->PlcSetup.prevBfi, - h_DecSetup->PlcSetup.prevprevBfi, &h_DecSetup->PlcAdvSetup->stabFac); - } - - if ( bfi != 1 ) - { - stab_fac = 1; - if (h_DecSetup->PlcAdvSetup) - { - stab_fac = h_DecSetup->PlcAdvSetup->stabFac; - } - - /* Partial Concealment */ - processPcMain_fl(&bfi, decoder, h_DecSetup->sqQdec_fl, h_DecSetup, h_DecSetup->ltpf_param[0], stab_fac, gg_idx, h_DecSetup->quantizedGainOff, - fac_ns_idx, &h_DecSetup->statePC, h_DecSetup->spec_inv_idx, decoder->yLen); - } - - /* Decoding only if no bit error detected */ - if (bfi != 1) { - /* Residual decoding */ - if (residualPresent) { - processResidualDecoding_fl(&bitsRead, h_DecSetup->sqQdec_fl, decoder->yLen, h_DecSetup->resBits, - nbits_residual - , decoder->hrmode - ); - } - - - /* Noise filling */ - if (zero_frame == 0) { - processNoiseFilling_fl(h_DecSetup->sqQdec_fl, nf_seed, fac_ns_idx, decoder->cutoffBins[h_DecSetup->BW_cutoff_idx_nf], decoder->frame_dms, h_DecSetup->prev_fac_ns, h_DecSetup->spec_inv_idx); - } - - /* Application of global gain */ - processApplyGlobalGain_fl(h_DecSetup->sqQdec_fl, decoder->yLen, gg_idx, h_DecSetup->quantizedGainOff); - - /* TNS decoder */ - processTnsDecoder_fl(h_DecSetup->sqQdec_fl, h_DecSetup->tns_idx, tns_order, tns_numfilters, - decoder->cutoffBins[bw_cutoff_idx], h_DecSetup->N_red_tns, h_DecSetup->fs_red_tns); - - /* SNS interpolation */ - processSnsInterpolateScf_fl(h_DecSetup->scf_q, 0, decoder->bands_number, h_DecSetup->int_scf); - - /* MDCT shaping */ - processMdctShaping_fl(h_DecSetup->sqQdec_fl, h_DecSetup->int_scf, decoder->bands_offset, decoder->bands_number); - } - - /* PLC */ - processPlcMain_fl(h_DecSetup->sqQdec_fl, h_DecSetup->x_fl, decoder, h_DecSetup, bfi, h_DecSetup->PlcAdvSetup, &h_DecSetup->PlcSetup, - decoder->plcMeth, h_DecSetup->ltpf_mem_pitch, h_DecSetup->ltpf_mem_pitch_fr, decoder->tilt, decoder->bands_offset, - decoder->bands_number, decoder->bands_offsetPLC, decoder->n_bandsPLC, decoder->hrmode, &h_DecSetup->statePC); - - processPlcDampingScramblingMain_fl(&h_DecSetup->PlcNsSetup.seed, - &h_DecSetup->statePC.seed, h_DecSetup->statePC.ns_nbLostCmpt_pc, - h_DecSetup->PlcSetup.nbLostCmpt, &h_DecSetup->PlcAdvSetup->stabFac, - &h_DecSetup->PlcAdvSetup->cum_fading_slow, &h_DecSetup->PlcAdvSetup->cum_fading_fast, - h_DecSetup->PlcSetup.q_d_prev, h_DecSetup->sqQdec_fl, h_DecSetup->spec_inv_idx, decoder->yLen, bfi, - decoder->frame_dms, h_DecSetup->concealMethod, h_DecSetup->ltpf_mem_pitch, h_DecSetup->ltpf_param[0], - &h_DecSetup->PlcAdvSetup->cum_fflcAtten -#ifdef CR8_A_PLC_FADEOUT_TUNING - , h_DecSetup->PlcAdvSetup->plc_fadeout_type -#endif - ); - - /* IMDCT */ - if (h_DecSetup->concealMethod == 4 || bfi != 1 ) - { - ProcessingIMDCT_fl(h_DecSetup->sqQdec_fl, decoder->frame_length, decoder->imdct_win, decoder->imdct_winLen, decoder->imdct_laZeros, - h_DecSetup->imdct_mem, h_DecSetup->x_fl, &h_DecSetup->dct4structImdct); - } - - processPlcUpdate_fl(h_DecSetup->PlcAdvSetup - , decoder->frame_length, h_DecSetup->x_fl, h_DecSetup->scf_q, - &h_DecSetup->PlcSetup.nbLostCmpt, &h_DecSetup->PlcNsSetup.cum_alpha, bfi, &h_DecSetup->PlcSetup.prevBfi, &h_DecSetup->PlcSetup.prevprevBfi); - - /* LTPF decoder */ - process_ltpf_decoder_fl(h_DecSetup->x_fl, decoder->frame_length, h_DecSetup->x_fl, decoder->fs, - h_DecSetup->ltpf_mem_x, h_DecSetup->ltpf_mem_y, &h_DecSetup->ltpf_mem_pitch, - &h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ltpf_mem_gain, &h_DecSetup->ltpf_mem_beta_idx, - bfi, h_DecSetup->ltpf_param, h_DecSetup->ltpf_param_mem, h_DecSetup->ltpf_conf_beta_idx, - h_DecSetup->ltpf_conf_beta, h_DecSetup->concealMethod, h_DecSetup->alpha - , &h_DecSetup->ltpf_mem_active -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - , &h_DecSetup->rel_pitch_change, decoder->hrmode, decoder->frame_dms -#endif - ); - - { - /* Round, scale and copy output to output buffer */ - if (bps == 16) { - for (i = 0; i < decoder->frame_length; i++) { - LC3_FLOAT tmp = round(h_DecSetup->x_fl[i]); - ((int16_t*)s_out)[i] = (int16_t)fmaxf(fminf(tmp, 32767), -32768); - } - } else { - for (i = 0; i < decoder->frame_length; i++) { - LC3_FLOAT tmp = round(LC3_CONST_POW_2_23 * LC3_CONST_POW_2_M15 * h_DecSetup->x_fl[i]); - ((int32_t*)s_out)[i] = (int32_t)fmaxf(fminf(tmp, LC3_CONST_POW_2_23_RED), LC3_CONST_POW_2_23_NEG); - } - } - } - return bfi; -} - -LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num_bytes, void** output, LC3_INT32 bps, LC3_INT32 bfi_ext) -{ - LC3_INT32 ch, bfi, lc3_num_bytes; - LC3PLUS_Error err; - LC3_INT32 fec_num_bytes; - LC3_INT32 lc3_channel_num_bytes; - LC3_INT32 channel_bfi, out_bfi; - LC3PLUS_EpModeRequest channel_epmr; - - bfi = bfi_ext; - lc3_num_bytes = 0; - err = LC3PLUS_OK; - - if (bfi == 0) - { - bfi = !num_bytes; - } - - if (decoder->ep_enabled) - { - decoder->combined_channel_coding = decoder->channels > 1 && num_bytes <= 160; - - if (decoder->combined_channel_coding) - { - fec_num_bytes = num_bytes; - - decoder->error_report = - fec_decoder(input, fec_num_bytes, &lc3_num_bytes, (LC3PLUS_EpModeRequest*)&decoder->epmr, decoder->combined_channel_coding, - &decoder->n_pccw, &bfi, &decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc, &decoder->m_fec); - - for (ch = 0; ch < decoder->channels; ch++) - { - lc3_channel_num_bytes = lc3_num_bytes / decoder->channels + (ch < (lc3_num_bytes % decoder->channels)); - - - if (bfi != 1 && lc3_channel_num_bytes != decoder->channel_setup[ch]->last_size) - { - err = update_dec_bitrate(decoder, ch, lc3_channel_num_bytes); - if (err) - { - bfi = 1; - decoder->last_error = err; - } - else - { - decoder->channel_setup[ch]->last_size = lc3_channel_num_bytes; - } - } - - bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, bfi); - input += decoder->channel_setup[ch]->targetBytes; - } - } - else - { - decoder->epmr = LC3PLUS_EPMR_HIGH_NC; - out_bfi = 0; - - for (ch = 0; ch < decoder->channels; ch++) - { - fec_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels)); - - channel_bfi = bfi; - - decoder->error_report = fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &channel_epmr, - decoder->combined_channel_coding, &decoder->n_pccw, &channel_bfi, - &decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc, &decoder->m_fec); - - decoder->epmr = MIN((LC3PLUS_EpModeRequest) decoder->epmr, channel_epmr); - - -#ifdef ENABLE_PADDING - if (channel_bfi != 1) - { - LC3_INT32 padding_len = 0, np_zero = 0; - - if (paddingDec_fl(input, (lc3_num_bytes << 3), decoder->yLen, decoder->BW_cutoff_bits, decoder->ep_enabled, &padding_len, &np_zero)) - { - channel_bfi = 1; - } - - input = input + np_zero; - decoder->n_pc = MAX(decoder->n_pc - (2 * np_zero), 0); - - if (channel_bfi == 2) - { - if (decoder->be_bp_right < (8 * np_zero)) - { - channel_bfi = 0; - decoder->be_bp_left = -1; - decoder->be_bp_right = -1; - } - else - { - decoder->be_bp_right = decoder->be_bp_right - (8 * np_zero); - decoder->be_bp_left = MAX(decoder->be_bp_left - (8 * np_zero), 0); - } - } - lc3_num_bytes = lc3_num_bytes - padding_len; - } -#endif - - if (channel_bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size) - { - err = update_dec_bitrate(decoder, ch, lc3_num_bytes); - if (err) - { - channel_bfi = 1; - decoder->last_error = err; - } - else - { - decoder->channel_setup[ch]->last_size = lc3_num_bytes; - } - } - - channel_bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, channel_bfi); - - out_bfi |= channel_bfi; - input += fec_num_bytes; - } - - bfi = out_bfi & 1; - } - } - else - { - for (ch = 0; ch < decoder->channels; ch++) - { - lc3_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels)); - -#ifdef ENABLE_PADDING - if (bfi != 1) - { - LC3_INT32 padding_len = 0, np_zero = 0; - - if (paddingDec_fl(input, (lc3_num_bytes << 3), decoder->yLen, decoder->BW_cutoff_bits, decoder->ep_enabled, &padding_len, &np_zero)) - { - bfi = 1; - decoder->last_error = LC3PLUS_PADDING_ERROR; - } - - lc3_num_bytes = lc3_num_bytes - padding_len; - if (lc3_num_bytes < 20 || lc3_num_bytes > LC3PLUS_MAX_BYTES) - { - bfi = 1; /* mark frame as broken if frame size is below the minimum of 20 bytes or above the maximum of LC3PLUS_MAX_BYTES */ - decoder->last_error = FRAMESIZE_ERROR; - } - } -#endif - - if (bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size) - { - err = update_dec_bitrate(decoder, ch, lc3_num_bytes); - if (err) - { - bfi = 1; - decoder->last_error = err; - } - else - { - decoder->channel_setup[ch]->last_size = lc3_num_bytes; - } - } - - bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, bfi); - input += decoder->channel_setup[ch]->targetBytes; - } - } - - if ((decoder->last_error == LC3PLUS_OK) && bfi) - { - decoder->last_error = LC3PLUS_DECODE_ERROR; - } - - return bfi == 1 ? LC3PLUS_DECODE_ERROR : LC3PLUS_OK; -} diff --git a/lib_lc3plus/defines.h b/lib_lc3plus/defines.h index 2ee688e6c..c9909ddf2 100644 --- a/lib_lc3plus/defines.h +++ b/lib_lc3plus/defines.h @@ -1,288 +1,300 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef DEFINES_H #define DEFINES_H -#include "options.h" -#include "wmc_auto.h" -#include "stdint.h" - - -typedef float LC3_FLOAT; -typedef int32_t LC3_INT; -typedef int16_t LC3_INT16; -typedef uint16_t LC3_UINT16; -typedef short LC3_SHORT; -typedef uint8_t LC3_UINT8; -typedef int8_t LC3_INT8; -typedef uint32_t LC3_UINT32; - -/* Release defines */ -#define ENABLE_2_5MS_MODE -#define ENABLE_5MS_MODE -#define ENABLE_075_DMS_MODE -#define ENABLE_10_MS_MODE -#define ENABLE_ADVANCED_PLC_FL -#define ENABLE_ADVANCED_PLC_FL_DEFAULT -#define ENABLE_BW_CONTROLLER -#define ENABLE_HR_MODE_FL -#define ENABLE_PADDING -#define ENABLE_RFRAME_FL -#define ENABLE_PLC -/* flags */ -#define ENABLE_PLC_MODE_FLAG -#define ENABLE_BANDWIDTH_FLAG -#define ENABLE_EP_MODE_FLAG -#define ENABLE_FRAME_MS_FLAG -#define ENABLE_HR_MODE_FL_FLAG - -#define CR8_G_ADD_75MS - -#ifndef NO_POST_REL_CHANGES -/* Post-release non-bitexact changes */ -#define CR8_A_PLC_FADEOUT_TUNING /* Adapt PLC fadeout to avoid gaps in signal */ -#define CR9_D_FLOATING_POINT_CODE_SIMPLIFICATIONS -#define CR9_F_PITCH_WIN_LEN_FIX /* Increase window length for pitch calculation */ -#define CR9_G_IMPROVE_TDC /* summarize G,H,J,L,N */ -#ifdef CR9_G_IMPROVE_TDC -#define CR9_G_PLC_NS_TDC_FIX /* Always use TDC if pitch > 0 */ -#define CR9_H_REMOVE_SWITCH_TO_PLC_NS -#define CR9_J_SLOW_TDC_FADEOUT -#define CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER -#ifdef ENABLE_HR_MODE_FL -#ifdef PLC_TUNING_SHORT_FADEOUT -#define CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH -#endif +#ifndef DISABLE_HR_MODE +# define ENABLE_HR_MODE #endif -#endif /* CR9_G_IMPROVE_TDC */ -#define CR9_I_INC_TDC_FADEOUT_LEN -#define CR9_K_REDUCE_NORM_CORR_TH -#endif /* NO_POST_REL_CHANGES */ - -#ifdef CR9_D_FLOATING_POINT_CODE_SIMPLIFICATIONS -#define CR9_SIMPLIFY_LOOP -#define CR9_LTPF_REWRITE -#define CR9_QUANT_SPEC_REWRITE -#define CR9_SIMPLIFY_ARI_DECODER +#ifdef ENABLE_HR_MODE +# define MAX_BW_HR 960 #endif -#ifdef CR8_A_PLC_FADEOUT_TUNING -#define MAX_UINT8 255 -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER -#ifdef CR9_K_REDUCE_NORM_CORR_TH -#define THRESH_100_DMS_TDC_CNT 9 -#define THRESH_100_DMS_NS_CNT 7 -#define THRESH_100_DMS_TDC_NS_CNT 73 -#define THRESH_075_DMS_TDC_CNT 7 -#define THRESH_075_DMS_NS_CNT 7 -#define THRESH_075_DMS_TDC_NS_CNT 87 -#define THRESH_050_DMS_TDC_CNT 22 -#define THRESH_050_DMS_NS_CNT 15 -#define THRESH_050_DMS_TDC_NS_CNT 141 -#define THRESH_025_DMS_TDC_CNT 20 -#define THRESH_025_DMS_NS_CNT 21 -#define THRESH_025_DMS_TDC_NS_CNT 278 +#ifdef ENABLE_HR_MODE +# define extractW16(a) extract_h(a) #else -#define THRESH_100_DMS_TDC_CNT 3 -#define THRESH_100_DMS_NS_CNT 35 -#define THRESH_100_DMS_TDC_NS_CNT 114 -#define THRESH_075_DMS_TDC_CNT 6 -#define THRESH_075_DMS_NS_CNT 37 -#define THRESH_075_DMS_TDC_NS_CNT 130 -#define THRESH_050_DMS_TDC_CNT 12 -#define THRESH_050_DMS_NS_CNT 55 -#define THRESH_050_DMS_TDC_NS_CNT 227 -#define THRESH_025_DMS_TDC_CNT 10 -#define THRESH_025_DMS_NS_CNT 138 -#define THRESH_025_DMS_TDC_NS_CNT 431 +# define extractW16(a) (a) #endif + +#define MAX_BR 320000 /* 400 * 800 */ + +/* FUNCTION MACROS */ +/* NB, divisions in some of these MACROs, use mainly for initial setup, do not use in loops */ +#define CEILING(x, y) (((x) + (y)-1) / (y)) + +#define FRAME2FS_IDX(x) (x / 100) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4 */ +#ifdef ENABLE_HR_MODE +# define FS2FS_IDX(x) ((x) == 96000 ? 5 : (x) / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4, 96000 -> 5 */ #else -#define FAC1_FADEOUT 0.2 -#define FAC2_FADEOUT 1.5 -#define FAC3_FADEOUT 1.75 +# define FS2FS_IDX(x) (x / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4 */ #endif -#define REL_PITCH_THRESH 0.36 -#define PLC_LONGTERM_ANALYSIS_MS 200 /* Analysis window 2000 ms / 10 ms */ - -#define PLC_LONGTERM_ANALYSIS_STARTUP_FILL 0.5f /* required buffer fill amount, set to 0.0 to not require any fill at all */ - -#endif +#define UNUSED(x) (void)(x) /* silence unused parameter warning */ +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define STATIC_ASSERTS(cond, s) typedef char assert_##s[(cond) ? 1 : -1] +#define STATIC_ASSERTI(cond, i) STATIC_ASSERTS(cond, i) +#define STATIC_ASSERT(cond) STATIC_ASSERTI(cond, __LINE__) +#define TRACE(x) PRINTF("%s:%i %s = %i\n", __FILE__, __LINE__, #x, (int)(x)) -/* Precision Defines */ -#define LC3_FABS(x) (fabsf(x)) -#define LC3_POW(x, y) (powf(x, y)) -#define LC3_LOGTEN(x) (log10f(x)) -#define LC3_LOGTWO(x) (log2f(x)) -#define LC3_COS(x) (cos(x)) -#define LC3_SIN(x) (sin(x)) -#define LC3_SQRT(x) (sqrtf(x)) -#define LC3_EXP(x) (expf(x)) +/* For dynamic memory calculations */ +#define CODEC_FS(fs) ((fs) == 44100 ? 48000 : (fs)) -#define MAX_BR 320000 /* 400 * 800 */ -#define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ -#define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */ -#define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */ -#define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */ -#define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ -#define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ -#define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ +#define DYN_MAX_LEN(fs) (CODEC_FS(fs) / 100) +#define DYN_MAX_LEN_EXT(fs) MAX(CODEC_FS(fs) / 100, 160) /* extension to length 160 for NB(fs=8000) */ +#define DYN_MAX_LPROT(fs) ((512 * (CODEC_FS(fs) / 100)) / 320) -#ifdef CR8_G_ADD_75MS -#define MIN_BR_075DMS_48KHZ_HR ((int)124800/ 800/2)* 800 -#define MIN_BR_075DMS_96KHZ_HR ((int)149600/ 800/2)* 800 -#define MIN_BR_075DMS 21334 /* ceil( 20 * 800 * 100/ 75) */ -#define MAX_BR_075DMS 426667 /* ceil(400 * 800 * 100/ 75) */ -#define MAX_BR_075DMS_NB 152534 /* ceil(143 * 800 * 100/ 75) */ -#define MAX_BR_075DMS_WB 295467 /* ceil(277 * 800 * 100/ 75) */ -#define MAX_BR_075DMS_SSWB 419200 /* ceil(393 * 800 * 100/ 75) */ -#endif -#define CR8_E_TONE_DETECTOR /* Tone detector for hrmode to deactivate TNS - improves SNR and THD+N */ +#define DYN_MAX_PLOCS(fs) (DYN_MAX_LPROT(fs) / 4 + 1) +#define DYN_MAX_MDCT_LEN(fs) (DYN_MAX_LEN(fs) - (180 * DYN_MAX_LEN(fs) / 480)) -typedef int32_t LC3_INT32; +#define MAX_PITCH_FS(fs) (CEILING((MAX_PITCH_12K8 * CODEC_FS(fs)), (12800))) -#if defined(__xtensa__) -#define ALIGNMENT_BALLOC 4 -#define ALIGNMENT_BALLOC_RED 3 -#else -#define ALIGNMENT_BALLOC 8 -#define ALIGNMENT_BALLOC_RED 7 -#endif +/* get the maximum buffer size assuming 10 ms framing */ +/* MAX_PITCH was previously always the highest fs in the current SUBSET , i.e. typically 48 kHz */ +/* now fs(from incoming wav file) adaptive MAX_PITCH_FS(fs) is used instead */ +#define DYN_MAX_LEN_PCM_PLC_CLASSIFIER(fs) \ + (MAX_PITCH_FS(fs) + DYN_MAX_LEN(fs)) /* CLASSIFIER PCM memory requirement */ +#define DYN_MAX_LEN_PCM_PLC_TDCAPPLYFILTER(fs) \ + ((M + 1) + MAX_PITCH_FS(fs) + (DYN_MAX_LEN(fs) / 2)) /* TDC filtering PCM memory requirement */ -#ifndef CR8_A_PLC_FADEOUT_TUNING -#define PLC2_FADEOUT_IN_MS 30 +#ifdef ENABLE_HR_MODE +# define DYN_MAX_LEN_PCM_PLC(fs) (MAX_PITCH_FS(fs) + DYN_MAX_LEN(fs)) +#else +# define DYN_MAX_LEN_PCM_PLC(fs) MAX(DYN_MAX_LEN_PCM_PLC_CLASSIFIER(fs), DYN_MAX_LEN_PCM_PLC_TDCAPPLYFILTER(fs)) #endif -#ifdef CR8_A_PLC_FADEOUT_TUNING -/* PLC2/PhEcu fading settings */ -/* PLC2/PHEcu muting Table setup settings */ -#define PLC2_FADEOUT_IN_MS_MIN 30 /* Table min */ -#define PLC2_FADEOUT_IN_MS_MAX 140 /* Table max */ -#define PLC2_FADEOUT_RES 10 /* 10 ms steps used in fadeout constant tables */ - -/* current active settings */ -#define PLC2_FADEOUT_IN_MS 30 /* 30 P800 fadeout optimized */ -#define PLC2_FADEOUT_LONG_IN_MS 120 /* 120 MUSHRA, && stable tonal fadeout optimized */ +#define FRAME_MS_BLOCK 25 -#endif +/* OPTIONS */ +#define ENABLE_2_5MS_MODE +#define ENABLE_5MS_MODE +#define ENABLE_075_DMS_MODE +#define ENABLE_10_MS_MODE +#define ENABLE_ADVANCED_PLC +#define ENABLE_ADVANCED_PLC_DEFAULT +#define ENABLE_BW_CONTROLLER +#define ENABLE_ERROR_PROTECTION +#define ENABLE_RFRAME +#define ENABLE_PC +#define ENABLE_PLC +#define ENABLE_PADDING +/* flags */ +#define ENABLE_BANDWIDTH_FLAG +#define ENABLE_RBANDWIDTH_FLAG +#define ENABLE_EP_MODE_FLAG +#define ENABLE_FRAME_MS_FLAG -#define PHECU_FRES 62.5 -#define PHECU_C_JACOB 1.1429 -#define MAX_LGW 9 /* LGW48K + 1 !! */ -#define QUOT_LPR_LTR 4 -#define MAX_PLC_LPROT ((512 * 48) / 32) -#define MAX_PLC_NPLOCS ((MAX_PLC_LPROT / 4) + 1) -#define MAX_PLC_LMSPEC ((MAX_PLC_LPROT / 2) + 1) -#define MAX_PLC_LMEM (400) /* "only" up to 20kHz (400 MDCT bins at 10 ms) at 48 kHz supported by PhEcu */ - -#define POS_ONE_Q15 (32767.0 / 32768.0) -#define PHECU_LTOT_MIN_MAN 1 /* lowest possible mantissa energy value */ -#define PHECU_LTOT_MIN_EXP -61 /* L_tot = PHECU_LTOT_MIN_MAN*2^(PHECU_LTOT_MIN_EXP-31) */ -#define PHECU_LTOT_MIN -#define PHECU_GRP_SHAPE_INIT 0 /* BASOP Q15 */ -#define PHECU_ENV_STAB_LOCAL POS_ONE_Q15 -#define PHECU_DELTA_CORR 5 -#define PHECU_PFIND_SENS 0.93 -#define PHECU_LA 0 - -#define LC3_ROUND(x) (roundf(x)) -#define LC3_FLOOR(x) (floorf(x)) - -#define LC3_CONST_POW_2_16 65536 -#define LC3_CONST_POW_2_M16 1.525878906250000e-05 -#define LC3_CONST_POW_2_100 1.267650600228229e+30 +#define CR8_A_PLC_FADEOUT_TUNING /* Adapt PLC fadeout to avoid gaps in signal */ +#define CR8_E_TONE_DETECTOR /* Tone detector for hrmode to deactivate TNS - improves SNR and THD+N */ +#define CR8_F_ADAPT_MDCT_DCT_PRECISION +#define CR8_G_ADD_75MS -#define MAX_LEN_PCM_PLC (MAX_PITCH + MAX_LEN) -#define MAX_PITCH CEILING((MAX_PITCH_12K8 * MAX_LEN * 100), 12800) -#define TDC_L_FIR_HP 11 -#define PLC3_HPBLENDTHROTTLE 30 /* higher numbers increase throttled blending from hp filtered to unfiltered uv excitation (0 is no throttle) */ -#ifdef CR9_I_INC_TDC_FADEOUT_LEN -#define PLC_FADEOUT_TYPE_1_IN_MS 200 -#endif -#define PLC_FADEOUT_IN_MS 60 /* fade-out to zero in ms for TD-PLC and NS, minimum value is 20 */ -#define PLC4_TRANSIT_START_IN_MS 20 /* begin of transition time for noise substitution for voiced signals */ -#define PLC4_TRANSIT_END_IN_MS PLC_FADEOUT_IN_MS /* end of transition time for noise substitution */ -#define PLC34_ATTEN_FAC_100 0.5000 /* attenuation factor for NS and TDC @ 10 ms*/ -#ifdef CR8_G_ADD_75MS -#define PLC34_ATTEN_FAC_075 0.5946 /* attenuation factor for NS and TDC @ 7.5 ms */ -#endif -#define PLC34_ATTEN_FAC_050 0.7071 /* attenuation factor for NS and TDC @ 5.0 ms*/ -#define PLC34_ATTEN_FAC_025 0.8409 /* attenuation factor for NS and TDC @ 2.5 ms*/ +#define CR9_B_FIX_MDCT_OVERFLOW /* Fix overflow */ +#define CR9_C_FIX_DCT2_OVERFLOW /* Fix overflow */ -#define FEC_SLOT_BYTES_MIN 40 -#define FEC_SLOT_BYTES_MAX 400 +#define CR9_F_PITCH_WIN_LEN_FIX /* Increase window length for pitch calculation */ +#define CR9_G_IMPROVE_TDC /* summarize G,H,J,L,N */ +#ifdef CR9_G_IMPROVE_TDC +# define CR9_G_PLC_NS_TDC_FIX /* Always use TDC if pitch > 0 */ +# define CR9_H_REMOVE_SWITCH_TO_PLC_NS +# define CR9_J_SLOW_TDC_FADEOUT +# define CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER +# ifdef ENABLE_HR_MODE +# define CR10_A_ATTENUATION_CURVE_SELECTOR +# ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +# define CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH +# endif +# endif +#endif /* CR9_G_IMPROVE_TDC */ +#define CR9_I_INC_TDC_FADEOUT_LEN +#define CR9_K_REDUCE_NORM_CORR_TH +#define CR9_M_FIX_DIV_ZERO -#define LC3_CONST_POW_2_M15 3.051757812500000e-05 -#define LC3_CONST_POW_2_23 8388608 -#define LC3_CONST_POW_2_23_NEG -8388608 -#define LC3_CONST_POW_2_23_RED 8388607 +#ifndef NO_POST_REL_CHANGES +/* Post-release non-bitexact changes */ -#define LC3_CONST_POW_2_100 1.267650600228229e+30 +#define CR11_A_FIX_IN_PLC_LONGTERM_STATISTIC + +#endif /* NO_POST_REL_CHANGES Post-release changes */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING +# ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER +# ifdef CR9_K_REDUCE_NORM_CORR_TH +# define THRESH_100_DMS_TDC_CNT 9 +# define THRESH_100_DMS_NS_CNT 7 +# define THRESH_100_DMS_TDC_NS_CNT 73 +# define THRESH_075_DMS_TDC_CNT 7 +# define THRESH_075_DMS_NS_CNT 7 +# define THRESH_075_DMS_TDC_NS_CNT 87 +# define THRESH_050_DMS_TDC_CNT 22 +# define THRESH_050_DMS_NS_CNT 15 +# define THRESH_050_DMS_TDC_NS_CNT 141 +# define THRESH_025_DMS_TDC_CNT 20 +# define THRESH_025_DMS_NS_CNT 21 +# define THRESH_025_DMS_TDC_NS_CNT 278 +# else +# define THRESH_100_DMS_TDC_CNT 3 +# define THRESH_100_DMS_NS_CNT 35 +# define THRESH_100_DMS_TDC_NS_CNT 114 +# define THRESH_075_DMS_TDC_CNT 6 +# define THRESH_075_DMS_NS_CNT 37 +# define THRESH_075_DMS_TDC_NS_CNT 130 +# define THRESH_050_DMS_TDC_CNT 12 +# define THRESH_050_DMS_NS_CNT 55 +# define THRESH_050_DMS_TDC_NS_CNT 227 +# define THRESH_025_DMS_TDC_CNT 10 +# define THRESH_025_DMS_NS_CNT 138 +# define THRESH_025_DMS_TDC_NS_CNT 431 +# endif +# else +# define FAC1_FADEOUT 6710886 /* 0.2 * 2^25 */ +# define SHIFT1_FADEOUT 25-15 /* 25 - 16 */ +# define FAC2_FADEOUT 50331648 /* 1.5 * 2^25 */ +# define SHIFT2_FADEOUT 25-15 /* 25 - 16 */ +# define FAC3_FADEOUT 58720256 /* 1.75 * 2^25 */ +# define SHIFT3_FADEOUT 25-15 /* 25 - 16 */ +# endif +# define PLC_LONGTERM_ANALYSIS_MS 200 /* Nominal analysis window 2000 ms */ +# define PLC_LONGTERM_ANALYSIS_STARTUP_FILL (Word16)(0.5*32768.0) /* 16384/32768 == 0.5 required buffer fill amount, set to 0.0 to not require any fill at all */ +#endif /* CR8_A_PLC_FADEOUT_TUNING */ + +#define REL_PITCH_THRESH 11796 + +# define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ +# ifdef SUBSET_NB +# define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ +# endif +# ifdef SUBSET_WB +# define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ +# endif +# ifdef SUBSET_SSWB +# define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ +# endif /* G192 bitstream writing/reading */ -#define G192_REDUNDANCY_FRAME 0x6B22 #define G192_GOOD_FRAME 0x6B21 #define G192_BAD_FRAME 0x6B20 +#define G192_REDUNDANCY_FRAME 0x6B22 #define G192_ZERO 0x007F #define G192_ONE 0x0081 -#define READ_G192FER /* Allow C executable to also read G192 formatted FER files */ +#define READ_G192FER /* allow C executable to also read G192 formatted FER files */ -#ifdef DEBUG +#ifdef DEBUG #ifdef READ_G192FER -#define READ_G192_FER_BYTE /* Allow C executable to also read G192 byte formatted FER files 0x20=BAD , 0x21=Good */ +# define READ_G192_FER_BYTE /* Allow C executable to also read G192 byte formatted FER files 0x20=BAD , 0x21=Good */ #endif #endif -#define LC3_EPS (1.1e-7f) +// #define DYNMEM_COUNT +#define STAMEM_COUNT -#define M_PI 3.14159265358979323846 -/* FUNCTION MACROS */ -#define CEILING(x, y) (((x) + (y)-1) / (y)) +/* +do not change __forceinline for mex compilation using gcc6.3.0 or larger + gcc630 supported by MATLAB 2018b, via Mingw "app" + */ +#ifdef __GNUC__ +# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +/* Define __forceinline as empty if ARM not activated to avoid any errors */ +#undef __forceinline +/* The above undef is needed to compile using make_mex.m without the following warning in Matlab for windows */ +#define __forceinline + +/* SUBSETS */ +#if !(defined(SUBSET_NB) || defined(SUBSET_WB) || defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB) || defined(SUBSET_UB)) +# define SUBSET_NB +# define SUBSET_WB +# define SUBSET_SSWB +# define SUBSET_SWB +# define SUBSET_FB +# ifdef ENABLE_HR_MODE +# define SUBSET_UB +# endif +#endif -#ifdef CR8_A_PLC_FADEOUT_TUNING -#define FRAME2FS_IDX_10MS(x) (x<500 ? (x/100) : 5) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4 , 960 -> 5*/ -#define FS2FS_IDX(x) ((x) == 96000 ? 5 : (x) / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4, 96000 -> 5 */ -#else -#define FRAME2FS_IDX(x) (x / 100) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4*/ -#define FS2FS_IDX(x) \ - (x / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4 \ - */ -#endif -#define UNUSED(x) (void)(x) /* silence unused parameter warning */ -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define STATIC_ASSERTS(cond, s) typedef char assert_##s[(cond) ? 1 : -1] -#define STATIC_ASSERTI(cond, i) STATIC_ASSERTS(cond, i) -#define STATIC_ASSERT(cond) STATIC_ASSERTI(cond, __LINE__) +# define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ +# define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */ +# define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */ +# define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */ +# ifdef SUBSET_NB +# define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ +# endif +# ifdef SUBSET_WB +# define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ +# endif +# ifdef SUBSET_SSWB +# define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ +# endif -/* For dynamic memory calculations */ -#define CODEC_FS(fs) ((fs) == 44100 ? 48000 : (fs)) -#define DYN_MAX_LEN(fs) MAX(CODEC_FS(fs) / 100, 160) -#define DYN_MAX_LEN_EXT(fs) MAX(CODEC_FS(fs) / 100, 160) /* extension to length 160 for NB(fs=8000) */ -#define DYN_MAX_MDCT_LEN(fs) (DYN_MAX_LEN(fs) - (180 * DYN_MAX_LEN(fs) / 480)) +#ifdef CR8_G_ADD_75MS +# define MIN_BR_075DMS_48KHZ_HR ((int)124800/ 800/2)* 800 +# define MIN_BR_075DMS_96KHZ_HR ((int)149600/ 800/2)* 800 +# define MIN_BR_075DMS 21334 /* ceil( 20 * 800 * 100/ 75) */ +# define MAX_BR_075DMS 426667 /* ceil(400 * 800 * 100/ 75) */ +# define MAX_BR_075DMS_NB 152534 /* ceil(143 * 800 * 100/ 75) */ +# define MAX_BR_075DMS_WB 295467 /* ceil(277 * 800 * 100/ 75) */ +# define MAX_BR_075DMS_SSWB 419200 /* ceil(393 * 800 * 100/ 75) */ + +# define NOISEFILLWIDTH_7_5MS 2 +# define NOISEFILLSTART_7_5MS 18 +#endif -/* OPTIONS */ +#define PACK_RESBITS + +/* FRAME/BUFFER */ +#ifdef SUBSET_UB +# define MAX_LEN 960 /* = 10ms at 96kHz */ +#elif defined SUBSET_FB +# define MAX_LEN 480 /* = 10ms at 48kHz */ +#elif defined(SUBSET_SWB) +# define MAX_LEN 320 /* = 10ms at 32kHz */ +#elif defined(SUBSET_SSWB) +# define MAX_LEN 240 /* = 10ms at 24kHz */ +#elif defined(SUBSET_WB) +# define MAX_LEN 160 /* = 10ms at 16kHz */ +#elif defined(SUBSET_NB) +# define MAX_LEN 80 /* = 10ms at 8kHz */ +#endif + +#ifdef ENABLE_HR_MODE +# define ENABLE_FFT_RESCALE +# define ENABLE_FFT_30X16 +# define ENABLE_DCTIV_RESCALE -#define MAX_LEN_NR 480 -#define MAX_SR 96000 -#define EXT_RES_ITER_MAX 20 -#define MAX_BW_BANDS_NUMBER 6 -#define MAX_LEN MAX_SR/100 /* = 10ms at 96kHz */ -#define MAX_RESBITS 5000 -#define MAX_RESBITS_LEN ((MAX_RESBITS + 7)/8) +# define EXT_RES_ITER_MAX 20 +# define MAX_RESBITS 5000 +# define HR_MODE_SCRATCH_SIZE 60 +#else /* ENABLE_HR_MODE */ +# define MAX_RESBITS MAX_LEN +#endif /* ENABLE_HR_MODE */ + +/* BW Cutoff-Detection */ +#define MAX_BW_BANDS_NUMBER 5 + +#ifdef ENABLE_HR_MODE +# define RESBITS_PACK_SHIFT 3 +# define RESBITS_PACK_N (1<<(RESBITS_PACK_SHIFT)) +# define RESBITS_PACK_MASK (RESBITS_PACK_N - 1) +# define MAX_RESBITS_LEN ((MAX_RESBITS + RESBITS_PACK_MASK) >> RESBITS_PACK_SHIFT) +# define MAX_RESBITS_LEN_32BIT_ALIGN (((MAX_RESBITS_LEN + 3)/4)*4) +#else /* ENABLE_HR_MODE */ +# define MAX_RESBITS_LEN (MAX_RESBITS) +# define MAX_RESBITS_LEN_32BIT_ALIGN (((MAX_RESBITS_LEN + 3)/4)*4) +#endif /* ENABLE_HR_MODE */ #define MAX_CHANNELS 2 #define MIN_NBYTES 20 /* 100dms: 16 kbps at !=44.1kHz, 14.7kbps at 44.1kHz @@ -290,48 +302,101 @@ typedef int32_t LC3_INT32; 25dms: 64 kbps at !=44.1kHz, 58.8kbps at 44.1kHz */ #define MAX_NBYTES_025 100 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ #define MAX_NBYTES_050 200 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ +#define MAX_NBYTES_075 400 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ #define MAX_NBYTES_100 400 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ - -#ifdef ENABLE_HR_MODE_FL -#define MIN_BR_25MS_48KHZ_HR ((int)172800/3200/2)*3200 -#define MIN_BR_25MS_96KHZ_HR ((int)198400/3200/2)*3200 -#define MIN_BR_50MS_48KHZ_HR ((int)148800/1600/2)*1600 -#define MIN_BR_50MS_96KHZ_HR ((int)174400/1600/2)*1600 -#define MIN_BR_100MS_48KHZ_HR ((int)124800/800/2)*800 -#define MIN_BR_100MS_96KHZ_HR ((int)149600/800/2)*800 -#endif /* ENABLE_HR_MODE */ -#define MAX_NBYTES2 625 -#define BYTESBUFSIZE (MAX_NBYTES2 * MAX_CHANNELS) +#ifdef ENABLE_HR_MODE +# define MIN_BR_25MS_48KHZ_HR ((int)172800/3200/2)*3200 +# define MIN_BR_25MS_96KHZ_HR ((int)198400/3200/2)*3200 +# define MIN_BR_50MS_48KHZ_HR ((int)148800/1600/2)*1600 +# define MIN_BR_50MS_96KHZ_HR ((int)174400/1600/2)*1600 +# define MIN_BR_100MS_48KHZ_HR ((int)124800/800/2)*800 +# define MIN_BR_100MS_96KHZ_HR ((int)149600/800/2)*800 +# define MAX_NBYTES_RED_HR 625 /* From table 5.2 */ +# define BYTESBUFSIZE (MAX_NBYTES_RED_HR * LC3PLUS_MAX_CHANNELS) +#else +# define BYTESBUFSIZE (MAX_NBYTES_100 * LC3PLUS_MAX_CHANNELS) +#endif #define MAX_BW_BIN 400 +#define FEC_SLOT_BYTES_MIN 40 +# define FEC_SLOT_BYTES_MAX 400 #if MAX_BW_BIN > MAX_LEN -#define MAX_BW MAX_LEN +# define MAX_BW MAX_LEN #else -#define MAX_BW MAX_BW_BIN +# define MAX_BW MAX_BW_BIN #endif -#ifdef ENABLE_HR_MODE_FL -#define MAX_BW_HR 960 -#endif +#define NUM_OFFSETS 7 +#define NUM_SAMP_FREQ 6 /* SCF */ -#define M 16 +#define M 16 /* LPC_ORDER */ #define MAX_BANDS_NUMBER 64 #define MAX_BANDS_NUMBER_PLC 80 #define PVQ_MAX_VEC_SIZE M +#define KMAX_FX 10 /* N=10 */ +#define K_OUTL_FAR 6 +#define MPVQ_SZ_OUTL_FAR (1549824U >> 1) +#define TOTBITS_SHAPE OUTL_FAR(1.0 + 19.5637) +#define SQRT_EN_MAX_FX 64 /* table size, for fast inv_sqrt */ +#define N_SETA 10 +#define N_SETB (PVQ_MAX_VEC_SIZE - N_SETA) + +#define SNS_DAMPING 27853 /* 0.85 in Q15 */ +#ifdef ENABLE_HR_MODE +# define SNS_DAMPING_HRMODE 19661 /* 0.6 in Q15 */ +# define SNS_DAMPING_HRMODE_UB_10MS 6881 /* 0.21 in Q15 */ +# define SNS_DAMPING_HRMODE_UB_7_5MS 5898 /* 0.18 in Q15 */ +# define SNS_DAMPING_HRMODE_UB_5MS 4915 /* 0.15 in Q15 */ +# define SNS_DAMPING_HRMODE_UB_2_5MS 4915 /* 0.15 in Q15 */ +#endif /* PVQ VQ setup */ -#define SCF_MAX_PARAM \ - 7 /* (L+H) + submode_MSB +gain+(Ia_leads+Ia_mpvq)+(Ib_joint_mpvq), \ - submode-LSB */ +#define VQMODES26 \ + ((0 << 4) + (1 << 3) + (1 << 2) + (1 << 1) + \ + (1 << 0)) /* select all shapes, including extended lf, and new far \ + shape for MODE26, add extreme far mode not enabled */ +#define SCF_STAGE1_MAX_BITS (5 + 5) /* typically only (5+5) used */ +#define SCF_STAGE1_NBCDKENTRIES 32 +#define SCF_STAGE2_MAX_GAIN_BITS 2 +#define SCF_STAGE2_NB_MODE_BITS 1 +#define SCF_STAGE2_MAX_NB_SHAPES 3 +#define SCF_MAX_PARAM 7 /* (L+H) + submode_MSB +gain+(Ia_leads+Ia_mpvq)+(Ib_joint_mpvq), submode-LSB */ +#define SCF_MAX_PARAM_ST2 (SCF_MAX_PARAM - 2) +#define N_SCF_SHAPES_ST2 4 +#define N_SCF_SHAPE_SETUPS 1 + +/* ARITHMETIC ENCODER */ +#define NBITS_CONTEXT 8 +#define NBITS_RATEQ 2 +#define A_THRES_SHIFT 2 +#define A_THRES (1 << A_THRES_SHIFT) +#define VAL_ESC 16 +#define SYM_BITS_Q 11 /* RESIDUAL CODING */ -#define NPRM_RESQ 5 * MAX_LEN +#define NPRM_RESQ MAX_LEN + +/* NOISE FILLING */ +#define NOISEFILLWIDTH 3 +#define NOISEFILLSTART 24 +#define NOISEFILLWIDTH_5MS 1 +#define NOISEFILLSTART_5MS 12 +#define NOISEFILLWIDTH_2_5MS 1 +#define NOISEFILLSTART_2_5MS 6 /* MDCT */ +#ifdef ENABLE_HR_MODE +# define TWIDDLE ((Word32)0x5a82799a) +#else +# define TWIDDLE WORD322WORD16(0x5a82799a) +#endif #define MDCT_MEM_LEN_MAX (MAX_LEN - ((180 * MAX_LEN) / 480)) /* TNS */ #define TNS_NUMFILTERS_MAX 2 +#define TNS_COEF_RES 17 +#define INDEX_SHIFT 8 +#define NSUBDIV 3 #define MAXLAG 8 /* OLPA/LTPF */ @@ -345,9 +410,322 @@ typedef int32_t LC3_INT32; #define RES2_PITCH_12K8 157 #define RES4_PITCH_12K8 127 #define LTPF_MEMIN_LEN (MAX_PITCH_12K8 + 4) +#define M_LTPF 24 +#define LTPF_MEM_X_LEN (MAX_LEN + MAX_LEN / 40 - 2) +#define LTPF_MEM_Y_LEN (MAX_LEN + CEILING(MAX_PITCH_12K8 * MAX_LEN, 128) + (MAX_LEN / 80)) + +/* PLC */ +#ifdef CR9_I_INC_TDC_FADEOUT_LEN +# define PLC_FADEOUT_TYPE_1_IN_MS 200 +#endif +#define PLC_FADEOUT_IN_MS 60 /* fade-out to zero in ms for TD-PLC and NS, minimum value is 20 */ + +# ifdef CR8_A_PLC_FADEOUT_TUNING + /* table settings */ +# define PLC2_FADEOUT_IN_MS_MIN 30 /* table min */ +# define PLC2_FADEOUT_IN_MS_MAX 140 /* table max */ +# define PLC2_FADEOUT_RES 10 /* 10 ms steps used in fade tables */ + +/* current settings */ +# define PLC2_FADEOUT_LONG_IN_MS 120 +# define PLC2_FADEOUT_IN_MS 30 /* 0 uses original constants for PLC2 + -1 uses TDC::PLC_FADEOUT_IN_MS as basis for a PLC2 macro-re-calculation + 30..140 will use a separate settings for PLC2 fadeout + 30: P800 short fade optimization + 120: Mushra optimized fade */ +#else +# define PLC2_FADEOUT_IN_MS 30 /* 0 uses original fixed values for PLC2 + -1 uses PLC_FADEOUT_IN_MS as basis for a PLC2 macro-re-calculation + 30..100 uses separate setting for PLC2 */ +#endif + + + +#define PLC4_TRANSIT_END_IN_MS PLC_FADEOUT_IN_MS /* end of transition time for noise substitution */ +#define PLC4_TRANSIT_START_IN_MS 20 /* begin of transition time for noise substitution for voiced signals */ +#define PLC34_ATTEN_FAC_100_FX 0x4000 /* attenuation factor for NS and TDC @ 10 ms (0.5000)*/ +#define PLC34_ATTEN_FAC_050_FX 0x5A83 /* attenuation factor for NS and TDC @ 5.0 ms (0.7071)*/ +#define PLC34_ATTEN_FAC_025_FX 0x6BA3 /* attenuation factor for NS and TDC @ 2.5 ms (0.8409)*/ +#ifdef CR8_G_ADD_75MS +#define PLC34_ATTEN_FAC_075_FX 0x4C1C /* attenuation factor for NS and TDC @ 7.5 ms (0.5946) */ +#endif +#define PLC3_HPBLENDTHROTTLE 30 /* higher numbers increase throttled blending from hp filtered to unfiltered uv excitation (0 is no throttle) */ + +#define MAX_PITCH_8K (CEILING((MAX_PITCH_12K8 * 8000), (12800))) /*NB was a risky MACRO at 0.5 border !!, */ +#define MAX_PITCH_16K ((MAX_PITCH_12K8 * 16000) / (12800)) /* exact integer */ +#define MAX_PITCH_24K \ + (CEILING((MAX_PITCH_12K8 * 24000), (12800))) /* was a risky MACRO truncation at 0.5 border !! , */ +#define MAX_PITCH_32K ((MAX_PITCH_12K8 * 32000) / (12800)) /* exact integer */ +#define MAX_PITCH_48K ((MAX_PITCH_12K8 * 48000) / (12800)) /* exact integer */ + +#ifdef ENABLE_HR_MODE +# define MAX_PITCH_96K ((MAX_PITCH_12K8 * 96000) / (12800)) /* exact integer */ +#endif + +#ifdef ENABLE_HR_MODE +# define MAX_PITCH MAX_PITCH_96K +#elif defined(SUBSET_FB) +# define MAX_PITCH MAX_PITCH_48K +#elif defined(SUBSET_SWB) +# define MAX_PITCH MAX_PITCH_32K +#elif defined(SUBSET_SSWB) +# define MAX_PITCH MAX_PITCH_24K +#elif defined(SUBSET_WB) +# define MAX_PITCH MAX_PITCH_16K +#elif defined(SUBSET_NB) +# define MAX_PITCH MAX_PITCH_8K +#endif + + +/* macri MAX_LEN_PCM_PLC is used for WC memory size checking + DYN_MAX_LEN_PCM_PLC(fs) is used by static memory buffers + */ +#define MAX_LEN_PCM_PLC (MAX_PITCH + MAX_LEN) + +#define TDC_L_FIR_HP 11 +#define TDC_L_FIR_LP 11 + +#define BASE_LPROT 512 /* BASE Lprot set to 512 for 32 kHz sampling */ + +#define LPROT48K (BASE_LPROT * 48 / 32) /* Fs based Lprot */ +#define LPROT40K (BASE_LPROT * 40 / 32) /* For Fs == 48000 only use 0 - 20000 Hz in 8 bands */ +#define LPROT32K BASE_LPROT +#define LPROT24K (BASE_LPROT * 24 / 32) +#define LPROT16K (BASE_LPROT * 16 / 32) +#define LPROT8K (BASE_LPROT * 8 / 32) + +/* #define PHECU_XFP_LA 1 */ /* Original soluiton xfp generated with 1ms look ahead into MDCT memory + ctrl.PhECU.LA = 0.001 * ctrl.fs; */ +/* #define PHECU_XFP_LA 4 */ /* Option with some lookahead 1/4 ms look ahead into MDCT memory + ctrl.PhECU.LA = 0.001 * ctrl.fs / 4; */ +#define PHECU_XFP_LA \ + 0 /* Option without lookahead 0 ms look ahead into MDCT memory \ + ctrl.PhECU.LA = 0; */ + +#if (PHECU_XFP_LA == 0) + +# define PHECU_LA_48K 0 /* 0 ms */ +# define PHECU_LA_32K 0 /* 0 ms */ +# define PHECU_LA_24K 0 /* 0 ms */ +# define PHECU_LA_16K 0 /* 0 ms */ +# define PHECU_LA_8K 0 /* 0 ms */ + +# define MAX_PHECU_LA (0) -/* Advanced PLC */ +#else +# if (PHECU_XFP_LA == 4) + +# define PHECU_LA_48K (48 / 4) /* 0.25 ms */ +# define PHECU_LA_32K (32 / 4) /* 0.25 ms */ +# define PHECU_LA_24K (24 / 4) /* 0.25 ms */ +# define PHECU_LA_16K (16 / 4) /* 0.25 ms */ +# define PHECU_LA_8K (8 / 4) /* 0.25 ms */ + +# define MAX_PHECU_LA (MAX_LEN / 10 / 4) + +# else + +# define PHECU_LA_48K 48 /* 1 ms */ +# define PHECU_LA_32K 32 /* 1 ms */ +# define PHECU_LA_24K 24 /* 1 ms */ +# define PHECU_LA_16K 16 /* 1 ms */ +# define PHECU_LA_8K 8 /* 1 ms */ + +# define MAX_PHECU_LA (MAX_LEN / 10) + +# endif +#endif + + +/* (PHECU_LA_48K == 0) */ + +#define COPY_LEN_8K 16 +#define COPY_LEN_16K 32 +#define COPY_LEN_24K 48 +#define COPY_LEN_32K 64 +#define COPY_LEN_48K 96 + +#define OLA_LEN_8K 14 +#define OLA_LEN_16K 28 +#define OLA_LEN_24K 42 +#define OLA_LEN_32K 56 +#define OLA_LEN_48K 84 + +#define LPROT48K_RED LPROT40K /* limit peak searched part of spectrum for FB */ +#define LPROT32K_RED LPROT32K /* limit peak searched part of spectrum for SWB */ +#define LPROT24K_RED LPROT24K /* limit peak searched part of spectrum for HQ */ +#define LPROT16K_RED LPROT16K /* limit peak searched part of spectrum for SQ */ +#define LPROT8K_RED LPROT8K /* limit peak searched part of spectrum for NB */ + +#define INV_LPROT48K_Q22 5461 /* round(2^22/LPROT48K) , 1/6 */ +#define INV_LPROT32K_Q22 8192 /* round(2^22/LPROT32K) , 1/4 */ +#define INV_LPROT24K_Q22 10923 /* round(2^22/LPROT24K) , 1/3 */ +#define INV_LPROT16K_Q22 16384 /* round(2^22/LPROT16K) , 1/2 */ +#define INV_LPROT8K_Q22 32767 /* round(2^22/LPROT8K) , 1/1 */ + +#define LGW48K 8 /* 8 bands defined , but may the same frequency groups as for SWB(32k) */ +#define LGW32K 7 +#define LGW24K 6 +#define LGW16K 5 +#define LGW8K 4 + +#define MAX_LGW 9 /* LGW48K + 1 !! */ + +#define UNINIT_OR_UNSAFE_OOLD_SENTINEL -32768 +#define LTOT_INIT_FLAG -32768 +#define LTOT_MIN_MAN 1 /* lowest possible energy value */ +#define LTOT_MIN_EXP -61 /* L_tot= LTOT_MIN_MAN*2^(LTOT_MIN_EXP-31) */ +#define GRP_SHAPE_INIT 0 /* Q15 */ + +#define TRANA_TIME 4 /* Transient analysis length in ms */ +#define LTRANA48K (48000 * TRANA_TIME / 1000) +#define LTRANA32K (32000 * TRANA_TIME / 1000) +#define LTRANA24K (24000 * TRANA_TIME / 1000) +#define LTRANA16K (16000 * TRANA_TIME / 1000) +#define LTRANA8K (8000 * TRANA_TIME / 1000) + +#define MAX_PLOCS ((MAX_LPROT / 4) + 1) /* maximum number of spectral peaks to be searched */ +#define QUOT_LPR_LTR 4 + +#define BETA_MUTE_FAC_INI 16384 /* Q15, initial noise attenuation factor */ + +#define OFF_FRAMES_LIMIT 30 /* Hard limit to a maximum of 300ms of burst decay frames */ + +#define Lprot_hamm_len2_48k (3 * 48) +#define Lprot_hamm_len2_32k (3 * 32) +#define Lprot_hamm_len2_24k (3 * 24) +#define Lprot_hamm_len2_16k (3 * 16) +#define Lprot_hamm_len2_8k (3 * 8) + +#define FRAME_TIME 10 /* Frame length in ms */ + +#define L_FRAME48K (48000 * FRAME_TIME / 1000) +#define L_FRAME32K (32000 * FRAME_TIME / 1000) +#define L_FRAME24K (24000 * FRAME_TIME / 1000) +#define L_FRAME16K (16000 * FRAME_TIME / 1000) +#define L_FRAME8K (8000 * FRAME_TIME / 1000) + +#ifdef DISABLE_PLC +# define MAX_LTRANA 0 +# define MAX_LPROT LPROT48K +# define MAX_L_FRAME L_FRAME48K +# define MAX_LPROT_RED LPROT48K_RED +#else + +# ifdef SUBSET_UB +# define MAX_LPROT LPROT48K /* Max length of protype frame for buffer allocation */ +# define MAX_LPROT_RED LPROT48K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA48K +# define MAX_L_FRAME L_FRAME48K +# elif defined(SUBSET_FB) +# define MAX_LPROT LPROT48K /* Max length of protype frame for buffer allocation */ +# define MAX_LPROT_RED LPROT48K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA48K +# define MAX_L_FRAME L_FRAME48K +# elif defined(SUBSET_SWB) +# define MAX_LPROT LPROT32K +# define MAX_LPROT_RED LPROT32K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA32K +# define MAX_L_FRAME L_FRAME32K +# elif defined(SUBSET_SSWB) +# define MAX_LPROT LPROT24K +# define MAX_LPROT_RED LPROT24K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA24K +# define MAX_L_FRAME L_FRAME24K +# elif defined(SUBSET_WB) +# define MAX_LPROT LPROT16K +# define MAX_LPROT_RED LPROT16K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA16K +# define MAX_L_FRAME L_FRAME16K +# elif defined(SUBSET_NB) +# define MAX_LPROT LPROT8K +# define MAX_LPROT_RED LPROT8K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA8K +# define MAX_L_FRAME L_FRAME8K +# endif + +#endif /* #ifdef DISABLE_PLC */ + +#define INV_L_FRAME48K_Q15 32768 / L_FRAME48K +#define INV_L_FRAME32K_Q15 32768 / L_FRAME32K +#define INV_L_FRAME24K_Q15 32768 / L_FRAME24K +#define INV_L_FRAME16K_Q15 32768 / L_FRAME16K +#define INV_L_FRAME8K_Q15 32768 / L_FRAME8K + +#define MDCT_MEM_LEN_48 (L_FRAME48K - ((180 * L_FRAME48K) / 480)) + +#define R1_48 690 +#define R2_48 420 +#define R1_16 230 +#define R2_16 140 +#define R1_25 368 +#define R2_25 224 + +#define MAX_LEN_PCM_PLC_TOT (MAX_LEN_PCM_PLC) /* TDC_pcm_buff */ +#define MAX_WIN_PRE_TDA (0) /* not in RAM any longer , now stored in ROM only as PhECU_wins[fs_idx][1] */ + +#define MAX_PLCMETH 1 + +/* Scratch buffer defines */ +#define scratchBuffer_ACTIVE +#ifdef ENABLE_HR_MODE +# define SCRATCH_BUF_LEN_ENC (4 * MAX_LEN + 32 + 32 + 4 * MAX_LEN + 3 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN) +# define SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH (4 * MAX_LEN + 8 * 60 + MAX_LEN) +#else +# define SCRATCH_BUF_LEN_ENC (4 * MAX_LEN + 32 + 32 + 2 * MAX_LEN + 3 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN) +# define SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH (4 * MAX_LEN) +#endif + +#define SCRATCH_BUF_LEN_ENC_TOT (SCRATCH_BUF_LEN_ENC + SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH) + +#ifdef ENABLE_HR_MODE +# define SCRATCH_BUF_LEN_DEC (4 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN + 32 + 32 + 4 * MAX_LEN + 32 + 128 + 128) +#else +# define SCRATCH_BUF_LEN_DEC (4 * MAX_LEN + 2 * MAX_LEN + 32 + 32 + 2 * MAX_LEN + 32 + 128 + 128) +#endif +#define SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH (2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME) +#ifdef ENABLE_HR_MODE +# define SCRATCH_BUF_LEN_DEC_TOT (SCRATCH_BUF_LEN_DEC + (4 * HR_MODE_SCRATCH_SIZE) + SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH) +#else +# define SCRATCH_BUF_LEN_DEC_TOT (SCRATCH_BUF_LEN_DEC + SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH) +#endif + +#define ADVACED_PLC_SIZE \ + (sizeof(AplcSetup) + (4 + 2) * MAX_PLOCS + 2 * MAX_LEN_PCM_PLC_TOT + 0 * MAX_LPROT + 2 * MDCT_MEM_LEN_MAX + \ + 2 * MAX_WIN_PRE_TDA) +/* ERI : Correct this sum after ROM/RAM , joint RAM optimizations */ + + +#define ENC_MAX_SIZE (sizeof(LC3PLUS_Enc) + MAX_CHANNELS * (sizeof(EncSetup) + 6 * MDCT_MEM_LEN_MAX)) +#define DEC_MAX_SIZE \ + (sizeof(LC3PLUS_Dec) + MAX_CHANNELS * (sizeof(DecSetup) + ADVACED_PLC_SIZE + 2 * LTPF_MEM_X_LEN + 2 * LTPF_MEM_Y_LEN + \ + 2 * MDCT_MEM_LEN_MAX + 2 * MAX_BW)) + +#if (defined(_M_ARM) || defined(__CC_ARM) || defined(__TMS470__) || defined(__arm__) || defined(__aarch64__)) && \ + (defined(__TARGET_FEATURE_NEON) || defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__ARM_AARCH64_NEON__)) +# define ALIGNMENT_DEFAULT 16 +#elif defined(__bfin__) +# define ALIGNMENT_DEFAULT 4 +#else +# define ALIGNMENT_DEFAULT 8 +#endif + +/* RAM_ALIGN keyword causes memory alignment of global variables. */ +#if defined(__GNUC__) +# define RAM_ALIGN __attribute__((aligned(ALIGNMENT_DEFAULT))) +#elif defined(__CC_ARM) +# define RAM_ALIGN __align(ALIGNMENT_DEFAULT) +#elif defined(__ANALOG_EXTENSIONS__) +# define RAM_ALIGN +# pragma pack(ALIGNMENT_DEFAULT) +#elif defined(_MSC_VER) +# define RAM_ALIGN __declspec(align(ALIGNMENT_DEFAULT)) +#else +# define RAM_ALIGN +#endif +#define scratchAlign(ptr, offset) (void *)(((uintptr_t)(ptr) + (offset) + 0x3) & ~0x3) +#define ALIGN_BUFFER_STRUCT /* some configurations leave empty translation units. */ diff --git a/lib_lc3plus/detect_cutoff_warped.c b/lib_lc3plus/detect_cutoff_warped.c deleted file mode 100644 index 21b73e806..000000000 --- a/lib_lc3plus/detect_cutoff_warped.c +++ /dev/null @@ -1,92 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx) -{ - const LC3_INT *warp_idx_start, *warp_idx_stop; - LC3_INT counter, brickwall = 0, i, stop, dist; - LC3_FLOAT d2_mean, d2_sum, e_diff, thr; - const LC3_INT *bw_dist; - - warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; - warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; - - switch (frame_dms) - { - case 25: - warp_idx_start = BW_warp_idx_start_all_2_5ms[fs_idx - 1]; - warp_idx_stop = BW_warp_idx_stop_all_2_5ms[fs_idx - 1]; - bw_dist = brickwall_dist; - break; - case 50: - warp_idx_start = BW_warp_idx_start_all_5ms[fs_idx - 1]; - warp_idx_stop = BW_warp_idx_stop_all_5ms[fs_idx - 1]; - bw_dist = brickwall_dist; - break; -#ifdef CR8_G_ADD_75MS - case 75: - warp_idx_start = BW_warp_idx_start_all_7_5ms[fs_idx - 1]; - warp_idx_stop = BW_warp_idx_stop_all_7_5ms[fs_idx - 1]; - bw_dist = brickwall_dist_7_5ms; - break; -#endif - case 100: - warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; - warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; - bw_dist = brickwall_dist; - break; - } - - counter = fs_idx; - - d2_sum = sum_vec(&d2[warp_idx_start[counter - 1]], warp_idx_stop[counter - 1] - warp_idx_start[counter - 1] + 1); - - d2_mean = d2_sum / (warp_idx_stop[counter - 1] - warp_idx_start[counter - 1] + 1); - - while (d2_mean < threshold_quiet[counter - 1]) { - d2_sum = 0; - counter--; - if (counter == 0) { - break; - } - - /* calculate mean energy per band */ - d2_sum = - sum_vec(&d2[warp_idx_start[counter - 1]], warp_idx_stop[counter - 1] - warp_idx_start[counter - 1] + 1); - - d2_mean = d2_sum / (warp_idx_stop[counter - 1] - warp_idx_start[counter - 1] + 1); - } - - *bw_idx = counter; - - /* check if energy difference between bands is present */ - if (*bw_idx < fs_idx) { - thr = (LC3_FLOAT)threshold_brickwall[counter]; - stop = warp_idx_start[counter]; - dist = bw_dist[counter]; - - for (i = stop; i >= stop - dist; i--) { - e_diff = 10.0 * LC3_LOGTEN(d2[i - dist + 1] + FLT_EPSILON) - 10.0 * LC3_LOGTEN(d2[i + 1] + FLT_EPSILON); - - if (e_diff > thr) { - brickwall = 1; - break; - } - } - - if (brickwall == 0) { - *bw_idx = fs_idx; - } - } -} diff --git a/lib_lc3plus/detect_cutoff_warped_fx.c b/lib_lc3plus/detect_cutoff_warped_fx.c new file mode 100644 index 000000000..b6ef25472 --- /dev/null +++ b/lib_lc3plus/detect_cutoff_warped_fx.c @@ -0,0 +1,124 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" +#include "rom_basop_util.h" + +void processDetectCutoffWarped_fx(Word16 *bw_idx, Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 frame_dms) +{ + + Dyn_Mem_Deluxe_In( + Counter iBand; + Word32 d2_fx_sum; + Word32 d2_fx_mean; + Word32 delta_energy; + Word16 d2_fx_sum_exp; + Word16 d2_fx_mean_exp; + Word16 nrg_below_thresh; + Word16 counter; + Word16 brickwall; + Word16 stop; + Word16 brickwall_dist; + const Word16 *warp_idx_start, *warp_idx_stop, *bw_brickwall_dist; + ); + + SWITCH (frame_dms) + { + case 25: + warp_idx_start = BW_warp_idx_start_all_2_5ms[fs_idx - 1]; move16(); + warp_idx_stop = BW_warp_idx_stop_all_2_5ms[fs_idx - 1]; move16(); + bw_brickwall_dist = BW_brickwall_dist_2_5ms; + BREAK; + case 50: + warp_idx_start = BW_warp_idx_start_all_5ms[fs_idx - 1]; move16(); + warp_idx_stop = BW_warp_idx_stop_all_5ms[fs_idx - 1]; move16(); + bw_brickwall_dist = BW_brickwall_dist_5ms; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + warp_idx_start = BW_warp_idx_start_all_7_5ms[fs_idx - 1]; move16(); + warp_idx_stop = BW_warp_idx_stop_all_7_5ms[fs_idx - 1]; move16(); + bw_brickwall_dist = BW_brickwall_dist_7_5ms; + BREAK; +#endif + default: /* 100 */ + warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; move16(); + warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; move16(); + bw_brickwall_dist = BW_brickwall_dist; + BREAK; + } + + counter = fs_idx; + DO + { + + /* counter is 0...num_idxs-1 */ + counter = sub(counter, 1); + + /* always code the lowest band (NB), skip check against threshold if counter == -1 */ + IF (counter < 0) + { + BREAK; + } + + d2_fx_mean = 0; move32(); + d2_fx_mean_exp = 0; move16(); + + iBand = warp_idx_start[counter]; move16(); + d2_fx_sum = d2_fx[iBand]; move32(); + d2_fx_sum_exp = d2_fx_exp; move16(); + + iBand++; + FOR (; iBand <= warp_idx_stop[counter]; iBand++) + { + d2_fx_sum = BASOP_Util_Add_Mant32Exp_lc3plus(d2_fx[iBand], d2_fx_exp, d2_fx_sum, d2_fx_sum_exp, &d2_fx_sum_exp); + } + /* Energy-sum */ + d2_fx_mean = Mpy_32_16_lc3plus(d2_fx_sum, InvIntTable[add(sub(warp_idx_stop[counter], warp_idx_start[counter]), 1)]); + d2_fx_mean_exp = d2_fx_sum_exp; move16(); + + /* check if above threshold */ + nrg_below_thresh = BASOP_Util_Cmp_Mant32Exp_lc3plus(BW_thresh_quiet[counter], BW_thresh_quiet_exp, d2_fx_mean, + d2_fx_mean_exp); /* true if firstNumber > secondNumber */ + } + WHILE (nrg_below_thresh > 0) + ; + + *bw_idx = add(1, counter); move16(); + + /* addtional check for brickwall characteristic */ + IF (sub(fs_idx, *bw_idx) > 0) + { + brickwall = 0; move16(); + stop = add(warp_idx_start[counter + 1], 1); + brickwall_dist = bw_brickwall_dist[counter + 1]; + + FOR (iBand = stop; iBand >= sub(stop, brickwall_dist); iBand--) + { + /* Band(x) > Band(x-3)*Thr */ + delta_energy = + L_sub(Mpy_32_16_lc3plus(d2_fx[iBand - brickwall_dist], BW_thresh_brickwall[counter + 1]), d2_fx[iBand]); + if (delta_energy > 0) + { + brickwall = 1; move16(); + } + IF (brickwall) + { + BREAK; + } + } + if (brickwall == 0) + { + *bw_idx = fs_idx; + } + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/dynmem.c b/lib_lc3plus/dynmem.c new file mode 100644 index 000000000..65e157d0a --- /dev/null +++ b/lib_lc3plus/dynmem.c @@ -0,0 +1,288 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/* + Tool for dynamic memory estimation + Anisse Taleb, November 2003 + +*/ + +/* turn off stdlib function warnings in visual studio */ +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include +#include +#include + +#include "dynmem.h" + +#define MAX_FUNC_NAME_LENGTH 128 + + + +struct C_Path{ + char func_name[MAX_FUNC_NAME_LENGTH]; + long mem_usage; + long mem_usage_acc; + struct C_Path *next; + struct C_Path *parent; +}; + + +typedef struct C_Path C_Path; + +static C_Path *Max_Mem_path; /* Snap shot of the maximum memory usage path */ +static C_Path *Head_path; +static C_Path *Curr_path; /* Current code path */ + + +static long Max_mem_usage; + +static C_Path *Static_mem_head; +static C_Path *Static_mem_curr; + +/* + * initialisation. Must be called at start, sets up all the + * structures and resets counters. + * + * Called externally. + */ + +static void path_free(C_Path * path) +{ + C_Path *path_end,*tmp; + path_end = path; + + if(path == NULL) return; + /* find last node */ + while(path_end->next != NULL) path_end = path_end->next; + + /* walk back */ + while(path_end != NULL) { + tmp = path_end; + path_end = path_end->parent; + free(tmp); + } + +} +static void path_save(void) +{ + C_Path * node; + C_Path * node_save; + C_Path * previous; + /* free the old path */ + path_free(Max_Mem_path); + Max_Mem_path = NULL; + /* */ + + Max_Mem_path = (C_Path *) malloc(sizeof(C_Path)); + + node = Head_path; + node_save = Max_Mem_path; + previous = NULL; + while(node != NULL){ + + strcpy(node_save->func_name,node->func_name); + node_save->mem_usage = node->mem_usage; + node_save->mem_usage_acc = node->mem_usage_acc; + + node_save->parent = previous; + node_save->next = NULL; + + if(node->next != NULL) { + node_save->next = (C_Path *) malloc(sizeof(C_Path)); + } + node = node->next; + previous = node_save; + node_save = node_save->next; + } while(node != NULL); + +} + +void P_Dyn_Mem_Init(void) +{ + + /* initialize the path */ + Head_path = (C_Path *) malloc(sizeof(C_Path)); + strcpy(Head_path->func_name,"---Top---"); + Head_path->mem_usage = 0; + Head_path->mem_usage_acc = 0; /*memory usage accumulator */ + Head_path->parent = NULL; + Head_path->next = NULL; + + Curr_path = Head_path; + /* Initilaize the memory consumptions */ + Max_mem_usage = 0; + Max_Mem_path = NULL; +} + +void P_Dyn_Mem_In(const char *func_name, + long mem_usage) +{ +#ifdef DEBUG_DYNMEM + printf( "Entering: %s\n", func_name ); +#endif + + /* Enter a new function, push on the stack */ + if(Curr_path->next != NULL) { + fprintf(stderr,"\n Something went wrong !!"); + exit(0); + + } + Curr_path->next = (C_Path*) malloc (sizeof(C_Path)); + + if(Curr_path->next == NULL) { + fprintf(stderr,"\n Can't allocate memory"); + exit(0); + } + + Curr_path->next->parent = Curr_path; + Curr_path = Curr_path->next; + Curr_path->next = NULL; + /* save function name */ + strcpy(Curr_path->func_name,func_name); + /* save memory usage */ + Curr_path->mem_usage = mem_usage; + /* update memory usage accumulator */ + Curr_path->mem_usage_acc = Curr_path->parent->mem_usage_acc + mem_usage; +} + +/* Add memory size to current function */ +void P_Dyn_Mem_Add(long mem_usage) +{ +#ifdef DEBUG_DYNMEM + printf( "Staying in: %s\n", Curr_path->func_name); +#endif + + /* Staying in the current function, nothing to push */ + + /* save memory usage */ + Curr_path->mem_usage = Curr_path->mem_usage + mem_usage; + /* update memory usage accumulator */ + Curr_path->mem_usage_acc = Curr_path->mem_usage_acc + mem_usage; +} + + +/* before any return */ + +void P_Dyn_Mem_Out(void) +{ + C_Path *tmp; + if(Curr_path->mem_usage_acc > Max_mem_usage) { + /* set new memory usage record */ + Max_mem_usage = Curr_path->mem_usage_acc; + /* save snap shot */ + path_save(); + } + +#ifdef DEBUG_DYNMEM + printf( "Exiting: %s\n", Curr_path->func_name ); +#endif + + /* delete last node */ + tmp = Curr_path; + + Curr_path = Curr_path->parent; + Curr_path->next = NULL; + free(tmp); +} + + +/* Write data and exit */ + +void P_Dyn_Mem_Exit(void) +{ + /*FILE *f_mem_statistics;*/ + C_Path *node; + /*f_mem_statistics = fopen("mem_stat.txt","wt"); + fprintf(f_mem_statistics,"\n Maximum dynamic memory usage = %ld b, %ld kW \n Critical Memory Usage Path", Max_mem_usage, Max_mem_usage/(1000*2));*/ + /* fprintf(stderr,"\n Maximum dynamic memory usage = %ld kWords (%ld bytes)\n Critical Memory Usage Path", Max_mem_usage/(1000*2),Max_mem_usage); */ + fprintf(stderr,"\n Maximum dynamic memory usage = %.2f kWords (%ld bytes)\n Critical Memory Usage Path", (ceil((float)Max_mem_usage/20.f)/100.f), Max_mem_usage); + + node = Max_Mem_path; + while (node != NULL) { + /*fprintf(f_mem_statistics,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage);*/ + fprintf(stderr,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage); + node=node->next; + } + + /*fclose(f_mem_statistics);*/ + fprintf(stderr,"\n"); + +#ifdef CTEST_MEASUREMENTS + printf("%.3f\n", "dynMem [kWords]", "numeric/float", Max_mem_usage/(1000.0*2)); +#endif + + path_free(Max_Mem_path); + path_free(Head_path); +} + +void P_Dyn_Mem_Exit_noprint(void) +{ + path_free(Max_Mem_path); + path_free(Head_path); +} +void P_Sta_Mem_Init(void) +{ + /* initialize the head object */ + Static_mem_head = (C_Path *) malloc(sizeof(C_Path)); + strcpy(Static_mem_head->func_name,"---Top---"); + Static_mem_head->mem_usage = 0; + Static_mem_head->mem_usage_acc = 0; + Static_mem_head->parent = NULL; + Static_mem_head->next = NULL; + Static_mem_curr = Static_mem_head; +} + +void P_Sta_Mem_Add(const char *func_name, + long mem_usage) +{ + /* Enter a new function, push on the stack */ + Static_mem_curr->next = (C_Path*) malloc (sizeof(C_Path)); + Static_mem_curr->next->parent = Static_mem_curr; + Static_mem_curr = Static_mem_curr->next; + Static_mem_curr->next = NULL; + /* save function name */ + strcpy(Static_mem_curr->func_name,func_name); + /* save memory usage */ + Static_mem_curr->mem_usage = mem_usage; + /* update memory usage accumulator */ + Static_mem_curr->mem_usage_acc = Static_mem_curr->parent->mem_usage_acc + mem_usage; +} + +void P_Sta_Mem_Exit(void) +{ + C_Path *node; + /* fprintf(stderr,"\n Static memory usage = %ld kWords (%ld bytes)\n Detailed Memory Usage", Static_mem_curr->mem_usage_acc/(1000*2),Static_mem_curr->mem_usage_acc); */ + fprintf(stderr,"\n Static memory usage = %.2f kWords (%ld bytes)\n Detailed Memory Usage", (ceil((float)Static_mem_curr->mem_usage_acc/20.f)/100.f),Static_mem_curr->mem_usage_acc); + + node = Static_mem_head->next; + while (node != NULL) { + fprintf(stderr,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage); + node=node->next; + } + + fprintf(stderr,"\n"); + +#ifdef CTEST_MEASUREMENTS + printf("%.3f\n", "statMem [kWords]", "numeric/float", Static_mem_curr->mem_usage_acc/(1000.0*2)); +#endif + + path_free(Static_mem_head); +} + +void P_Sta_Mem_Exit_noprint(void) +{ + path_free(Static_mem_head); +} diff --git a/lib_lc3plus/dynmem.h b/lib_lc3plus/dynmem.h new file mode 100644 index 000000000..e81169a33 --- /dev/null +++ b/lib_lc3plus/dynmem.h @@ -0,0 +1,80 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef DYNMEM_H +#define DYNMEM_H + +#ifdef _MSC_VER +/* This disables warnings about anonymous temporary struct declarations */ +#pragma warning(disable:4115) +#pragma warning(disable:4116) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void P_Dyn_Mem_Init(void); +void P_Dyn_Mem_In(const char *func_name, + long mem_usage); +void P_Dyn_Mem_Add(long mem_usage); +void P_Dyn_Mem_Out(void); +void P_Dyn_Mem_Exit(void); +void P_Dyn_Mem_Exit_noprint(void); + +void P_Sta_Mem_Init(void); +void P_Sta_Mem_Add(const char *func_name, + long mem_usage); +void P_Sta_Mem_Exit(void); +void P_Sta_Mem_Exit_noprint(void); + +#ifdef DONT_COUNT_MEM + +#define Dyn_Mem_Init() +#define Dyn_Mem_Exit() +#define Dyn_Mem_Exit_noprint() +#define Dyn_Mem_In(a,b) +#define Dyn_Mem_Add(b) +#define Dyn_Mem_Out() + +#define DYN_MEM_IN Dyn_Mem_In +#define DYN_MEM_ADD Dyn_Mem_Add +#define DYN_MEM_OUT Dyn_Mem_Out + +#define Sta_Mem_Init() +#define Sta_Mem_Exit() +#define Sta_Mem_Exit_noprint() +#define Sta_Mem_Add(a,b) + +#else /* DONT_COUNT_MEM */ + +#define Dyn_Mem_Init P_Dyn_Mem_Init +#define Dyn_Mem_Exit P_Dyn_Mem_Exit +#define Dyn_Mem_Exit_noprint P_Dyn_Mem_Exit_noprint +#define Dyn_Mem_In P_Dyn_Mem_In +#define Dyn_Mem_Add P_Dyn_Mem_Add +#define Dyn_Mem_Out P_Dyn_Mem_Out + +#define DYN_MEM_IN P_Dyn_Mem_In +#define DYN_MEM_ADD P_Dyn_Mem_Add +#define DYN_MEM_OUT P_Dyn_Mem_Out + +#define Sta_Mem_Init P_Sta_Mem_Init +#define Sta_Mem_Exit P_Sta_Mem_Exit +#define Sta_Mem_Exit_noprint P_Sta_Mem_Exit_noprint +#define Sta_Mem_Add P_Sta_Mem_Add + +#endif /* DONT_COUNT_MEM */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_lc3plus/enc_entropy.c b/lib_lc3plus/enc_entropy.c index dc285088a..35dd8d950 100644 --- a/lib_lc3plus/enc_entropy.c +++ b/lib_lc3plus/enc_entropy.c @@ -1,128 +1,173 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" #include "functions.h" -static const LC3_INT gainMSBbits[4] = {1, 1, 2, 2}; -static const LC3_INT gainLSBbits[4] = {0, 1, 0, 1}; +static Word32 ac_enc_mux_st2VQ_cws( /* o: max 25 bits total codeword */ + const Word32 L_szA, /* i: max 22 bits */ + const Word32 L_szB, /* i: max 4 bits */ + const Word32 L_cwA, const Word32 L_cwB); -void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits, - LC3_INT bw_cutoff_idx, LC3_INT lastnz, LC3_INT N, LC3_INT lsbMode, LC3_INT gg_idx, LC3_INT num_tns_filters, - LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx - , LC3_INT bfi_ext, LC3_INT fs_idx - ) +void processEncoderEntropy(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 targetBytes, + Word16 L_spec, Word16 BW_cutoff_bits, Word16 tns_numfilters, + Word16 lsbMode, Word16 lastnz, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, + Word16 BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, Word16 bfi_ext, Word16 fs_idx) { - LC3_UINT8* ptr; - LC3_INT i, submodeMSB, submodeLSB, tmp, gainMSB, gainLSB; + Word16 tmp; + Word32 L_tmp; + Word16 submode_LSB, submode_MSB, gain_MSBs; + Word32 L_gain_LSB; + Counter n; + UWord8 *ptr; - - LC3_INT16 lastnzTrigger[5] = {63, 127, 127, 255, 255}; + Word16 lastnzTrigger[5] = {63, 127, 127, 255, 255}; - *bp_side = numbytes - 1; - *mask_side = 1; +#ifdef DYNMEM_COUNT + struct _dynmem + { + Word16 tmp; + Word32 L_tmp; + Word16 submode_LSB, submode_MSB, gain_MSBs; + Word32 L_gain_LSB; + Counter n; + UWord8 *ptr; + Word16 lastnzTrigger[5]; + }; + Dyn_Mem_In("processEncoderEntropy", sizeof(struct _dynmem)); +#endif + + /* Init */ + *bp_side = shr_pos(sub(nbbits, 1), 3); + *mask_side = shl(1, sub(8, sub(nbbits, shl_pos(*bp_side, 3)))); ptr = bytes; - /* Bandwidth */ - if (bw_cutoff_bits > 0) { - write_uint_backward_fl(ptr, bp_side, mask_side, bw_cutoff_idx, bw_cutoff_bits); + basop_memset(bytes, 0, targetBytes * sizeof(*bytes)); + + /* Cutoff-detection */ + IF (BW_cutoff_bits > 0) + { + write_indice_backward(ptr, bp_side, mask_side, BW_cutoff_idx, BW_cutoff_bits); } - /* Last non zero touple */ - if (bfi_ext == 1) { - write_uint_backward_fl(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], ceil(LC3_LOGTWO(N >> 1))); + /* Encode last non-zero tuple */ + tmp = sub(14, norm_s(negate(L_spec))); + + IF (sub(bfi_ext, 1) == 0) + { + write_indice_backward(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], tmp); } - else + ELSE { - write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N >> 1))); + write_indice_backward(ptr, bp_side, mask_side, sub(shr_pos(lastnz, 1), 1), tmp); } - /* LSB mode bit */ - write_bit_backward_fl(ptr, bp_side, mask_side, lsbMode); + /* Mode bit */ + write_bit_backward(ptr, bp_side, mask_side, lsbMode); - /* Global gain */ - write_uint_backward_fl(ptr, bp_side, mask_side, gg_idx, 8); + /* Encode global-gain */ + write_indice_backward(ptr, bp_side, mask_side, gg_idx, 8); - /* TNS activation flag */ - for (i = 0; i < num_tns_filters; i++) { - write_bit_backward_fl(ptr, bp_side, mask_side, MIN(1, tns_order[i])); + /* TNS on/off flag */ + FOR (n = 0; n < tns_numfilters; n++) + { + write_bit_backward(ptr, bp_side, mask_side, s_min(tns_order[n], 1)); } - /* LTPF activation flag */ - write_bit_backward_fl(ptr, bp_side, mask_side, ltpf_idx[0]); - - /* SNS-VQ 1st stage */ - write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0], 5); - write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[1], 5); - - /* SNS-VQ 2nd stage side-info (3-4 bits) */ - submodeMSB = scf_idx[2] / 2; - submodeLSB = scf_idx[2] & 1; - write_bit_backward_fl(ptr, bp_side, mask_side, submodeMSB); - gainMSB = scf_idx[3] >> (gainLSBbits[scf_idx[2]]); - gainLSB = scf_idx[3] & 1; - write_uint_backward_fl(ptr, bp_side, mask_side, gainMSB, gainMSBbits[scf_idx[2]]); - write_bit_backward_fl(ptr, bp_side, mask_side, scf_idx[4]); - - /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */ - if (submodeMSB == 0) { - if (submodeLSB == 0) { - tmp = scf_idx[6] + 2; - } else { - tmp = gainLSB; + /* LTPF on/off*/ + write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[0], 1); + + /* Encode SCF VQ parameters - 1st stage (10 bits) */ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[0]), 5); /* stage1 LF 5 bits */ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[1]), 5); /* stage1 HF 5 bits */ + + /* Encode SCF VQ parameters - 2nd stage side-info (3-4 bits) */ + submode_MSB = shr_pos(extract_l(L_scf_idx[2]), 1); /* explicit tx */ + write_bit_backward(ptr, bp_side, mask_side, submode_MSB); /* submode MSB 1 explicit bit */ + submode_LSB = s_and(extract_l(L_scf_idx[2]), 0x1); /* for joint coding with shapeCw */ + gain_MSBs = extract_l(L_scf_idx[3]); /* all gain bits */ + L_gain_LSB = L_and(L_scf_idx[3], 0x1L); + gain_MSBs = shr(gain_MSBs, sns_gainLSBbits[L_scf_idx[2]]); + + ASSERT(gain_MSBs >= 0 && gain_MSBs < (1 << sns_gainMSBbits[L_scf_idx[2]])); /* ASSERT max 2 MSB(s) in gain bits */ + + write_indice_backward(ptr, bp_side, mask_side, gain_MSBs, + sns_gainMSBbits[L_scf_idx[2]]); /* adjgain or MSBs of adjGains 1-2 bits */ + write_bit_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[4])); /* shape LS 1 bit */ + + /* Encode SCF VQ parameters - 2nd stage data (24-25 bits) */ + IF (submode_MSB == 0) + { /* regular,regular_lf*/ + ASSERT(submode_MSB == 0); + + L_tmp = L_add(L_gain_LSB, 0); /* gain-LSB 0,1 for regular_lf, offset is 0 */ + if (submode_LSB == 0) + { + L_tmp = L_add(L_scf_idx[6], + sns_MPVQ_Sz[1][1]); /* shape B pos offset is 2 , upshifted two positions , 0..11 -> 2..13 */ } - - tmp = tmp * 2390004 + scf_idx[5]; - write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 25); - } else { - tmp = scf_idx[5]; - - if (submodeLSB != 0) { - tmp = 2 * tmp + gainLSB + 15158272; + /* regular mode A,B indexes multiplexed, total 24.x bits MPVQ codeword section A + codeword for section B */ + L_tmp = ac_enc_mux_st2VQ_cws(sns_MPVQ_Sz[0][0], /* max 21.3 bits*/ + UL_addNsD(sns_MPVQ_Sz[0][1], sns_MPVQ_Sz[1][1]), /* max log2(14) bits */ + L_scf_idx[5] /* shapeA */, L_tmp /* shapeB joint with adjGainLSB */); + /* regular mode mode shape index total 1+23.9999 bits MPVQ codeword */ + ASSERT(L_tmp < (1L << 25)); + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_tmp), 13); /* multiplex 13 bits */ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_shr_pos(L_tmp, 13)), 12); /* multiplex 12 bits */ + } + ELSE + { /* outlier near, outlier far */ + ASSERT(submode_MSB == 1); + L_tmp = L_scf_idx[5]; move32(); /* outlier near section assumed */ + if (submode_LSB != 0) + { /* outl_far */ + L_tmp = L_add(L_shl_pos(L_tmp, 1), L_gain_LSB); /* add lsb bit of Gain */ + L_tmp = L_add(L_tmp, sns_MPVQ_Sz[2][0]); /* outlier far section offset added */ } - write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 24); + ASSERT(L_tmp < (1L << 24)); + /* outlier mode shape index total 23.8536 ( + ~.14 ) bits as MPVQ codeword */ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_tmp), 12); /* multiplex 12 bits LSB*/ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_shr(L_tmp, 12)), 12); /* multiplex 12 bits MSBs */ } /* LTPF data */ - if (ltpf_idx[0] == 1) { - write_uint_backward_fl(ptr, bp_side, mask_side, ltpf_idx[1], 1); - write_uint_backward_fl(ptr, bp_side, mask_side, ltpf_idx[2], 9); + IF (ltpf_idx[0] != 0) + { + write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[1], 1); + write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[2], 9); } - /* Noise factor */ - write_uint_backward_fl(ptr, bp_side, mask_side, fac_ns_idx, 3); + /* Encoder noise-fac */ + write_indice_backward(ptr, bp_side, mask_side, fac_ns_idx, 3); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif } -void write_uint_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT val, LC3_INT numbits) +static __forceinline Word32 +ac_enc_mux_st2VQ_cws( /* o: max 25 bits total codeword */ + const Word32 L_szA, /* i: max 22 bits */ + const Word32 L_szB, /* i: max 4 bits 0..13 */ + const Word32 L_cwA, + const Word32 L_cwB) /* [0..13} corresponding to gains{0,1}, shapeB{0..11} or */ { - LC3_INT k, bit; - for (k = 0; k < numbits; k++) { - bit = val & 1; - write_bit_backward_fl(ptr, bp_side, mask_side, bit); - val = val >> 1; - } -} + Word32 L_cwTx; + /* L_cw_tx = L_cwB(21.z bits) * L_szA(3.y bits) + L_cwA(21.x bits)); */ + L_cwTx = (Word32)UL_Mpy_32_32( + (UWord32)L_cwB, (UWord32)L_szA); /* non-fractional 16x32 -> 32 may possibly also be used if available */ + L_cwTx = L_add(L_cwTx, L_cwA); -void write_bit_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT bit) -{ - if (bit != 0) { - ptr[*bp_side] = ptr[*bp_side] | *mask_side; - } - - if (*mask_side == 128) { - *mask_side = 1; - *bp_side = *bp_side - 1; - } else { - *mask_side = *mask_side << 1; - } + ASSERT((L_szA * L_szB) <= 1 << 25); /* multiplexing only allowed up to 25 bits (+ leading sign) */ + ASSERT(L_cwTx >= 0 && L_cwTx <= 0x01ffFFff); /* max 25 bits allowed */ + UNUSED(L_szB); + + return L_cwTx; } diff --git a/lib_lc3plus/enc_lc3.c b/lib_lc3plus/enc_lc3.c new file mode 100644 index 000000000..30ff9971b --- /dev/null +++ b/lib_lc3plus/enc_lc3.c @@ -0,0 +1,680 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" +#include // ToDo: probably to be removed + +static void Enc_LC3PLUS_Channel(LC3PLUS_Enc *encoder, int channel, int bits_per_sample, Word32 *s_in, UWord8 *bytes, + Word8 *scratchBuffer, int bfi_ext) +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In(Word16 d_fx_exp; + Word16 gain_e, gain, quantizedGain, quantizedGainMin; + Word16 ener_fx_exp; + Word16 pitch, normcorr; + Word16 ltpf_bits; + Word16 tns_numfilters; + Word16 lsbMode, lastnz, BW_cutoff_idx; + Word16 gainChange, fac_ns_idx; + Word16 nBits, numResBits; + Word16 bp_side, mask_side; + Word16 s_12k8_len; + Word16 b_left; + Word32 * L_scf_idx; + Word32 * d_fx, *ener_fx; + Word16 * s_12k8, *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX], *indexes; + Word32 * q_d_fx24; + Word16 * scf; + Word16 * codingdata; + Word32 * scf_q, *int_scf_fx; + Word32 * s_in_scaled; + Word16 * s_in_scaled_lp; + UWord8 * resBits; + Word16 ltpf_idx[3]; + EncSetup * h_EncSetup; + Word8 * currentScratch; + Word16 hrmode; + ); +#else + Dyn_Mem_Deluxe_In(Word16 d_fx_exp; Word16 gain_e, gain, quantizedGain, quantizedGainMin; Word16 ener_fx_exp; + Word16 pitch, normcorr; Word16 ltpf_bits; Word16 tns_numfilters; + Word16 lsbMode, lastnz, BW_cutoff_idx; Word16 gainChange, fac_ns_idx; Word16 nBits, numResBits; + Word16 bp_side, mask_side; Word16 s_12k8_len; Word16 b_left; + + Word32 * L_scf_idx; Word32 * d_fx, *ener_fx; + Word16 * s_12k8, *int_scf_fx_exp, *q_d_fx16, *int_scf_fx, tns_order[TNS_NUMFILTERS_MAX], *indexes; + Word16 * scf, *scf_q; Word16 * codingdata; Word16 * s_in_scaled; UWord8 * resBits; + Word8 * currentScratch; Word16 ltpf_idx[3]; EncSetup * h_EncSetup;); +#endif /* ENABLE_HR_MODE */ + + h_EncSetup = encoder->channel_setup[channel]; + +#ifdef ENABLE_HR_MODE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + hrmode = encoder->hrmode; +# endif +#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + +#ifdef WMOPS + BASOP_sub_start("Encoder"); +#endif + + /* BUFFER INITIALISATION. Some buffers may overlap since they are not used in the whole encoding process */ + d_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */ + L_scf_idx = scratchAlign( + d_fx, sizeof(*d_fx) * s_max(80, encoder->frame_length)); /* Size = 4 * SCF_MAX_PARAM -> aligned to 32 bytes */ + indexes = scratchAlign(L_scf_idx, + sizeof(*L_scf_idx) * SCF_MAX_PARAM); /* Size = 2 * TNS_NUMFILTERS_MAX * MAXLAG = 32 bytes */ + +#ifdef ENABLE_HR_MODE + q_d_fx24 = scratchAlign(indexes, sizeof(*indexes) * (TNS_NUMFILTERS_MAX * MAXLAG)); +#else + q_d_fx16 = scratchAlign(indexes, sizeof(*indexes) * (TNS_NUMFILTERS_MAX * MAXLAG)); /* Size = 2 * MAX_LEN bytes */ +#endif /* ENABLE_HR_MODE */ + +#ifdef ENABLE_HR_MODE + codingdata = + scratchAlign(q_d_fx24, sizeof(*q_d_fx24) * s_max(80, encoder->frame_length)); /* Size = 3 * MAX_LEN bytes */ +#else + codingdata = + scratchAlign(q_d_fx16, sizeof(*q_d_fx16) * s_max(80, encoder->frame_length)); /* Size = 3 * MAX_LEN bytes */ +#endif + +#ifdef ENABLE_HR_MODE + ener_fx = scratchAlign(q_d_fx24, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */ + s_in_scaled = scratchAlign(q_d_fx24, 0); /* Size = 2 * MAX_LEN bytes */ +#else + ener_fx = scratchAlign(q_d_fx16, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */ + s_in_scaled = scratchAlign(q_d_fx16, 0); /* Size = 2 * MAX_LEN bytes */ +#endif + +#ifdef ENABLE_HR_MODE + s_in_scaled_lp = (Word16 *)s_in_scaled; +#endif + +#ifdef ENABLE_HR_MODE + /* allocate memory for residual bits */ + if (encoder->hrmode) + { + resBits = scratchAlign(codingdata, sizeof(*codingdata) * (3 * s_max(80, encoder->frame_length) / 2)); + } + else +#endif /* #ifdef ENABLE_HR_MODE */ + { + resBits = scratchAlign(codingdata, + sizeof(*codingdata) * (3 * s_max(80, encoder->frame_length) / 2)); /* Size = MAX_LEN bytes */ + } + + { +#ifdef ENABLE_HR_MODE + currentScratch = + scratchAlign(resBits, sizeof(*resBits) * MAX_RESBITS_LEN); /* Size = 4 * MAX_LEN */ +#else + currentScratch = + scratchAlign(resBits, sizeof(*resBits) * s_max(80, encoder->frame_length)); /* Size = 4 * MAX_LEN */ +#endif /* #ifdef ENABLE_HR_MODE */ + } + + s_12k8 = scratchAlign( + s_in_scaled, + sizeof(*s_in_scaled) * + s_max(80, encoder->frame_length)); /* Size = 2 * (LEN_12K8 + 1) = 258 bytes -> aligned to 288 bytes */ + scf_q = scratchAlign(ener_fx, sizeof(*ener_fx) * MAX_BANDS_NUMBER); /* Size = 2 * M */ + scf = scratchAlign(scf_q, sizeof(*scf_q) * M); /* Size = 2 * M */ + int_scf_fx = scratchAlign(scf, sizeof(*scf) * M); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + int_scf_fx_exp = + scratchAlign(int_scf_fx, sizeof(*int_scf_fx) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + + /* Scale 24-bit input data */ + IF (sub(bits_per_sample, 24) == 0) + { +#ifdef WMOPS + BASOP_sub_start("Scale_signal24"); +#endif + scale_signal24_fx(s_in, s_in_scaled, &h_EncSetup->x_exp, h_EncSetup->stEnc_mdct_mem, + encoder->stEnc_mdct_mem_len, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len, + h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len, + h_EncSetup->mdct_mem32, encoder->frame_length, h_EncSetup->resamp_mem32, + h_EncSetup->olpa_mem_s12k8, &h_EncSetup->resamp_exp); +#ifdef WMOPS + BASOP_sub_end(); +#endif + } + ELSE + { +#ifdef ENABLE_HR_MODE + Word16 *ip_buf = (Word16*)s_in; + Word32 i; + FOR(i = 0; i < encoder->frame_length; i++) + { + s_in_scaled[i] = L_deposit_h(ip_buf[i]); + } + h_EncSetup->x_exp = 15; move16(); +#else + memcpy(s_in_scaled, s_in, encoder->frame_length * sizeof(*s_in_scaled)); +#endif + } + +#ifdef WMOPS + BASOP_sub_start("Mdct"); +#endif + + /* currentScratch Size = 4 * MAX_LEN */ + processMdct_fx(s_in_scaled, h_EncSetup->x_exp, encoder->frame_length, +#ifdef ENABLE_HR_MODE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + hrmode, +# endif +#endif + encoder->W_fx, encoder->W_size, + h_EncSetup->stEnc_mdct_mem, encoder->stEnc_mdct_mem_len, d_fx, &d_fx_exp, currentScratch); +#ifdef WMOPS + BASOP_sub_end(); +#endif + + /* begin s_12k8 */ +#ifdef WMOPS + BASOP_sub_start("Resamp12k8"); +#endif + /* currentScratch Size = 2.25 * MAX_LEN bytes */ +#ifdef ENABLE_HR_MODE + downshift_w32_arr(s_in_scaled, s_in_scaled_lp, 16, encoder->frame_length); /* s_in_scaled is no longer required */ + + process_resamp12k8_fx(s_in_scaled_lp, encoder->frame_length, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len, + h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len, s_12k8, + &s_12k8_len, encoder->fs_idx, encoder->frame_dms, currentScratch + , bits_per_sample + ); +#else + process_resamp12k8_fx(s_in_scaled, encoder->frame_length, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len, + h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len, s_12k8, + &s_12k8_len, encoder->fs_idx, encoder->frame_dms, currentScratch + , bits_per_sample + ); +#endif /* ENABLE_HR_MODE */ +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Olpa"); +#endif + /* currentScratch Size = 392 bytes */ + process_olpa_fx(&h_EncSetup->olpa_mem_s6k4_exp, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4, &pitch, + s_12k8, s_12k8_len, &normcorr, &h_EncSetup->olpa_mem_pitch, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + &h_EncSetup->pitch_flag, +#endif + h_EncSetup->resamp_exp, encoder->frame_dms, currentScratch); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("LtpfEnc"); +#endif + /* currentScratch Size = 512 bytes */ + process_ltpf_coder_fx(<pf_bits, pitch, h_EncSetup->ltpf_enable, &h_EncSetup->ltpf_mem_in_exp, + h_EncSetup->ltpf_mem_in, encoder->ltpf_mem_in_len, ltpf_idx, s_12k8, s_12k8_len, + &h_EncSetup->ltpf_mem_normcorr, &h_EncSetup->ltpf_mem_mem_normcorr, normcorr, + &h_EncSetup->ltpf_mem_ltpf_on, &h_EncSetup->ltpf_mem_pitch, h_EncSetup->resamp_exp, + encoder->frame_dms, currentScratch +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,encoder->hrmode +#endif +); +#ifdef WMOPS + BASOP_sub_end(); +#endif + + /* end s_12k8 */ +#ifdef WMOPS + BASOP_sub_start("AttackDetector"); +#endif + /* currentScratch Size = ??? bytes */ +#ifdef ENABLE_HR_MODE + attack_detector_fx(encoder, h_EncSetup, s_in_scaled_lp, sub(h_EncSetup->x_exp, 15), currentScratch); +#else + attack_detector_fx(encoder, h_EncSetup, s_in_scaled, sub(h_EncSetup->x_exp, 15), currentScratch); +#endif +#ifdef WMOPS + BASOP_sub_end(); +#endif + + /* begin ener_fx */ +#ifdef WMOPS + BASOP_sub_start("PerBandEnergy"); +#endif + /* currentScratch Size = 160 bytes */ + processPerBandEnergy_fx(ener_fx, &ener_fx_exp, d_fx, d_fx_exp, encoder->bands_offset, encoder->fs_idx, + encoder->bands_number, 0, encoder->frame_dms, currentScratch +#ifdef ENABLE_HR_MODE + , encoder->hrmode +#endif + ); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Near Nyquist Detector"); +#endif + /* Near Nyquist Detector */ + processNearNyquistdetector_fx(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, + encoder->bands_number, ener_fx, ener_fx_exp +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + , encoder->frame_dms, encoder->hrmode ); +#else + ); +#endif +#else + ); +#endif + /* Disable LTPF if nyquist detector triggers */ + IF (encoder->near_nyquist_flag != 0 || sub(h_EncSetup->lfe, 1) == 0) + { + h_EncSetup->ltpf_mem_ltpf_on = 0; move16(); + ltpf_idx[1] = 0; move16(); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif +#ifdef WMOPS + BASOP_sub_start("BW Cutoff-Detection"); +#endif + IF (h_EncSetup->lfe == 0) + { +#ifdef ENABLE_HR_MODE + /* No BW Cutoff for 8 kHz and 96 kHz */ + IF (encoder->fs_idx > 0 && encoder->hrmode == 0 && encoder->bw_ctrl_active == 0) + { +#else /* ENABLE_HR_MODE */ + IF (encoder->fs_idx > 0 && encoder->bw_ctrl_active == 0) + { +#endif /* ENABLE_HR_MODE */ + processDetectCutoffWarped_fx(&BW_cutoff_idx, ener_fx, ener_fx_exp, encoder->fs_idx, encoder->frame_dms); + } + ELSE + { + BW_cutoff_idx = encoder->fs_idx; + move16(); + } + } + ELSE + { + BW_cutoff_idx = 0; + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("SnsCompScf"); +#endif + + + /* currentScratch Size = 512 bytes */ + processSnsComputeScf_fx(ener_fx, ener_fx_exp, encoder->fs_idx, encoder->bands_number, scf, + h_EncSetup->attdec_detected, encoder->attdec_damping, currentScratch, encoder->sns_damping + ); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("SnsQuantScfEnc"); +#endif + /* currentScratch Size = 500 bytes */ + + processSnsQuantizeScfEncoder_fx(scf, L_scf_idx, scf_q, currentScratch); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("SnsInterpScfEnc"); +#endif + /* currentScratch Size = 128 bytes */ + processSnsInterpolateScf_fx(scf_q, int_scf_fx, int_scf_fx_exp, 1, encoder->bands_number, currentScratch); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Mdct shaping_enc"); +#endif + processMdctShaping_fx(d_fx, int_scf_fx, int_scf_fx_exp, encoder->bands_offset, encoder->bands_number); + +#ifdef WMOPS + BASOP_sub_end(); +#endif + /* end int_scf_fx_exp */ +#ifdef WMOPS + BASOP_sub_start("BandwidthControl_enc"); +#endif + if (encoder->bandwidth < L_shr_pos(encoder->fs, 1)) + { + process_cutoff_bandwidth(d_fx, encoder->yLen, encoder->bw_ctrl_cutoff_bin); + BW_cutoff_idx = s_min(BW_cutoff_idx, encoder->bw_index); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif +#ifdef WMOPS + BASOP_sub_start("Tns_enc"); +#endif + /* currentScratch Size = 2 * MAX_LEN + 220 */ + + IF (h_EncSetup->lfe == 0) + { + processTnsCoder_fx(&(h_EncSetup->tns_bits), indexes, d_fx, BW_cutoff_idx, tns_order, &tns_numfilters, + h_EncSetup->enable_lpc_weighting, encoder->nSubdivisions, encoder->frame_dms, + encoder->frame_length, currentScratch +#ifdef ENABLE_HR_MODE + , encoder->hrmode +#endif + , encoder->near_nyquist_flag + ); + } + ELSE + { + tns_numfilters = 1; + move16(); + tns_order[0] = 0; + move16(); + h_EncSetup->tns_bits = tns_numfilters; + move16(); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Est. Global Gain"); +#endif + /* currentScratch Size = 4 * MAX_LEN bytes */ + h_EncSetup->targetBitsQuant = sub(h_EncSetup->targetBitsInit, add(h_EncSetup->tns_bits, ltpf_bits)); + + test(); + IF (h_EncSetup->targetBitsQuant < 0 && sub(ltpf_bits, 1) > 0) + { + /* Disable LTPF */ + h_EncSetup->ltpf_mem_ltpf_on = 0; move16(); + ltpf_idx[1] = 0; move16(); + ltpf_bits = 1; move16(); + h_EncSetup->targetBitsQuant = sub(h_EncSetup->targetBitsInit, add(h_EncSetup->tns_bits, ltpf_bits)); + } + +#ifdef ENABLE_HR_MODE + Word32 gain32; +#endif + + processEstimateGlobalGain_fx(d_fx, d_fx_exp, encoder->yLen, h_EncSetup->targetBitsQuant, +#ifdef ENABLE_HR_MODE + &gain32, +#else + &gain, +#endif + &gain_e, + &quantizedGain, &quantizedGainMin, h_EncSetup->quantizedGainOff, + &h_EncSetup->targetBitsOff, &h_EncSetup->mem_targetBits, h_EncSetup->mem_specBits, + currentScratch +#ifdef ENABLE_HR_MODE + , encoder->hrmode, h_EncSetup->regBits, encoder->frame_dms +#endif + ); +#ifdef WMOPS + BASOP_sub_end(); +#endif + /* begin q_d_fx16 */ + +#ifdef WMOPS + BASOP_sub_start("Quant. 1"); +#endif +#ifdef ENABLE_HR_MODE + processQuantizeSpec_fx(d_fx, d_fx_exp, gain32, gain_e, q_d_fx24, encoder->yLen, h_EncSetup->targetBitsQuant, + h_EncSetup->targetBitsAri, &h_EncSetup->mem_specBits, &nBits, encoder->fs_idx, &lastnz, + codingdata, &lsbMode, -1, encoder->hrmode); + +#else + processQuantizeSpec_fx(d_fx, d_fx_exp, gain, gain_e, q_d_fx16, encoder->yLen, h_EncSetup->targetBitsQuant, + h_EncSetup->targetBitsAri, &h_EncSetup->mem_specBits, &nBits, encoder->fs_idx, &lastnz, + codingdata, &lsbMode, -1); +#endif /* ENABLE_HR_MODE */ +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Adj. Global Gain"); +#endif +#ifdef ENABLE_HR_MODE + //gain32 = L_shl_pos((Word32)gain, 16); + processAdjustGlobalGain_fx(&quantizedGain, quantizedGainMin, h_EncSetup->quantizedGainOff, &gain32, &gain_e, + h_EncSetup->targetBitsQuant, h_EncSetup->mem_specBits, &gainChange, encoder->fs_idx + , encoder->hrmode, encoder->frame_dms + ); + gain = round_fx(gain32); +#else + processAdjustGlobalGain_fx(&quantizedGain, quantizedGainMin, h_EncSetup->quantizedGainOff, &gain, &gain_e, + h_EncSetup->targetBitsQuant, h_EncSetup->mem_specBits, &gainChange, encoder->fs_idx); +#endif /* ENABLE_HR_MODE */ +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Quant. 2"); +#endif + IF (sub(gainChange, 1) == 0) + { +#ifdef ENABLE_HR_MODE + processQuantizeSpec_fx(d_fx, d_fx_exp, gain32, gain_e, q_d_fx24, encoder->yLen, h_EncSetup->targetBitsQuant, + h_EncSetup->targetBitsAri, NULL, &nBits, encoder->fs_idx, &lastnz, codingdata, &lsbMode, + 0, encoder->hrmode); +#else + processQuantizeSpec_fx(d_fx, d_fx_exp, gain, gain_e, q_d_fx16, encoder->yLen, h_EncSetup->targetBitsQuant, + h_EncSetup->targetBitsAri, NULL, &nBits, encoder->fs_idx, &lastnz, codingdata, &lsbMode, + 0); +#endif /* ENABLE_HR_MODE */ + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Res. Cod."); +#endif + IF (lsbMode == 0) + { + processResidualCoding_fx(d_fx_exp, d_fx, +#ifdef ENABLE_HR_MODE + q_d_fx24, +#else + q_d_fx16, +#endif +#ifdef ENABLE_HR_MODE + gain32, +#else + gain, +#endif + gain_e, encoder->yLen, h_EncSetup->targetBitsQuant, nBits, resBits, &numResBits +#ifdef ENABLE_HR_MODE + , encoder->hrmode +#endif + ); + } + ELSE + { + numResBits = 0; + move16(); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Noise fac"); +#endif + /* currentScratch Size = 2 * MAX_LEN bytes */ + IF (h_EncSetup->lfe == 0) + { + processNoiseFactor_fx(&fac_ns_idx, d_fx_exp, d_fx, +#ifdef ENABLE_HR_MODE + q_d_fx24, +#else + q_d_fx16, +#endif + gain, gain_e, BW_cutoff_idx, encoder->frame_dms, h_EncSetup->targetBytes, currentScratch +#ifdef ENABLE_HR_MODE + , encoder->hrmode +#endif + ); + } + ELSE + { + fac_ns_idx = 7; + move16(); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Entropy cod"); +#endif + processEncoderEntropy(bytes, &bp_side, &mask_side, h_EncSetup->targetBitsAri, h_EncSetup->targetBytes, + encoder->yLen, encoder->BW_cutoff_bits, tns_numfilters, lsbMode, lastnz, tns_order, + fac_ns_idx, quantizedGain, BW_cutoff_idx, ltpf_idx, L_scf_idx, bfi_ext, encoder->fs_idx); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Ari cod"); +#endif + processAriEncoder_fx(bytes, bp_side, mask_side, h_EncSetup->targetBitsAri, +#ifdef ENABLE_HR_MODE + q_d_fx24, +#else + q_d_fx16, +#endif + tns_order, tns_numfilters, indexes, lastnz, codingdata, resBits, numResBits, lsbMode, + h_EncSetup->enable_lpc_weighting, currentScratch); +#ifdef WMOPS + BASOP_sub_end(); +#endif + +#ifdef WMOPS + BASOP_sub_start("Reorder Bitstream Enc"); +#endif + test(); + IF (encoder->combined_channel_coding == 0 && h_EncSetup->n_pc > 0) + { +#ifdef WMOPS + BASOP_sub_start("Reorder Ari dec"); +#endif + +#ifdef ENABLE_HR_MODE + Word32 *xbuf = (Word32 *) scratchAlign(scratchBuffer, 0); + + processAriDecoder_fx(bytes, &bp_side, &mask_side, h_EncSetup->total_bits, encoder->yLen, encoder->fs_idx, + h_EncSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &gain, tns_order, + fac_ns_idx, quantizedGain, encoder->frame_dms, h_EncSetup->n_pc, 0, + shr_pos(h_EncSetup->total_bits, 3), 1, &gain, &b_left, &gain, + xbuf, + &gain, resBits, indexes, &gain, + currentScratch + , encoder->hrmode + ); +#else + + processAriDecoder_fx(bytes, &bp_side, &mask_side, h_EncSetup->total_bits, encoder->yLen, encoder->fs_idx, + h_EncSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &gain, tns_order, + fac_ns_idx, quantizedGain, encoder->frame_dms, h_EncSetup->n_pc, 0, + shr_pos(h_EncSetup->total_bits, 3), 1, &gain, &b_left, &gain, + codingdata, + &gain, resBits, indexes, &gain, + currentScratch + ); +#endif + +#ifdef WMOPS + BASOP_sub_end(); /* Ari dec */ +#endif + processReorderBitstream_fx(bytes, h_EncSetup->n_pccw, h_EncSetup->n_pc, b_left, currentScratch); + } +#ifdef WMOPS + BASOP_sub_end(); +#endif + + /* end q_d_fx16 */ +#ifdef WMOPS + BASOP_sub_end(); +#endif + + Dyn_Mem_Deluxe_Out(); +} + +int Enc_LC3PLUS(LC3PLUS_Enc *encoder, void **input, int bits_per_sample, UWord8 *output, void *scratch, Word16 bfi_ext) +{ + int ch = 0, output_size = 0; + int input_size = 0; + int totalBytes = (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); + int output_size2; + + UWord8 *lc3buf = output; + + for (ch = 0; ch < encoder->channels; ch++) + { + Enc_LC3PLUS_Channel(encoder, ch, bits_per_sample, input[ch], lc3buf, scratch, bfi_ext); + if (encoder->epmode && encoder->combined_channel_coding == 0) + { + output_size2 = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); +#ifdef WMOPS + BASOP_sub_start("fec_enc"); +#endif + + fec_encoder(encoder->epmode, encoder->epmr, lc3buf, encoder->channel_setup[ch]->targetBytes, output_size2, + encoder->channel_setup[ch]->n_pccw, scratch); + +#ifdef WMOPS + BASOP_sub_end(); +#endif + + lc3buf += output_size2; + output_size += output_size2; + } + else + { + lc3buf += encoder->channel_setup[ch]->targetBytes; + output_size += encoder->channel_setup[ch]->targetBytes; + } + } + + if (encoder->epmode > 0 && encoder->combined_channel_coding) + { + input_size = output_size; + output_size = (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); +#ifdef WMOPS + BASOP_sub_start("fec_enc"); +#endif + + fec_encoder(encoder->epmode, encoder->epmr, output, input_size, output_size, encoder->channel_setup[0]->n_pccw, + scratch); + +#ifdef WMOPS + BASOP_sub_end(); +#endif + } + + return output_size; +} + diff --git a/lib_lc3plus/enc_lc3_fl.c b/lib_lc3plus/enc_lc3_fl.c deleted file mode 100644 index 56771ce5b..000000000 --- a/lib_lc3plus/enc_lc3_fl.c +++ /dev/null @@ -1,283 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s_in, uint8_t* bytes, int bps -, LC3_INT32 bfi_ext -) -{ - EncSetup* h_EncSetup; - - LC3_INT s_12k8_len = 0, T0_out = 0, ltpfBits = 0, BW_cutoff_idx = 0, tns_numfilters = 0, quantizedGain = 0, - quantizedGainMin = 0, nbits = 0, nbits2 = 0, lastnz = 0, lsbMode = 0, gainChange = 0, bp_side = 0, - mask_side = 0, fac_ns_idx = 0, numResBits = 0, tns_order[2] = {0}, i = 0; - LC3_FLOAT normcorr = 0, gain = 0; - - - LC3_FLOAT d_fl[MAX_LEN] = {0}; - LC3_INT q_d[MAX_LEN] = {0}; - LC3_INT indexes[TNS_NUMFILTERS_MAX * MAXLAG] = {0}; - - h_EncSetup = encoder->channel_setup[channel]; - memset(bytes, 0, sizeof(uint8_t) * h_EncSetup->targetBytes); - - if (bps == 24) { - for (i = 0; i < encoder->frame_length; i++) { - int32_t tmp = ((int32_t*)s_in)[i]; - - if (tmp >= 0) - { - tmp = tmp & 0x007fffff; - } - else - { - tmp = tmp | (int32_t)0xff800000; - } - - h_EncSetup->s_in_scaled[i] = ((LC3_FLOAT) tmp / (float) LC3_POW(2, 8)); - } - } else if (bps == 16) { - for (i = 0; i < encoder->frame_length; i++) { - h_EncSetup->s_in_scaled[i] = (LC3_FLOAT)((int16_t*)s_in)[i]; - } - } - - /* MDCT */ - processMdct_fl(h_EncSetup->s_in_scaled, d_fl, &h_EncSetup->mdctStruct); - - /* 12.8 kHz resampler */ - process_resamp12k8_fl(h_EncSetup->s_in_scaled, encoder->frame_length, h_EncSetup->r12k8_mem_in, - encoder->r12k8_mem_in_len, h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, - encoder->r12k8_mem_out_len, h_EncSetup->s_12k8, &s_12k8_len, encoder->fs_idx, - encoder->frame_dms, encoder->fs); - - /* Pitch estimation */ - processOlpa_fl(h_EncSetup->s_12k8, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4, - &h_EncSetup->olpa_mem_pitch, -#ifdef CR9_F_PITCH_WIN_LEN_FIX - &h_EncSetup->pitch_flag, -#endif - &T0_out, &normcorr, s_12k8_len, encoder->frame_dms); - - /* LTPF encoder */ - process_ltpf_coder_fl(h_EncSetup->s_12k8, s_12k8_len + 1, h_EncSetup->ltpf_enable, T0_out, normcorr, - encoder->frame_dms, h_EncSetup->ltpf_mem_in, encoder->ltpf_mem_in_len, - &h_EncSetup->ltpf_mem_normcorr, &h_EncSetup->ltpf_mem_ltpf_on, - &h_EncSetup->ltpf_mem_pitch, h_EncSetup->ltpf_param, &h_EncSetup->ltpf_mem_mem_normcorr, - <pfBits -#ifdef CR9_K_REDUCE_NORM_CORR_TH - ,encoder->hrmode -#endif -); - - /* Attack detector */ - attack_detector_fl(h_EncSetup->s_in_scaled, encoder->frame_length, encoder->fs, &h_EncSetup->attdec_position, - &h_EncSetup->attdec_acc_energy, &h_EncSetup->attdec_detected, h_EncSetup->attdec_filter_mem, - h_EncSetup->attack_handling, encoder->attdec_nblocks, encoder->attdec_hangover_thresh); - - /* Per-band energy */ - processPerBandEnergy_fl(encoder->bands_number, encoder->bands_offset, encoder->hrmode, encoder->frame_dms, h_EncSetup->ener, d_fl); - /* Near Nyquist detector */ - processNearNyquistdetector_fl(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, encoder->bands_number, h_EncSetup->ener -#ifdef CR8_E_TONE_DETECTOR - , encoder->frame_dms, encoder->hrmode ); -#else - ); -#endif - /* Disable LTPF if nyquist detector triggers or -lfe mode is active*/ - if (encoder->near_nyquist_flag != 0 || h_EncSetup->lfe == 1) - { - h_EncSetup->ltpf_mem_ltpf_on = 0; - h_EncSetup->ltpf_param[1] = 0; - } - - /* Bandwidth cut-off detection */ - if (h_EncSetup->lfe == 0) { - /* No BW Cutoff for 8 kHz and 96 kHz. No detection if bandwidth controller is active */ - if (encoder->fs_idx > 0 && encoder->hrmode == 0 && encoder->bw_ctrl_active == 0) { - processDetectCutoffWarped_fl(h_EncSetup->ener, encoder->fs_idx, encoder->frame_dms, &BW_cutoff_idx); - } else { - BW_cutoff_idx = encoder->fs_idx; - } - } else { - BW_cutoff_idx = 0; - } - - processSnsComputeScf_fl(h_EncSetup->ener, encoder->bands_number, h_EncSetup->scf, - h_EncSetup->attdec_detected, encoder->sns_damping, encoder->attdec_damping, encoder->fs_idx); - - /* SNS Quantizer */ - process_snsQuantizesScf_Enc(h_EncSetup->scf, h_EncSetup->L_scf_idx, h_EncSetup->scf_q, h_EncSetup->dct2StructSNS); - - /* SNS Interpolation */ - processSnsInterpolateScf_fl(h_EncSetup->scf_q, 1, encoder->bands_number, h_EncSetup->int_scf); - - /* MDCT shaping */ - processMdctShaping_fl(d_fl, h_EncSetup->int_scf, encoder->bands_offset, encoder->bands_number); - - /* Bandwidth controller */ - if (encoder->bandwidth < encoder->fs / 2) { - process_cutoff_bandwidth(d_fl, encoder->yLen, encoder->bw_ctrl_cutoff_bin); - BW_cutoff_idx = MIN(BW_cutoff_idx, encoder->bw_index); - } - - /* TNS encoder */ - if (h_EncSetup->lfe == 0) - { - processTnsCoder_fl(d_fl, BW_cutoff_idx, encoder->cutoffBins[BW_cutoff_idx], encoder->fs, encoder->frame_length, - encoder->frame_dms, h_EncSetup->total_bits, tns_order, indexes, &tns_numfilters, - &(h_EncSetup->tns_bits) - , encoder->near_nyquist_flag - ); - } - else - { - tns_numfilters = 1; - tns_order[0] = 0; - h_EncSetup->tns_bits = tns_numfilters; - } - /* Global Gain Estimation */ - h_EncSetup->targetBitsQuant = h_EncSetup->targetBitsInit - (h_EncSetup->tns_bits + ltpfBits); - - if (h_EncSetup->targetBitsQuant < 0 && ltpfBits > 1) - { - /* Disable LTPF */ - h_EncSetup->ltpf_mem_ltpf_on = 0; - h_EncSetup->ltpf_param[1] = 0; - ltpfBits = 1; - h_EncSetup->targetBitsQuant = h_EncSetup->targetBitsInit - (h_EncSetup->tns_bits + ltpfBits); - } - - processEstimateGlobalGain_fl(d_fl, encoder->yLen, h_EncSetup->targetBitsQuant, &gain, &quantizedGain, - &quantizedGainMin, h_EncSetup->quantizedGainOff, &h_EncSetup->targetBitsOff, - &h_EncSetup->mem_targetBits, h_EncSetup->mem_specBits - , encoder->hrmode, h_EncSetup->regBits, encoder->frame_ms - - ); - - /* 1. Quantization */ - processQuantizeSpec_fl(d_fl, gain, q_d, encoder->yLen, h_EncSetup->total_bits, &nbits, &nbits2, encoder->fs, - &lastnz, h_EncSetup->codingdata, &lsbMode, -1, h_EncSetup->targetBitsQuant, encoder->hrmode - ); - - h_EncSetup->mem_specBits = nbits; - - /* Global Gain Adjustment */ - processAdjustGlobalGain_fl(&quantizedGain, quantizedGainMin, h_EncSetup->quantizedGainOff, &gain, - h_EncSetup->targetBitsQuant, h_EncSetup->mem_specBits, &gainChange, encoder->fs_idx - , encoder->hrmode, encoder->frame_dms - ); - - /* 2. Quantization */ - if (gainChange) { - processQuantizeSpec_fl(d_fl, gain, q_d, encoder->yLen, h_EncSetup->total_bits, &nbits, &nbits2, encoder->fs, - &lastnz, - h_EncSetup->codingdata, - &lsbMode, 0, h_EncSetup->targetBitsQuant - , encoder->hrmode - ); - } - - /* Noise factor */ - if (h_EncSetup->lfe == 0) - { - processNoiseFactor_fl(&fac_ns_idx, d_fl, q_d, gain, encoder->cutoffBins[BW_cutoff_idx], encoder->frame_dms, - h_EncSetup->targetBytes - ); - } - else - { - fac_ns_idx = 7; - } - /* Residual Coding */ - if (lsbMode == 0) { - processResidualCoding_fl(d_fl, q_d, gain, encoder->yLen, h_EncSetup->targetBitsQuant, nbits2, - h_EncSetup->resBits, &numResBits - , encoder->hrmode - ); - } else { - numResBits = 0; - } - - /* Entropy encoding */ - processEncoderEntropy_fl(bytes, &bp_side, &mask_side, h_EncSetup->targetBytes, encoder->BW_cutoff_bits, - BW_cutoff_idx, lastnz, encoder->yLen, lsbMode, quantizedGain, tns_numfilters, tns_order, - h_EncSetup->ltpf_param, h_EncSetup->L_scf_idx, fac_ns_idx - , bfi_ext, encoder->fs_idx - ); - - /* Artithmetic encoding */ - processAriEncoder_fl(bytes, bp_side, mask_side, q_d, tns_order, tns_numfilters, indexes, lastnz, - h_EncSetup->codingdata, - h_EncSetup->resBits, numResBits, lsbMode, h_EncSetup->targetBitsAri, - h_EncSetup->enable_lpc_weighting); - - if (encoder->combined_channel_coding == 0 && h_EncSetup->n_pc > 0) - { - LC3_INT32 xbuf[MAX_LEN] = {0}, nf_seed, tns_idx[M], zero_frame, nbits_residual, residualPresent, b_left, spec_inv_idx; - - memset(h_EncSetup->resBits, 0, sizeof(*(h_EncSetup->resBits)) * MAX_RESBITS_LEN); - - processAriDecoder_fl(bytes, bp_side, mask_side, encoder->yLen, encoder->fs_idx, h_EncSetup->enable_lpc_weighting, - tns_numfilters, lsbMode, lastnz, &bfi_ext, tns_order, fac_ns_idx, quantizedGain, - h_EncSetup->resBits, xbuf, &nf_seed, tns_idx, &zero_frame, h_EncSetup->targetBytes, &nbits_residual, - &residualPresent, encoder->frame_dms, h_EncSetup->n_pc, 0, h_EncSetup->total_bits >> 3, 1, &b_left, - &spec_inv_idx, encoder->hrmode); - - processReorderBitstream_fl(bytes, h_EncSetup->n_pccw, h_EncSetup->n_pc, b_left, h_EncSetup->targetBytes); - } - -} - -int Enc_LC3PLUS_fl(LC3PLUS_Enc* encoder, void** input, uint8_t* output, int bps -, LC3_INT32 bfi_ext -) -{ - int ch = 0, output_size = 0; - uint8_t* lc3buf = output; - - LC3_INT32 totalBytes; - LC3_INT32 output_size2, input_size; - - totalBytes = encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); - - for (ch = 0; ch < encoder->channels; ch++) - { - Enc_LC3PLUS_Channel_fl(encoder, ch, input[ch], lc3buf, bps, bfi_ext); - if (encoder->epmode && encoder->combined_channel_coding == 0) - { - output_size2 = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); - - fec_encoder(encoder->epmode, encoder->epmr, lc3buf, encoder->channel_setup[ch]->targetBytes, output_size2, - encoder->channel_setup[ch]->n_pccw); - - lc3buf += output_size2; - output_size += output_size2; - } - else - { - lc3buf += encoder->channel_setup[ch]->targetBytes; - output_size += encoder->channel_setup[ch]->targetBytes; - } - } - - if (encoder->epmode > 0 && encoder->combined_channel_coding) - { - input_size = output_size; - output_size = encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); - - fec_encoder(encoder->epmode, encoder->epmr, output, input_size, output_size, encoder->channel_setup[0]->n_pccw); - } - - return output_size; -} diff --git a/lib_lc3plus/estimate_global_gain.c b/lib_lc3plus/estimate_global_gain.c deleted file mode 100644 index 2e69d239b..000000000 --- a/lib_lc3plus/estimate_global_gain.c +++ /dev/null @@ -1,130 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC3_FLOAT* gain, LC3_INT* quantizedGain, - LC3_INT* quantizedGainMin, LC3_INT quantizedGainOff, LC3_FLOAT* targetBitsOff, - LC3_INT* old_targetBits, LC3_INT old_specBits - , LC3_INT hrmode , LC3_INT regBits, LC3_FLOAT frame_ms -) -{ - - LC3_INT i, N, offset, j, iszero, fac; - LC3_FLOAT g_min, x_max, tmp, ind, ind_min, target, ener; - LC3_FLOAT en[MAX_LEN / 4]; - LC3_FLOAT reg_val = 4.656612873077393e-10; - - if (*old_targetBits < 0) { - *targetBitsOff = 0; - } else { - tmp = MIN(40, MAX(-40, *targetBitsOff + *old_targetBits - old_specBits)); - *targetBitsOff = 0.8 * *targetBitsOff + 0.2 * tmp; - } - - *old_targetBits = nbitsSQ; - nbitsSQ = nbitsSQ + round(*targetBitsOff); - - x_max = array_max_abs(x, lg); - - if (hrmode && regBits > 0) - { - LC3_FLOAT M0 = 1e-5, M1 = 1e-5, rB_offset; - LC3_FLOAT thresh = 2*frame_ms; - for (i = 0; i < lg; i++) - { - M0 += fabs(x[i]); - M1 += i*fabs(x[i]); - } - - rB_offset = 8 * (1 - MIN(M1/M0, thresh) / thresh); - reg_val = x_max * LC3_POW(2,-regBits - rB_offset); - } - - if (x_max < LC3_EPS) - { - ind_min = quantizedGainOff; - ind = 0; - *old_targetBits = -1; - } else { - if (hrmode == 1) { - g_min = x_max / (32768 * 256 - 2); - } else { - g_min = x_max / (32767 - 0.375); - } - /* Prevent positive rounding errors from LC3_LOG10 function */ - ind_min = 28.0 * LC3_LOGTEN(g_min); - - ind_min = ceil(ind_min + LC3_FABS(ind_min) * LC3_EPS); - - assert(LC3_POW(10, ind_min / 28.0) >= g_min); - assert(ind_min <= (255 + quantizedGainOff)); - - N = lg; - - j = 0; - for (i = 0; i < N; i = i + 4) { - tmp = x[i] * x[i]; - tmp += x[i + 1] * x[i + 1]; - tmp += x[i + 2] * x[i + 2]; - tmp += x[i + 3] * x[i + 3]; - en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOGTEN(tmp + reg_val)); - j++; - } - - target = (28.0 / 20.0) * (1.4) * nbitsSQ; - fac = 256; - offset = 255 + quantizedGainOff; - - for (i = 0; i < 8; i++) - { - fac = fac >> 1; - offset = offset - fac; - ener = 0; - iszero = 1; - - for (j = N / 4 - 1; j >= 0; j--) { - tmp = en[j] - offset; - - if (tmp < (7.0) * (28.0 / 20.0)) { - if (iszero == 0) { - ener = ener + (2.7) * (28.0 / 20.0); - } - } else { - if (tmp > (50.0) * (28.0 / 20.0)) { - ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0); - } else { - ener = ener + tmp; - } - - iszero = 0; - } - } - - if (ener > target && iszero == 0) { - offset = offset + fac; - } - } - - if (offset < ind_min) { - *old_targetBits = -1; - } - - ind = MAX(ind_min, offset) - quantizedGainOff; - } - - *quantizedGainMin = ind_min; - *quantizedGain = ind; - - *gain = LC3_POW(10.0, ((ind + quantizedGainOff) / 28.0)); -} diff --git a/lib_lc3plus/estimate_global_gain_fx.c b/lib_lc3plus/estimate_global_gain_fx.c new file mode 100644 index 000000000..c6d1766b4 --- /dev/null +++ b/lib_lc3plus/estimate_global_gain_fx.c @@ -0,0 +1,506 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void processEstimateGlobalGain_fx(Word32 x[], Word16 x_e, Word16 lg, Word16 nbitsSQ, +#ifdef ENABLE_HR_MODE + Word32 *gain, +#else + Word16 *gain, +#endif + Word16 *gain_e, + Word16 *quantizedGain, Word16 *quantizedGainMin, Word16 quantizedGainOff, + Word32 *targetBitsOff, Word16 *old_targetBits, Word16 old_specBits, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode, Word16 regBits, Word16 frame_dms +#endif +) +{ + + Word16 lg_4, tmp16, iszero, s; + Word32 ener, tmp32, x_max; + Word32 target, fac, offset; + Word32 *en; + Counter iter, i; + Word32 diff, diff2; +#ifdef ENABLE_HR_MODE + Word16 *en_exp = NULL; + Word32 M0, M1; +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processEstimateGlobalGain_fx", sizeof(struct { + Word16 lg_4, s, tmp16, iszero; + Word32 ener, tmp32, x_max; + Word32 target, fac, offset; + Word32 *en; + Counter i, iter; + Word32 diff, diff2; + })); +#endif + + en = (Word32 *)scratchAlign(scratchBuffer, + 0); /* Size = MAX_LEN bytes */ + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + M0 = 1; + M1 = 1; /* Regularization factor; needs´to be 1e-5, but 1e-5 is 0 in Q15 */ + en_exp = (Word16 *) scratchAlign(en, sizeof(*en) * MAX_LEN); + } +#endif + IF (*old_targetBits < 0) + { + *targetBitsOff = 0; + move16(); + } + ELSE + { + tmp32 = L_add(*targetBitsOff, L_deposit_h(sub(*old_targetBits, old_specBits))); + tmp32 = L_min((40 << 16), L_max(-(40 << 16), tmp32)); + *targetBitsOff = L_add(Mpy_32_16_lc3plus(*targetBitsOff, 26214), Mpy_32_16_lc3plus(tmp32, 6554)); + move16(); + } + + *old_targetBits = nbitsSQ; + move16(); + nbitsSQ = add(nbitsSQ, round_fx(*targetBitsOff)); + + lg_4 = shr_pos(lg, 2); + x_max = 0; + move32(); + +/* energy of quadruples with 9dB offset */ +#ifdef ENABLE_HR_MODE + IF (hrmode) + { + FOR (i = 0; i < lg_4; i++) + { + Word32 absval; + Word16 idx; + /* normalization */ + s = 31; + move16(); + + /* M1 requires a 32x16 mult with Q0 i, resulting in Q15. Keeping both M0 and M1 in same Q */ + /* Use Q15 for M0 and M1 calculation */ + idx = shl(i, 2); + + tmp32 = L_abs(x[0]); + absval = L_shr(tmp32, 16); + M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/ + M1 = L_add(M1, L_mult(absval, idx)); /* M1 += i*fabs(x[idx])*/ + idx = add(idx, 1); + + absval = L_abs(x[1]); + tmp32 = L_max(tmp32, absval); + absval = L_shr(tmp32, 16); + M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/ + M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/ + idx = add(idx, 1); + + absval = L_abs(x[2]); + tmp32 = L_max(tmp32, absval); + absval = L_shr(tmp32, 16); + M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/ + M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/ + idx = add(idx, 1); + + absval = L_abs(x[3]); + tmp32 = L_max(tmp32, absval); + absval = L_shr(tmp32, 16); + M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/ + M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/ + + x_max = L_max(x_max, tmp32); + + if (tmp32 != 0) + s = norm_l(tmp32); + + s = sub(s, 2); /* 2 bits headroom */ + + /* calc quadruple energy */ + ener = L_deposit_l(1); + + tmp16 = round_fx(L_shl(x[0], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[1], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[2], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[3], s)); + ener = L_mac(ener, tmp16, tmp16); + + s = shl_pos(sub(x_e, s), 1); + if (ener == 1 && s < 0) + s = 0; + IF (regBits > 0) + { + en[i] = ener; + en_exp[i] = s; + move32(); + } + ELSE + { + /* log */ + tmp32 = L_add(BASOP_Util_Log2_lc3plus(ener), L_shl_pos(L_deposit_l(s), 25)); /* log2, 6Q25 */ + tmp32 = L_add(L_shr_pos(Mpy_32_16_lc3plus(tmp32, 0x436E), 7), + 0x4E666); /* -> (28/20)*(7+10*tmp32/log2(10)), 16Q15 */ + en[i] = tmp32; + move32(); + } + + x += 4; + } + } + ELSE +#endif + { + FOR (i = 0; i < lg_4; i++) + { + /* normalization */ + s = 31; + move16(); + + tmp32 = L_abs(x[0]); + tmp32 = L_max(tmp32, L_abs(x[1])); + tmp32 = L_max(tmp32, L_abs(x[2])); + tmp32 = L_max(tmp32, L_abs(x[3])); + x_max = L_max(x_max, tmp32); + + if (tmp32 != 0) + s = norm_l(tmp32); + + s = sub(s, 2); /* 2 bits headroom */ + + /* calc quadruple energy */ + ener = L_deposit_l(1); + + tmp16 = round_fx(L_shl(x[0], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[1], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[2], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[3], s)); + ener = L_mac(ener, tmp16, tmp16); + + s = shl_pos(sub(x_e, s), 1); + if (ener == 1 && s < 0) + s = 0; + + /* log */ + tmp32 = L_add_sat(BASOP_Util_Log2_lc3plus(ener), L_shl_sat(L_deposit_l(s), 25)); /* log2, 6Q25 */ + tmp32 = + L_add(L_shr_pos(Mpy_32_16_lc3plus(tmp32, 0x436E), 6), 0x9CCCD); /* -> (28/20)*(7+10*tmp32/log2(10)), 15Q16 */ + en[i] = tmp32; + move32(); + x += 4; + } + } + + IF (x_max == 0) + { + *quantizedGainMin = quantizedGainOff; + move16(); + *quantizedGain = 0; + move16(); + *old_targetBits = -1; + move16(); + } + ELSE + { + Word32 sub_val = 0xFCDD38F; + /*28 * log10(32767 - 0.375) * (1 - 1e-7) in Q21 */ + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + /* + Original float code : + rB_offset = 8 * (1 - MIN(M1/M0, 2*frame_ms)/(2*frame_ms) + */ + Word16 ratio; + Word16 ratio_exp = 0; + Word32 regterm = MAX_32; /* 1 in Q31 */ + Word32 rB_offset, reg_val; + Word32 ratio_prod; + Word16 n_reg_val; + + if (M0 <= 0x7fff) + { + Word16 inv_M0 = Inv16_lc3plus(M0, &ratio_exp); /* Inverse in Q(15 - ratio_exp) */ + ratio = L_shr(Mpy_32_16_lc3plus(M1, inv_M0), 15 - ratio_exp); /* Integer ratio */ + } + else + { + Word16 M0_h = L_shr(M0, 15); + Word32 M1_h = L_shr(M1, 15); + + Word16 inv_M0 = Inv16_lc3plus(M0_h, &ratio_exp); /* Inverse in Q(15 - ratio_exp) */ + ratio = extract_l(L_shr(Mpy_32_16_lc3plus(M1_h, inv_M0), 15 - ratio_exp)); /* Integer ratio */ + } + + /* + regterm = MIN (M1 / M0, 2 *frame_ms) / (2 * frame_ms) + regterm = MIN (M1 * (10 / 2) / M0, frame_dms) / frame_dms + regterm = MIN ( ratio * 5, frame_dms) / frame_dms + */ + + ratio_prod = L_mult(ratio, 5); + + if (ratio_prod < frame_dms) + { + Word16 mult_factor = 0; + + SWITCH (frame_dms) /* 1 / frame_dms in Q15 */ + { + case 25: mult_factor = 1311; break; + case 50: mult_factor = 655; break; +#ifdef CR8_G_ADD_75MS + case 75: mult_factor = 437; break; +#endif + case 100: mult_factor = 328; break; + } + + /* ratio_prod < frame_dms. Hence Word16 can be used */ + + regterm = L_shl(L_mult(extract_l(ratio_prod), mult_factor), 15); /* result in Q31 */ + } + + rB_offset = L_sub(MAX_32, regterm); + /* Calculation in Q28 to prevent overflow. Subtraction result in Q31, downshift by 3 results in Q28. + Multiplication by 8 is implemented as upshift by 3. + */ + + /* + FLOAT code : reg_val = x_max * LC3_POW(2,-regBits - rB_offset); + */ + Word16 reg_val_e = x_e; + + IF(rB_offset > 0) + { + Word32 reg_exp = L_negate(L_add(L_shl(regBits, 25), L_shr(rB_offset, 3))); + reg_val = Mpy_32_32_lc3plus(x_max, BASOP_Util_InvLog2_lc3plus(reg_exp)); /* Product is in Q31 */ + /* reg_val is in Q(31-x_e) */ + } + ELSE + { + reg_val = x_max; + reg_val_e = sub(x_e, regBits); + } + + sub_val = 0x183BA045; + move16(); + /*28 * log10(32768*256 - 2) in Q21 */ + + /* + Adding LC3_POW(2, -31) to reg_val.2^-31 * 2^(31-x_e) = 2^-x_e. + If x_e is positive, this is below precision requirements to be used. + */ + + if (reg_val_e < 0) + { + reg_val = L_add_sat(reg_val, L_shl_sat(1, negate(reg_val_e))); + } + n_reg_val = norm_l(reg_val); + + FOR (i = 0; i < lg_4; i++) + { + ener = en[i]; + move16(); + s = en_exp[i]; + move16(); + + Word16 shift_val = sub(reg_val_e, s); + + IF (sub(n_reg_val, shift_val) > 0) + { + IF(shift_val > -32) + { + ener = L_add(ener, L_shl(reg_val, shift_val)); /* Match q formats */ + } + } + ELSE + { + IF (sub(shift_val, 32) >= 0 ) + { + ener = reg_val; + } + ELSE + { + ener = L_add_sat(reg_val, L_shr(ener, shift_val)); + } + s = reg_val_e; + } + + tmp32 = L_add(BASOP_Util_Log2_lc3plus(ener), L_shl_pos(L_deposit_l(s), 25)); /* log2, 6Q25 */ + tmp32 = L_add(L_shr_pos(Mpy_32_32_lc3plus(tmp32, 0x436E439A), 7), 0x4E666); /* -> (28/20)*(7+10*tmp32/log2(10)), 15Q16 */ + en[i] = tmp32; + move32(); + } + } +#endif + x_max = BASOP_Util_Log2_lc3plus(x_max); + /* Minimum gain */ + x_max = L_add(x_max, L_shl_pos(L_deposit_l(x_e), 25)); /* log2(x_max) in 6Q25 */ + x_max = L_sub( + Mpy_32_32_lc3plus(x_max, 0x436E439A), + sub_val); /* 28*log10(x_max/(32768-0.375)) = log2(x_max)*(28/log2(10))-28*log10(32768-0.375) in 10Q21 */ + /* 28/log1(10) is in Q27 + Mpy_32_32_lc3plus : Q25(x_max) + Q27 + Q1(Mpy_32_32_ss) - Q32 = Q21 */ + *quantizedGainMin = extract_l(L_shr_pos(L_add(x_max, (1 << 21) + (1 << 11)), 21)); + move16(); + ASSERT(*quantizedGainMin <= 255 + quantizedGainOff); + *quantizedGainMin = s_max(quantizedGainOff, s_min(add(255, quantizedGainOff), *quantizedGainMin)); + + offset = L_deposit_h(add(255, quantizedGainOff)); /* -> 127 */ + +#ifdef ENABLE_HR_MODE + IF(hrmode) + { + offset = L_shr_pos(offset, 2); + /* SQ scale: 4 bits / 6 dB per quadruple */ + target = L_mult(0x3EB8, nbitsSQ); /* -> (28/20) * (1.4) * nbitsSQ */ + + fac = L_add(0x400000, 0); /* -> 256 */ + /* find offset (0 to 127) */ + FOR (iter = 0; iter < 8; iter++) + { + fac = L_shr_pos(fac, 1); + offset = L_sub(offset, fac); + + ener = L_deposit_l(0); + iszero = 1; + move16(); + + FOR (i = lg_4 - 1; i >= 0; i--) + { + tmp32 = L_sub(L_shr_pos(en[i], 1), offset); + diff = L_sub(tmp32, 0x27333); /* 0x4E666 -> (28/20)*(7) in Q15 */ + if (diff < 0) + { + if (iszero == 0) + { + ener = L_add(ener, 0xF1EC); /* 0x1E3D7 -> (28/20)*(2.7) in Q15 */ + } + } + else + { + ener = L_add(ener, tmp32); + iszero = 0; + move16(); + + diff2 = L_sub(tmp32, 0x118000); /* 0x230000 -> (28/20)*(50) */ + if (diff2 >= 0) + { + ener = L_add(ener, diff2); + } + } + } + + /* if ener is above target -> increase offset */ + test(); + if (L_sub(ener, target) > 0 && iszero == 0) + { + offset = L_add(offset, fac); + } + } + tmp16 = extract_h(L_shl(offset, 2)); + } + ELSE +#endif + { + /* SQ scale: 4 bits / 6 dB per quadruple */ + target = L_shl_pos(L_mult(0x7D71, nbitsSQ), 1); /* -> (28/20) * (1.4) * nbitsSQ */ + fac = L_add(0x1000000, 0); /* -> 256 */ + + /* find offset (0 to 127) */ + FOR (iter = 0; iter < 8; iter++) + { + fac = L_shr_pos(fac, 1); + offset = L_sub(offset, fac); + + ener = L_deposit_l(0); + iszero = 1; + move16(); + FOR (i = lg_4 - 1; i >= 0; i--) + { + tmp32 = L_sub(en[i], offset); + diff = L_sub(tmp32, 0x9CCCD); /* 0x9CCCD -> (28/20)*(7) in Q16 */ + if (diff < 0) + { + if (iszero == 0) + { + ener = L_add_sat(ener, 0x3C7AE); /* 0x3C7AE -> (28/20)*(2.7) in Q16 */ + } + } + else + { + ener = L_add_sat(ener, tmp32); + iszero = 0; + move16(); + + diff2 = L_sub(tmp32, 0x460000); /* 0x460000 -> (28/20)*(50) in Q16 */ + if (diff2 >= 0) + { + ener = L_add_sat(ener, diff2); + } + } + + } + + /* if ener is above target -> increase offset */ + test(); + if (L_sub(ener, target) > 0 && iszero == 0) + { + offset = L_add(offset, fac); + } + } + tmp16 = extract_h(offset); + + } + + if (sub(tmp16, *quantizedGainMin) < 0) + { + *old_targetBits = -1; + move16(); + } + *quantizedGain = sub(s_max(*quantizedGainMin, tmp16), quantizedGainOff); + move16(); + } + +#ifdef ENABLE_HR_MODE + tmp32 = + Mpy_32_16_lc3plus(0x797CD707, L_shl_pos(add(*quantizedGain, quantizedGainOff), 6)); +#else + tmp32 = + L_shl_pos(L_mult0(add(*quantizedGain, quantizedGainOff), 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */ +#endif + *gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); /* get exponent */ +#ifdef ENABLE_HR_MODE + *gain = BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000)); +#else + *gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32,(Word32) 0xFE000000))); +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/fft/cfft.c b/lib_lc3plus/fft/cfft.c deleted file mode 100644 index d96516391..000000000 --- a/lib_lc3plus/fft/cfft.c +++ /dev/null @@ -1,427 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - - -#include "options.h" -#include "wmc_auto.h" -#include "cfft.h" -#include "iisfft.h" /* for M_PIl */ -#include /* for abs() */ -#include - -#define MAX_FFT_SIZE 1024 -#define MAX_TRIGDATA_SIZE (MAX_FFT_SIZE / 2) - -/** - * \brief table aTrigData - - Generate table: aTrigData[i] = sin( pi * i / (2*MAX_TRIGDATA_SIZE) ); i = 0, ... MAX_TRIGDATA_SIZE - */ -static const LC3_FLOAT static_table[MAX_TRIGDATA_SIZE + 1] = { - 0.0000000000e+000, 3.0679567717e-003, 6.1358846724e-003, 9.2037543654e-003, 1.2271538377e-002, 1.5339205973e-002, - 1.8406730145e-002, 2.1474080160e-002, 2.4541229010e-002, 2.7608145028e-002, 3.0674804002e-002, 3.3741172403e-002, - 3.6807224154e-002, 3.9872925729e-002, 4.2938258499e-002, 4.6003181487e-002, 4.9067676067e-002, 5.2131704986e-002, - 5.5195245892e-002, 5.8258265257e-002, 6.1320737004e-002, 6.4382627606e-002, 6.7443922162e-002, 7.0504575968e-002, - 7.3564566672e-002, 7.6623864472e-002, 7.9682439566e-002, 8.2740262151e-002, 8.5797309875e-002, 8.8853552938e-002, - 9.1908954084e-002, 9.4963498414e-002, 9.8017141223e-002, 1.0106986016e-001, 1.0412163287e-001, 1.0717242211e-001, - 1.1022220552e-001, 1.1327095330e-001, 1.1631862819e-001, 1.1936521530e-001, 1.2241067737e-001, 1.2545497715e-001, - 1.2849810719e-001, 1.3154003024e-001, 1.3458070159e-001, 1.3762012124e-001, 1.4065824449e-001, 1.4369502664e-001, - 1.4673046768e-001, 1.4976453781e-001, 1.5279719234e-001, 1.5582840145e-001, 1.5885815024e-001, 1.6188639402e-001, - 1.6491311789e-001, 1.6793829203e-001, 1.7096188664e-001, 1.7398387194e-001, 1.7700421810e-001, 1.8002289534e-001, - 1.8303988874e-001, 1.8605515361e-001, 1.8906866014e-001, 1.9208039343e-001, 1.9509032369e-001, 1.9809840620e-001, - 2.0110464096e-001, 2.0410896838e-001, 2.0711137354e-001, 2.1011184156e-001, 2.1311031282e-001, 2.1610680223e-001, - 2.1910123527e-001, 2.2209362686e-001, 2.2508391738e-001, 2.2807207704e-001, 2.3105810583e-001, 2.3404195905e-001, - 2.3702360690e-001, 2.4000301957e-001, 2.4298018217e-001, 2.4595504999e-001, 2.4892760813e-001, 2.5189781189e-001, - 2.5486564636e-001, 2.5783109665e-001, 2.6079410315e-001, 2.6375466585e-001, 2.6671275496e-001, 2.6966831088e-001, - 2.7262136340e-001, 2.7557182312e-001, 2.7851969004e-001, 2.8146493435e-001, 2.8440752625e-001, 2.8734746575e-001, - 2.9028466344e-001, 2.9321914911e-001, 2.9615089297e-001, 2.9907983541e-001, 3.0200594664e-001, 3.0492922664e-001, - 3.0784964561e-001, 3.1076714396e-001, 3.1368175149e-001, 3.1659337878e-001, 3.1950202584e-001, 3.2240769267e-001, - 3.2531028986e-001, 3.2820984721e-001, 3.3110630512e-001, 3.3399966359e-001, 3.3688986301e-001, 3.3977687359e-001, - 3.4266072512e-001, 3.4554132819e-001, 3.4841868281e-001, 3.5129275918e-001, 3.5416352749e-001, 3.5703095794e-001, - 3.5989505053e-001, 3.6275571585e-001, 3.6561298370e-001, 3.6846682429e-001, 3.7131720781e-001, 3.7416407466e-001, - 3.7700742483e-001, 3.7984719872e-001, 3.8268342614e-001, 3.8551604748e-001, 3.8834503293e-001, 3.9117038250e-001, - 3.9399203658e-001, 3.9680999517e-001, 3.9962419868e-001, 4.0243464708e-001, 4.0524131060e-001, 4.0804415941e-001, - 4.1084316373e-001, 4.1363832355e-001, 4.1642954946e-001, 4.1921690106e-001, 4.2200025916e-001, 4.2477968335e-001, - 4.2755508423e-001, 4.3032649159e-001, 4.3309381604e-001, 4.3585708737e-001, 4.3861624599e-001, 4.4137126207e-001, - 4.4412213564e-001, 4.4686883688e-001, 4.4961133599e-001, 4.5234957337e-001, 4.5508357882e-001, 4.5781329274e-001, - 4.6053871512e-001, 4.6325978637e-001, 4.6597650647e-001, 4.6868881583e-001, 4.7139674425e-001, 4.7410020232e-001, - 4.7679921985e-001, 4.7949376702e-001, 4.8218378425e-001, 4.8486924171e-001, 4.8755016923e-001, 4.9022647738e-001, - 4.9289819598e-001, 4.9556526542e-001, 4.9822765589e-001, 5.0088536739e-001, 5.0353837013e-001, 5.0618666410e-001, - 5.0883013010e-001, 5.1146882772e-001, 5.1410275698e-001, 5.1673179865e-001, 5.1935601234e-001, 5.2197527885e-001, - 5.2458965778e-001, 5.2719914913e-001, 5.2980363369e-001, 5.3240311146e-001, 5.3499764204e-001, 5.3758704662e-001, - 5.4017144442e-001, 5.4275077581e-001, 5.4532498121e-001, 5.4789406061e-001, 5.5045795441e-001, 5.5301672220e-001, - 5.5557024479e-001, 5.5811852217e-001, 5.6066155434e-001, 5.6319934130e-001, 5.6573182344e-001, 5.6825894117e-001, - 5.7078075409e-001, 5.7329714298e-001, 5.7580816746e-001, 5.7831376791e-001, 5.8081394434e-001, 5.8330863714e-001, - 5.8579784632e-001, 5.8828157187e-001, 5.9075969458e-001, 5.9323227406e-001, 5.9569931030e-001, 5.9816068411e-001, - 6.0061645508e-001, 6.0306662321e-001, 6.0551106930e-001, 6.0794979334e-001, 6.1038279533e-001, 6.1281007528e-001, - 6.1523157358e-001, 6.1764729023e-001, 6.2005722523e-001, 6.2246125937e-001, 6.2485951185e-001, 6.2725180387e-001, - 6.2963825464e-001, 6.3201874495e-001, 6.3439327478e-001, 6.3676184416e-001, 6.3912445307e-001, 6.4148104191e-001, - 6.4383155107e-001, 6.4617604017e-001, 6.4851438999e-001, 6.5084666014e-001, 6.5317285061e-001, 6.5549284220e-001, - 6.5780669451e-001, 6.6011434793e-001, 6.6241580248e-001, 6.6471099854e-001, 6.6699993610e-001, 6.6928261518e-001, - 6.7155897617e-001, 6.7382901907e-001, 6.7609268427e-001, 6.7835003138e-001, 6.8060100079e-001, 6.8284553289e-001, - 6.8508368731e-001, 6.8731534481e-001, 6.8954056501e-001, 6.9175922871e-001, 6.9397145510e-001, 6.9617712498e-001, - 6.9837623835e-001, 7.0056879520e-001, 7.0275473595e-001, 7.0493406057e-001, 7.0710676908e-001, 7.0927280188e-001, - 7.1143221855e-001, 7.1358484030e-001, 7.1573084593e-001, 7.1787005663e-001, 7.2000253201e-001, 7.2212821245e-001, - 7.2424709797e-001, 7.2635912895e-001, 7.2846436501e-001, 7.3056274652e-001, 7.3265427351e-001, 7.3473888636e-001, - 7.3681658506e-001, 7.3888731003e-001, 7.4095112085e-001, 7.4300795794e-001, 7.4505776167e-001, 7.4710059166e-001, - 7.4913638830e-001, 7.5116515160e-001, 7.5318682194e-001, 7.5520139933e-001, 7.5720882416e-001, 7.5920921564e-001, - 7.6120239496e-001, 7.6318842173e-001, 7.6516723633e-001, 7.6713889837e-001, 7.6910334826e-001, 7.7106052637e-001, - 7.7301043272e-001, 7.7495312691e-001, 7.7688848972e-001, 7.7881652117e-001, 7.8073722124e-001, 7.8265058994e-001, - 7.8455656767e-001, 7.8645521402e-001, 7.8834640980e-001, 7.9023021460e-001, 7.9210656881e-001, 7.9397547245e-001, - 7.9583692551e-001, 7.9769086838e-001, 7.9953724146e-001, 8.0137616396e-001, 8.0320751667e-001, 8.0503135920e-001, - 8.0684757233e-001, 8.0865615606e-001, 8.1045717001e-001, 8.1225061417e-001, 8.1403630972e-001, 8.1581443548e-001, - 8.1758481264e-001, 8.1934750080e-001, 8.2110249996e-001, 8.2284981012e-001, 8.2458931208e-001, 8.2632106543e-001, - 8.2804507017e-001, 8.2976120710e-001, 8.3146959543e-001, 8.3317017555e-001, 8.3486288786e-001, 8.3654773235e-001, - 8.3822470903e-001, 8.3989381790e-001, 8.4155499935e-001, 8.4320825338e-001, 8.4485358000e-001, 8.4649091959e-001, - 8.4812033176e-001, 8.4974175692e-001, 8.5135519505e-001, 8.5296058655e-001, 8.5455799103e-001, 8.5614734888e-001, - 8.5772860050e-001, 8.5930180550e-001, 8.6086696386e-001, 8.6242395639e-001, 8.6397284269e-001, 8.6551362276e-001, - 8.6704623699e-001, 8.6857068539e-001, 8.7008696795e-001, 8.7159508467e-001, 8.7309497595e-001, 8.7458664179e-001, - 8.7607008219e-001, 8.7754529715e-001, 8.7901222706e-001, 8.8047087193e-001, 8.8192129135e-001, 8.8336336613e-001, - 8.8479709625e-001, 8.8622254133e-001, 8.8763964176e-001, 8.8904833794e-001, 8.9044874907e-001, 8.9184069633e-001, - 8.9322429895e-001, 8.9459949732e-001, 8.9596623182e-001, 8.9732456207e-001, 8.9867448807e-001, 9.0001589060e-001, - 9.0134882927e-001, 9.0267330408e-001, 9.0398931503e-001, 9.0529674292e-001, 9.0659570694e-001, 9.0788608789e-001, - 9.0916800499e-001, 9.1044127941e-001, 9.1170603037e-001, 9.1296219826e-001, 9.1420978308e-001, 9.1544872522e-001, - 9.1667908430e-001, 9.1790080070e-001, 9.1911387444e-001, 9.2031830549e-001, 9.2151403427e-001, 9.2270112038e-001, - 9.2387950420e-001, 9.2504924536e-001, 9.2621022463e-001, 9.2736250162e-001, 9.2850607634e-001, 9.2964088917e-001, - 9.3076694012e-001, 9.3188428879e-001, 9.3299281597e-001, 9.3409252167e-001, 9.3518352509e-001, 9.3626564741e-001, - 9.3733900785e-001, 9.3840354681e-001, 9.3945920467e-001, 9.4050604105e-001, 9.4154405594e-001, 9.4257318974e-001, - 9.4359344244e-001, 9.4460481405e-001, 9.4560730457e-001, 9.4660091400e-001, 9.4758558273e-001, 9.4856137037e-001, - 9.4952815771e-001, 9.5048606396e-001, 9.5143502951e-001, 9.5237499475e-001, 9.5330601931e-001, 9.5422810316e-001, - 9.5514118671e-001, 9.5604526997e-001, 9.5694035292e-001, 9.5782643557e-001, 9.5870345831e-001, 9.5957154036e-001, - 9.6043050289e-001, 9.6128046513e-001, 9.6212142706e-001, 9.6295326948e-001, 9.6377605200e-001, 9.6458977461e-001, - 9.6539443731e-001, 9.6618998051e-001, 9.6697646379e-001, 9.6775382757e-001, 9.6852207184e-001, 9.6928125620e-001, - 9.7003126144e-001, 9.7077214718e-001, 9.7150391340e-001, 9.7222650051e-001, 9.7293996811e-001, 9.7364425659e-001, - 9.7433936596e-001, 9.7502535582e-001, 9.7570210695e-001, 9.7636973858e-001, 9.7702813148e-001, 9.7767734528e-001, - 9.7831737995e-001, 9.7894817591e-001, 9.7956979275e-001, 9.8018211126e-001, 9.8078525066e-001, 9.8137921095e-001, - 9.8196387291e-001, 9.8253929615e-001, 9.8310548067e-001, 9.8366242647e-001, 9.8421007395e-001, 9.8474848270e-001, - 9.8527765274e-001, 9.8579752445e-001, 9.8630809784e-001, 9.8680937290e-001, 9.8730140924e-001, 9.8778414726e-001, - 9.8825758696e-001, 9.8872166872e-001, 9.8917651176e-001, 9.8962199688e-001, 9.9005818367e-001, 9.9048507214e-001, - 9.9090266228e-001, 9.9131083488e-001, 9.9170976877e-001, 9.9209928513e-001, 9.9247956276e-001, 9.9285042286e-001, - 9.9321192503e-001, 9.9356412888e-001, 9.9390697479e-001, 9.9424046278e-001, 9.9456459284e-001, 9.9487930536e-001, - 9.9518471956e-001, 9.9548077583e-001, 9.9576741457e-001, 9.9604469538e-001, 9.9631261826e-001, 9.9657112360e-001, - 9.9682027102e-001, 9.9706006050e-001, 9.9729043245e-001, 9.9751144648e-001, 9.9772304296e-001, 9.9792528152e-001, - 9.9811810255e-001, 9.9830156565e-001, 9.9847555161e-001, 9.9864023924e-001, 9.9879544973e-001, 9.9894130230e-001, - 9.9907773733e-001, 9.9920475483e-001, 9.9932235479e-001, 9.9943059683e-001, 9.9952942133e-001, 9.9961882830e-001, - 9.9969881773e-001, 9.9976938963e-001, 9.9983060360e-001, 9.9988234043e-001, 9.9992471933e-001, 9.9995762110e-001, - 9.9998116493e-001, 9.9999529123e-001, 1.0000000000e+000}; - -/** - * \brief scramble - The function sorts the complex vector re/im of length n from 'in-order' to 'bitreversed order'. - - * \param[i/o] re: real input - * \param[i/o] im: imag input - * \param[i ] n: size of fft - * \param[i ] s: stride of real and imag input - - * \return none - */ -static void scramble(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT n, LC3_INT s) -{ - LC3_FLOAT tmp; - LC3_INT m, k, j; - - for (m = 1, j = 0; m < (n - 1); m++) { - { - for (k = n >> 1; (!((j ^= k) & k)); k >>= 1) - ; - } - - if (j > m) { - tmp = re[s * m]; - re[s * m] = re[s * j]; - re[s * j] = tmp; - - tmp = im[s * m]; - im[s * m] = im[s * j]; - im[s * j] = tmp; - } - } -} - -/** - * \brief fft - The function performs a radix-2, decimation in time complex fft. The calculation takes place inplace. - The real and imaginary part can reside in separate buffers as well as interleaved in one buffer. The - stride length has to be set accordingly. - - * \param[i/o] re: real input / real output - * \param[i/o] im: imag input / imag output - * \param[i ] sizeOfFft: size of fft - * \param[i ] s: stride of real and imag input / output - - * \return none - */ -static void fft(const LC3_FLOAT* aTrigData, LC3_INT trigdata_size, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft, - LC3_INT s) -{ - LC3_INT trigstep, i, ldm, n; - LC3_INT trigDataSize; - LC3_INT ldn = 0; - - trigDataSize = sizeOfFft / 2; - - while (sizeOfFft >>= 1) { - ldn++; - } - - n = 1 << ldn; - - scramble(re, im, n, s); - - /* 1+2 stage implemented as radix 4 */ - for (i = 0; i < n; i += 4) { - LC3_FLOAT a00, a01, a10, a11; - LC3_FLOAT a20, a21, a30, a31; - - a00 = re[s * (i + 0)] + re[s * (i + 1)]; - a10 = re[s * (i + 2)] + re[s * (i + 3)]; - a20 = im[s * (i + 0)] + im[s * (i + 1)]; - a30 = im[s * (i + 2)] + im[s * (i + 3)]; - - a01 = re[s * (i + 0)] - re[s * (i + 1)]; - a21 = re[s * (i + 2)] - re[s * (i + 3)]; - a31 = im[s * (i + 0)] - im[s * (i + 1)]; - a11 = im[s * (i + 2)] - im[s * (i + 3)]; - - re[s * (i + 0)] = a00 + a10; - re[s * (i + 2)] = a00 - a10; - im[s * (i + 0)] = a20 + a30; - im[s * (i + 2)] = a20 - a30; - re[s * (i + 1)] = a11 + a01; - re[s * (i + 3)] = a01 - a11; - im[s * (i + 1)] = a31 - a21; - im[s * (i + 3)] = a21 + a31; - } - - /* next stages implemented as radix 2 */ - for (ldm = 3; ldm <= ldn; ++ldm) { - const LC3_INT m = (1 << ldm); - const LC3_INT mh = (m >> 1); - LC3_INT j, r; - - trigstep = ((trigDataSize * 4) >> ldm) * trigdata_size / trigDataSize; - - for (j = 0; j < mh / 2; ++j) { - LC3_FLOAT c1, c2; - - c2 = aTrigData[j * trigstep]; - c1 = aTrigData[trigdata_size - j * trigstep]; - - for (r = 0; r < n; r += m) { - LC3_FLOAT vr, vi, ur, ui; - - LC3_INT t0 = r + j; - LC3_INT t1 = s * t0; - LC3_INT t2 = s * (t0 + mh); - - vr = re[t2] * c1 + im[t2] * c2; - vi = -re[t2] * c2 + im[t2] * c1; - - ur = re[t1]; - ui = im[t1]; - - re[t1] = re[t1] + vr; - im[t1] = im[t1] + vi; - - re[t2] = ur - vr; - im[t2] = ui - vi; - - t0 = r + j + mh / 2; - t1 = s * t0; - t2 = s * (t0 + mh); - - vr = -re[t2] * c2 + im[t2] * c1; - vi = -re[t2] * c1 - im[t2] * c2; - - ur = re[t1]; - ui = im[t1]; - re[t1] = re[t1] + vr; - im[t1] = im[t1] + vi; - - re[t2] = ur - vr; - im[t2] = ui - vi; - } - } - } -} - -/** - * \brief ifft - The function performs a radix-2, decimation in time complex inverse fft. The calculation takes place - inplace. The real and imaginary part can reside in separate buffers as well as interleaved in one buffer. - The stride length has to be set accordingly. - - * \param[i/o] re: real input / real output - * \param[i/o] im: imag input / imag output - * \param[i ] sizeOfFft: size of fft - * \param[i ] s: stride of real and imag input / output - - * \return none - */ -static void ifft(const LC3_FLOAT* aTrigData, LC3_INT trigdata_size, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft, - LC3_INT s) -{ - LC3_INT trigstep, i, ldm, n; - LC3_INT trigDataSize; - LC3_INT ldn = 0; - - trigDataSize = sizeOfFft; - - while (sizeOfFft >>= 1) { - ldn++; - } - - n = 1 << ldn; - - scramble(re, im, n, s); - - /* 1+2 stage radix 4 */ - for (i = 0; i < n; i += 4) { - LC3_FLOAT a00, a01, a10, a11; - LC3_FLOAT a20, a21, a30, a31; - - a00 = re[s * (i + 0)] + re[s * (i + 1)]; - a10 = re[s * (i + 2)] + re[s * (i + 3)]; - a20 = im[s * (i + 0)] + im[s * (i + 1)]; - a30 = im[s * (i + 2)] + im[s * (i + 3)]; - - a01 = re[s * (i + 0)] - re[s * (i + 1)]; - a21 = re[s * (i + 2)] - re[s * (i + 3)]; - a31 = im[s * (i + 0)] - im[s * (i + 1)]; - a11 = im[s * (i + 2)] - im[s * (i + 3)]; - - re[s * (i + 0)] = a00 + a10; - re[s * (i + 2)] = a00 - a10; - im[s * (i + 0)] = a20 + a30; - im[s * (i + 2)] = a20 - a30; - - re[s * (i + 1)] = a01 - a11; - re[s * (i + 3)] = a01 + a11; - im[s * (i + 1)] = a31 + a21; - im[s * (i + 3)] = a31 - a21; - } - - for (ldm = 3; ldm <= ldn; ++ldm) { - const LC3_INT m = (1 << ldm); - const LC3_INT mh = (m >> 1); - LC3_INT j, r; - - trigstep = ((trigDataSize * 4) >> ldm) * trigdata_size / trigDataSize; - - for (j = 0; j < mh / 2; ++j) { - LC3_FLOAT c1, c2; - - c2 = aTrigData[j * trigstep]; - c1 = aTrigData[trigdata_size - j * trigstep]; - - for (r = 0; r < n; r += m) { - LC3_FLOAT vr, vi, ur, ui; - - LC3_INT t0 = r + j; - LC3_INT t1 = s * t0; - LC3_INT t2 = s * (t0 + mh); - - vr = re[t2] * c1 - im[t2] * c2; - vi = re[t2] * c2 + im[t2] * c1; - - ur = re[t1]; - ui = im[t1]; - - re[t1] = ur + vr; - im[t1] = ui + vi; - - re[t2] = ur - vr; - im[t2] = ui - vi; - - t0 = r + j + mh / 2; - t1 = s * t0; - t2 = s * (t0 + mh); - - vr = -re[t2] * c2 - im[t2] * c1; - vi = re[t2] * c1 - im[t2] * c2; - - ur = re[t1]; - ui = im[t1]; - - re[t1] = ur + vr; - im[t1] = ui + vi; - re[t2] = ur - vr; - im[t2] = ui - vi; - } - } - } -} - -/** - * \brief cfft - The function serves as wrapper for the forward and inverse fft. - - * \param[i/o] re: real input / real output - * \param[i/o] im: imag input / imag output - * \param[i ] sizeOfFft: size of fft - * \param[i ] s: stride of real and imag input / output - * \param[i ] iSign: forward fft: -1 / inverse fft: 1 - - * \return none - */ -void LC3_cfft(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT length, LC3_INT stride, LC3_INT sign) -{ - assert(abs(sign) == 1); - assert(CFFT_SUPPORT(length)); - - if (sign == -1) { - fft(static_table, MAX_TRIGDATA_SIZE, re, im, length, stride); - } else { - ifft(static_table, MAX_TRIGDATA_SIZE, re, im, length, stride); - } -} - -LC3_INT LC3_cfft_plan(Cfft* handle, LC3_INT length, LC3_INT sign) -{ - /* check if length is power of two */ - if (!CFFT_PLAN_SUPPORT(length) || (abs(sign) != 1)) - { - return 0; - } - - handle->len = length; - handle->sign = sign; - - if (length <= MAX_FFT_SIZE) { - handle->table = NULL; - } else { - LC3_INT i = 0; - handle->table = (LC3_FLOAT*)malloc((length / 2 + 1) * sizeof(LC3_FLOAT)); - for (i = 0; i < length / 2 + 1; i++) { - handle->table[i] = (LC3_FLOAT)LC3_SIN((LC3_FLOAT)M_PIl * i / length); - } - } - return 1; -} - -void LC3_cfft_apply(Cfft* handle, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT stride) -{ - if (handle->len <= MAX_FFT_SIZE) { - LC3_cfft(re, im, handle->len, stride, handle->sign); - } else if (handle->sign == -1) { - fft(handle->table, handle->len / 2, re, im, handle->len, stride); - } else { - ifft(handle->table, handle->len / 2, re, im, handle->len, stride); - } -} - -void LC3_cfft_free(Cfft* handle) -{ - if (handle->table) - { - free(handle->table); - } -} diff --git a/lib_lc3plus/fft/cfft.h b/lib_lc3plus/fft/cfft.h deleted file mode 100644 index 18f1e80ad..000000000 --- a/lib_lc3plus/fft/cfft.h +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - - -#include "options.h" -#include "wmc_auto.h" -#include "../functions.h" - -#ifndef CFFT_H -#define CFFT_H - - -/* macro to check if cfft supports len */ -#define CFFT_IS_POWER_OF_TWO(n) ((n != 0) && ((n & (~n + 1)) == n)) -#define CFFT_SUPPORT(len) (len >= 4 && len <= 1024 && CFFT_IS_POWER_OF_TWO(len)) -#define CFFT_PLAN_SUPPORT(len) (len >= 4 && CFFT_IS_POWER_OF_TWO(len)) - -/** - * \brief fft_radix2 - The function serves as wrapper for the forward and inverse complex fft. - - * \param[i/o] re: real input / real output - * \param[i/o] im: imag input / imag output - * \param[i ] sizeOfFft: size of fft - * \param[i ] s: stride of real and imag input / output - * \param[i ] iSign: forward fft: -1 / inverse fft: 1 - - * \return none - */ - -void LC3_cfft(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft, LC3_INT stride, LC3_INT sign); - -LC3_INT LC3_cfft_plan(Cfft* handle, LC3_INT length, LC3_INT sign); -void LC3_cfft_apply(Cfft* handle, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT stride); -void LC3_cfft_free(Cfft* handle); - -#endif /* FFT_RADIX2_H */ diff --git a/lib_lc3plus/fft/fft_15_16.h b/lib_lc3plus/fft/fft_15_16.h deleted file mode 100644 index c527f1bf5..000000000 --- a/lib_lc3plus/fft/fft_15_16.h +++ /dev/null @@ -1,401 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -/* guard against unindended includes */ -#ifndef INCLUDED_FROM_IISFFT_C -#error "this file must not be included" -#endif - -static void fft15(LC3_FLOAT* vec) -{ - LC3_FLOAT r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, i0, i1, i2, i3, i4, i5, - i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, - tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, - tmp25, tmp26, tmp27, tmp28, tmp29; - - /* Pre-additions real part */ - r1 = vec[2] + vec[8]; - r2 = vec[2] - vec[8]; - r3 = vec[4] + vec[16]; - r4 = vec[4] - vec[16]; - r5 = vec[6] + vec[24]; - r6 = vec[6] - vec[24]; - r7 = vec[10] + vec[20]; - r8 = vec[10] - vec[20]; - r9 = vec[12] + vec[18]; - r10 = vec[12] - vec[18]; - r11 = vec[14] + vec[26]; - r12 = vec[14] - vec[26]; - r13 = vec[22] + vec[28]; - r14 = vec[22] - vec[28]; - - tmp2 = r1 + r3; - tmp4 = r1 - r3; - tmp6 = r2 + r14; - tmp8 = r2 - r14; - tmp10 = r4 + r12; - tmp12 = r4 - r12; - tmp14 = r5 + r9; - tmp16 = r5 - r9; - tmp18 = r11 + r13; - tmp20 = r11 - r13; - - /* Pre-additions imaginary part */ - i1 = vec[3] + vec[9]; - i2 = vec[3] - vec[9]; - i3 = vec[5] + vec[17]; - i4 = vec[5] - vec[17]; - i5 = vec[7] + vec[25]; - i6 = vec[7] - vec[25]; - i7 = vec[11] + vec[21]; - i8 = vec[11] - vec[21]; - i9 = vec[13] + vec[19]; - i10 = vec[13] - vec[19]; - i11 = vec[15] + vec[27]; - i12 = vec[15] - vec[27]; - i13 = vec[23] + vec[29]; - i14 = vec[23] - vec[29]; - - tmp3 = i1 + i3; - tmp5 = i1 - i3; - tmp7 = i2 + i14; - tmp9 = i2 - i14; - tmp11 = i4 + i12; - tmp13 = i4 - i12; - tmp15 = i5 + i9; - tmp17 = i5 - i9; - tmp19 = i11 + i13; - tmp21 = i11 - i13; - - /* Pre-additions and core multiplications */ - tmp28 = tmp4 + tmp20; - tmp29 = tmp5 + tmp21; - r4 = tmp2 + tmp18; - i4 = tmp3 + tmp19; - r3 = (r4 + tmp14) * (LC3_FLOAT)-1.25; - i3 = (i4 + tmp15) * (LC3_FLOAT)-1.25; - r2 = (tmp29 - i8) * (LC3_FLOAT)-8.660254037844387e-1; - i2 = (tmp28 - r8) * (LC3_FLOAT)8.660254037844387e-1; - r1 = r4 + r7; - i1 = i4 + i7; - r0 = r1 + vec[0] + tmp14; - i0 = i1 + vec[1] + tmp15; - r7 = tmp4 - tmp20; - i7 = tmp5 - tmp21; - r8 = (tmp3 - tmp19) * (LC3_FLOAT)-4.841229182759272e-1; - i8 = (tmp2 - tmp18) * (LC3_FLOAT)4.841229182759272e-1; - tmp0 = tmp6 + r10; - tmp1 = tmp7 + i10; - tmp2 = r6 - tmp10; - tmp3 = i6 - tmp11; - r10 = tmp7 * (LC3_FLOAT)-2.308262652881440; - i10 = tmp6 * (LC3_FLOAT)2.308262652881440; - r11 = tmp8 * (LC3_FLOAT)1.332676064001459; - i11 = tmp9 * (LC3_FLOAT)1.332676064001459; - r6 = (r7 - tmp16) * (LC3_FLOAT)5.590169943749475e-1; - i6 = (i7 - tmp17) * (LC3_FLOAT)5.590169943749475e-1; - r12 = (tmp1 + tmp3) * (LC3_FLOAT)5.877852522924733e-1; - i12 = (tmp0 + tmp2) * (LC3_FLOAT)-5.877852522924733e-1; - r13 = (tmp7 - tmp11) * (LC3_FLOAT)-8.816778784387098e-1; - i13 = (tmp6 - tmp10) * (LC3_FLOAT)8.816778784387098e-1; - r14 = (tmp8 + tmp12) * (LC3_FLOAT)5.090369604551274e-1; - i14 = (tmp9 + tmp13) * (LC3_FLOAT)5.090369604551274e-1; - r16 = tmp11 * (LC3_FLOAT)5.449068960040204e-1; - i16 = tmp10 * (LC3_FLOAT)-5.449068960040204e-1; - r17 = tmp12 * (LC3_FLOAT)3.146021430912046e-1; - i17 = tmp13 * (LC3_FLOAT)3.146021430912046e-1; - - r4 *= (LC3_FLOAT)1.875; - i4 *= (LC3_FLOAT)1.875; - r1 *= (LC3_FLOAT)-1.5; - i1 *= (LC3_FLOAT)-1.5; - r7 *= (LC3_FLOAT)-8.385254915624212e-1; - i7 *= (LC3_FLOAT)-8.385254915624212e-1; - r5 = tmp29 * (LC3_FLOAT)1.082531754730548; - i5 = tmp28 * (LC3_FLOAT)-1.082531754730548; - r9 = tmp1 * (LC3_FLOAT)1.538841768587627; - i9 = tmp0 * (LC3_FLOAT)-1.538841768587627; - r15 = tmp3 * (LC3_FLOAT)3.632712640026803e-1; - i15 = tmp2 * (LC3_FLOAT)-3.632712640026803e-1; - - /* Post-additions real part */ - tmp2 = r0 + r1; - tmp4 = r3 + r6; - tmp6 = r3 - r6; - tmp8 = r4 + r5; - tmp10 = r4 - r5; - tmp12 = r7 + r8; - tmp14 = r7 - r8; - tmp16 = r13 + r16; - tmp18 = r14 + r17; - tmp20 = r10 - r13; - tmp22 = r11 - r14; - tmp24 = r12 + r15; - tmp26 = r12 - r9; - - r1 = tmp2 + r2; - r2 = tmp2 - r2; - r3 = tmp4 + tmp26; - r4 = tmp4 - tmp26; - r5 = tmp6 + tmp24; - r6 = tmp6 - tmp24; - r7 = tmp16 + tmp18; - r8 = tmp16 - tmp18; - r9 = tmp20 - tmp22; - r10 = tmp20 + tmp22; - r11 = r1 + tmp8; - r12 = r2 + tmp10; - r13 = r11 - tmp12; - r14 = r12 - tmp14; - r15 = r12 + tmp14; - r16 = r11 + tmp12; - - /* Post-additions imaginary part */ - tmp3 = i0 + i1; - tmp5 = i3 + i6; - tmp7 = i3 - i6; - tmp9 = i4 + i5; - tmp11 = i4 - i5; - tmp13 = i7 + i8; - tmp15 = i7 - i8; - tmp17 = i13 + i16; - tmp19 = i14 + i17; - tmp21 = i10 - i13; - tmp23 = i11 - i14; - tmp25 = i12 + i15; - tmp27 = i12 - i9; - - i1 = tmp3 + i2; - i2 = tmp3 - i2; - i3 = tmp5 + tmp27; - i4 = tmp5 - tmp27; - i5 = tmp7 + tmp25; - i6 = tmp7 - tmp25; - i7 = tmp17 + tmp19; - i8 = tmp17 - tmp19; - i9 = tmp21 - tmp23; - i10 = tmp21 + tmp23; - i11 = i1 + tmp9; - i12 = i2 + tmp11; - i13 = i11 - tmp13; - i14 = i12 - tmp15; - i15 = i12 + tmp15; - i16 = i11 + tmp13; - - *vec++ = r0; - *vec++ = i0; - *vec++ = r13 + r5 + r7; - *vec++ = i13 + i5 + i7; - *vec++ = r15 + r3 - r9; - *vec++ = i15 + i3 - i9; - *vec++ = r0 + r4; - *vec++ = i0 + i4; - *vec++ = r13 + r6 - r7; - *vec++ = i13 + i6 - i7; - *vec++ = r2; - *vec++ = i2; - *vec++ = r0 + r5; - *vec++ = i0 + i5; - *vec++ = r16 + r3 - r10; - *vec++ = i16 + i3 - i10; - *vec++ = r15 + r4 + r9; - *vec++ = i15 + i4 + i9; - *vec++ = r0 + r6; - *vec++ = i0 + i6; - *vec++ = r1; - *vec++ = i1; - *vec++ = r14 + r5 + r8; - *vec++ = i14 + i5 + i8; - *vec++ = r0 + r3; - *vec++ = i0 + i3; - *vec++ = r16 + r4 + r10; - *vec++ = i16 + i4 + i10; - *vec++ = r14 + r6 - r8; - *vec++ = i14 + i6 - i8; -} - -static void fft16(LC3_FLOAT* vec) -{ - const LC3_FLOAT INV_SQRT2 = 7.071067811865475e-1; - const LC3_FLOAT COS_PI_DIV8 = 9.238795325112867e-1; - const LC3_FLOAT COS_3PI_DIV8 = 3.826834323650898e-1; - const LC3_FLOAT SQRT2PLUS1 = 2.414213562373095; - const LC3_FLOAT SQRT2MINUS1 = 4.142135623730952e-1; - - LC3_FLOAT temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp110, temp111, temp112, - temp113, temp114, temp115, temp20, temp21, temp22, temp23, temp24, temp25, temp26, temp27, temp28, temp29, - temp210, temp211, temp212, temp213, temp214, temp215, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, - vec9, vec10, vec11, vec12, vec13, vec14, vec15; - - /* even */ - vec0 = vec[0] + vec[16]; - vec1 = vec[1] + vec[17]; - vec2 = vec[2] + vec[18]; - vec3 = vec[3] + vec[19]; - vec4 = vec[4] + vec[20]; - vec5 = vec[5] + vec[21]; - vec6 = vec[6] + vec[22]; - vec7 = vec[7] + vec[23]; - vec8 = vec[8] + vec[24]; - vec9 = vec[9] + vec[25]; - vec10 = vec[10] + vec[26]; - vec11 = vec[11] + vec[27]; - vec12 = vec[12] + vec[28]; - vec13 = vec[13] + vec[29]; - vec14 = vec[14] + vec[30]; - vec15 = vec[15] + vec[31]; - - /* Pre-additions */ - temp10 = vec0 + vec8; - temp12 = vec0 - vec8; - temp11 = vec1 + vec9; - temp13 = vec1 - vec9; - temp14 = vec2 + vec10; - temp16 = vec2 - vec10; - temp15 = vec3 + vec11; - temp17 = vec3 - vec11; - temp18 = vec4 + vec12; - temp110 = vec4 - vec12; - temp19 = vec5 + vec13; - temp111 = vec5 - vec13; - temp112 = vec6 + vec14; - temp114 = vec6 - vec14; - temp113 = vec7 + vec15; - temp115 = vec7 - vec15; - - /* Pre-additions and core multiplications */ - temp20 = temp10 + temp18; - temp24 = temp10 - temp18; - temp21 = temp11 + temp19; - temp25 = temp11 - temp19; - temp28 = temp12 - temp111; - temp210 = temp12 + temp111; - temp29 = temp13 + temp110; - temp211 = temp13 - temp110; - temp22 = temp14 + temp112; - temp27 = temp14 - temp112; - temp23 = temp15 + temp113; - temp26 = temp113 - temp15; - - temp11 = temp16 + temp114; - temp12 = temp16 - temp114; - temp10 = temp17 + temp115; - temp13 = temp17 - temp115; - temp212 = (temp10 + temp12) * INV_SQRT2; - temp214 = (temp10 - temp12) * INV_SQRT2; - temp213 = (temp13 - temp11) * INV_SQRT2; - temp215 = (temp11 + temp13) * -INV_SQRT2; - - /* odd */ - vec0 = vec[0] - vec[16]; - vec1 = vec[1] - vec[17]; - vec2 = vec[2] - vec[18]; - vec3 = vec[3] - vec[19]; - vec4 = vec[4] - vec[20]; - vec5 = vec[5] - vec[21]; - vec6 = vec[6] - vec[22]; - vec7 = vec[7] - vec[23]; - vec8 = vec[8] - vec[24]; - vec9 = vec[9] - vec[25]; - vec10 = vec[10] - vec[26]; - vec11 = vec[11] - vec[27]; - vec12 = vec[12] - vec[28]; - vec13 = vec[13] - vec[29]; - vec14 = vec[14] - vec[30]; - vec15 = vec[15] - vec[31]; - - /* Pre-additions and core multiplications */ - temp19 = (vec2 + vec14) * -COS_3PI_DIV8; - temp110 = (vec2 - vec14) * COS_PI_DIV8; - temp18 = (vec3 + vec15) * COS_3PI_DIV8; - temp111 = (vec3 - vec15) * COS_PI_DIV8; - temp15 = (vec4 + vec12) * -INV_SQRT2; - temp16 = (vec4 - vec12) * INV_SQRT2; - temp14 = (vec5 + vec13) * INV_SQRT2; - temp17 = (vec5 - vec13) * INV_SQRT2; - temp113 = (vec6 + vec10) * -COS_PI_DIV8; - temp114 = (vec6 - vec10) * COS_3PI_DIV8; - temp112 = (vec7 + vec11) * COS_PI_DIV8; - temp115 = (vec7 - vec11) * COS_3PI_DIV8; - - /* Core multiplications */ - vec2 = temp18 * SQRT2PLUS1 - temp112 * SQRT2MINUS1; - vec3 = temp19 * SQRT2PLUS1 - temp113 * SQRT2MINUS1; - vec4 = temp110 * SQRT2MINUS1 - temp114 * SQRT2PLUS1; - vec5 = temp111 * SQRT2MINUS1 - temp115 * SQRT2PLUS1; - - /* Post-additions */ - temp18 += temp112; - temp19 += temp113; - temp110 += temp114; - temp111 += temp115; - vec6 = vec0 + temp14; - vec10 = vec0 - temp14; - vec7 = vec1 + temp15; - vec11 = vec1 - temp15; - - vec12 = temp16 - vec9; - vec14 = temp16 + vec9; - vec13 = vec8 + temp17; - vec15 = vec8 - temp17; - - temp10 = vec6 - vec14; - temp12 = vec6 + vec14; - temp11 = vec7 + vec15; - temp13 = vec7 - vec15; - temp14 = vec10 + vec12; - temp16 = vec10 - vec12; - temp15 = vec11 + vec13; - temp17 = vec11 - vec13; - - vec10 = temp18 + temp110; - temp110 = temp18 - temp110; - vec11 = temp19 + temp111; - temp111 = temp19 - temp111; - - temp112 = vec2 + vec4; - temp114 = vec2 - vec4; - temp113 = vec3 + vec5; - temp115 = vec3 - vec5; - - /* Post-additions */ - *vec++ = temp20 + temp22; - *vec++ = temp21 + temp23; - *vec++ = temp12 + vec10; - *vec++ = temp13 + vec11; - *vec++ = temp210 + temp212; - *vec++ = temp211 + temp213; - *vec++ = temp10 + temp112; - *vec++ = temp11 + temp113; - *vec++ = temp24 - temp26; - *vec++ = temp25 - temp27; - *vec++ = temp16 + temp114; - *vec++ = temp17 + temp115; - *vec++ = temp28 + temp214; - *vec++ = temp29 + temp215; - *vec++ = temp14 + temp110; - *vec++ = temp15 + temp111; - *vec++ = temp20 - temp22; - *vec++ = temp21 - temp23; - *vec++ = temp12 - vec10; - *vec++ = temp13 - vec11; - *vec++ = temp210 - temp212; - *vec++ = temp211 - temp213; - *vec++ = temp10 - temp112; - *vec++ = temp11 - temp113; - *vec++ = temp24 + temp26; - *vec++ = temp25 + temp27; - *vec++ = temp16 - temp114; - *vec++ = temp17 - temp115; - *vec++ = temp28 - temp214; - *vec++ = temp29 - temp215; - *vec++ = temp14 - temp110; - *vec++ = temp15 - temp111; -} diff --git a/lib_lc3plus/fft/fft_240_480.h b/lib_lc3plus/fft/fft_240_480.h deleted file mode 100644 index 18a0c8707..000000000 --- a/lib_lc3plus/fft/fft_240_480.h +++ /dev/null @@ -1,185 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -/* guard against unindended includes */ -#ifndef INCLUDED_FROM_IISFFT_C -#error "this file must not be included" -#endif - -static void fft240(LC3_FLOAT* in) -{ - const LC3_INT table1[240] = { - 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 225, 1, 17, 33, 49, 65, 81, - 97, 113, 129, 145, 161, 177, 193, 209, 210, 226, 2, 18, 34, 50, 66, 82, 98, 114, 130, 146, 162, 178, - 194, 195, 211, 227, 3, 19, 35, 51, 67, 83, 99, 115, 131, 147, 163, 179, 180, 196, 212, 228, 4, 20, - 36, 52, 68, 84, 100, 116, 132, 148, 164, 165, 181, 197, 213, 229, 5, 21, 37, 53, 69, 85, 101, 117, - 133, 149, 150, 166, 182, 198, 214, 230, 6, 22, 38, 54, 70, 86, 102, 118, 134, 135, 151, 167, 183, 199, - 215, 231, 7, 23, 39, 55, 71, 87, 103, 119, 120, 136, 152, 168, 184, 200, 216, 232, 8, 24, 40, 56, - 72, 88, 104, 105, 121, 137, 153, 169, 185, 201, 217, 233, 9, 25, 41, 57, 73, 89, 90, 106, 122, 138, - 154, 170, 186, 202, 218, 234, 10, 26, 42, 58, 74, 75, 91, 107, 123, 139, 155, 171, 187, 203, 219, 235, - 11, 27, 43, 59, 60, 76, 92, 108, 124, 140, 156, 172, 188, 204, 220, 236, 12, 28, 44, 45, 61, 77, - 93, 109, 125, 141, 157, 173, 189, 205, 221, 237, 13, 29, 30, 46, 62, 78, 94, 110, 126, 142, 158, 174, - 190, 206, 222, 238, 14, 15, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 239}; - const LC3_INT table2[240] = { - 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 15, 31, 47, 63, 79, 95, 111, - 127, 143, 159, 175, 191, 207, 223, 239, 30, 46, 62, 78, 94, 110, 126, 142, 158, 174, 190, 206, 222, 238, - 14, 45, 61, 77, 93, 109, 125, 141, 157, 173, 189, 205, 221, 237, 13, 29, 60, 76, 92, 108, 124, 140, - 156, 172, 188, 204, 220, 236, 12, 28, 44, 75, 91, 107, 123, 139, 155, 171, 187, 203, 219, 235, 11, 27, - 43, 59, 90, 106, 122, 138, 154, 170, 186, 202, 218, 234, 10, 26, 42, 58, 74, 105, 121, 137, 153, 169, - 185, 201, 217, 233, 9, 25, 41, 57, 73, 89, 120, 136, 152, 168, 184, 200, 216, 232, 8, 24, 40, 56, - 72, 88, 104, 135, 151, 167, 183, 199, 215, 231, 7, 23, 39, 55, 71, 87, 103, 119, 150, 166, 182, 198, - 214, 230, 6, 22, 38, 54, 70, 86, 102, 118, 134, 165, 181, 197, 213, 229, 5, 21, 37, 53, 69, 85, - 101, 117, 133, 149, 180, 196, 212, 228, 4, 20, 36, 52, 68, 84, 100, 116, 132, 148, 164, 195, 211, 227, - 3, 19, 35, 51, 67, 83, 99, 115, 131, 147, 163, 179, 210, 226, 2, 18, 34, 50, 66, 82, 98, 114, - 130, 146, 162, 178, 194, 225, 1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209}; - - const LC3_INT L = 240; - const LC3_INT A = 15; - const LC3_INT B = 16; - const LC3_INT* idx1 = table1; - const LC3_INT* idx2 = table2; - - LC3_INT k, l; - LC3_FLOAT temp[32], out[480]; - - for (k = 0; k < A; k++) { - for (l = 0; l < B; l++) { - temp[2 * l] = in[2 * *idx1]; - temp[2 * l + 1] = in[2 * *idx1 + 1]; - idx1 += A; - } - - fft16(temp); /* 16-point FFT */ - idx1 -= L; - - for (l = 0; l < B; l++) { - in[2 * *idx1] = temp[2 * l]; - in[2 * *idx1 + 1] = temp[2 * l + 1]; - idx1 += A; - } - - idx1 -= L - 1; - } - - idx1 -= A; - - for (k = 0; k < B; k++) { - for (l = 0; l < A; l++) { - temp[2 * l] = in[2 * *idx1]; - temp[2 * l + 1] = in[2 * *idx1++ + 1]; - } - - fft15(temp); /* 15-point FFT */ - - for (l = 0; l < A; l++) { - out[2 * *idx2] = temp[2 * l]; - out[2 * *idx2++ + 1] = temp[2 * l + 1]; - } - } - - memmove(in, out, 2 * L * sizeof(LC3_FLOAT)); -} - -/* description in iis_fft.h */ -static void fft480(LC3_FLOAT* in) -{ - const LC3_INT table1[480] = { - 0, 256, 32, 288, 64, 320, 96, 352, 128, 384, 160, 416, 192, 448, 224, 225, 1, 257, 33, 289, 65, 321, - 97, 353, 129, 385, 161, 417, 193, 449, 450, 226, 2, 258, 34, 290, 66, 322, 98, 354, 130, 386, 162, 418, - 194, 195, 451, 227, 3, 259, 35, 291, 67, 323, 99, 355, 131, 387, 163, 419, 420, 196, 452, 228, 4, 260, - 36, 292, 68, 324, 100, 356, 132, 388, 164, 165, 421, 197, 453, 229, 5, 261, 37, 293, 69, 325, 101, 357, - 133, 389, 390, 166, 422, 198, 454, 230, 6, 262, 38, 294, 70, 326, 102, 358, 134, 135, 391, 167, 423, 199, - 455, 231, 7, 263, 39, 295, 71, 327, 103, 359, 360, 136, 392, 168, 424, 200, 456, 232, 8, 264, 40, 296, - 72, 328, 104, 105, 361, 137, 393, 169, 425, 201, 457, 233, 9, 265, 41, 297, 73, 329, 330, 106, 362, 138, - 394, 170, 426, 202, 458, 234, 10, 266, 42, 298, 74, 75, 331, 107, 363, 139, 395, 171, 427, 203, 459, 235, - 11, 267, 43, 299, 300, 76, 332, 108, 364, 140, 396, 172, 428, 204, 460, 236, 12, 268, 44, 45, 301, 77, - 333, 109, 365, 141, 397, 173, 429, 205, 461, 237, 13, 269, 270, 46, 302, 78, 334, 110, 366, 142, 398, 174, - 430, 206, 462, 238, 14, 15, 271, 47, 303, 79, 335, 111, 367, 143, 399, 175, 431, 207, 463, 239, 240, 16, - 272, 48, 304, 80, 336, 112, 368, 144, 400, 176, 432, 208, 464, 465, 241, 17, 273, 49, 305, 81, 337, 113, - 369, 145, 401, 177, 433, 209, 210, 466, 242, 18, 274, 50, 306, 82, 338, 114, 370, 146, 402, 178, 434, 435, - 211, 467, 243, 19, 275, 51, 307, 83, 339, 115, 371, 147, 403, 179, 180, 436, 212, 468, 244, 20, 276, 52, - 308, 84, 340, 116, 372, 148, 404, 405, 181, 437, 213, 469, 245, 21, 277, 53, 309, 85, 341, 117, 373, 149, - 150, 406, 182, 438, 214, 470, 246, 22, 278, 54, 310, 86, 342, 118, 374, 375, 151, 407, 183, 439, 215, 471, - 247, 23, 279, 55, 311, 87, 343, 119, 120, 376, 152, 408, 184, 440, 216, 472, 248, 24, 280, 56, 312, 88, - 344, 345, 121, 377, 153, 409, 185, 441, 217, 473, 249, 25, 281, 57, 313, 89, 90, 346, 122, 378, 154, 410, - 186, 442, 218, 474, 250, 26, 282, 58, 314, 315, 91, 347, 123, 379, 155, 411, 187, 443, 219, 475, 251, 27, - 283, 59, 60, 316, 92, 348, 124, 380, 156, 412, 188, 444, 220, 476, 252, 28, 284, 285, 61, 317, 93, 349, - 125, 381, 157, 413, 189, 445, 221, 477, 253, 29, 30, 286, 62, 318, 94, 350, 126, 382, 158, 414, 190, 446, - 222, 478, 254, 255, 31, 287, 63, 319, 95, 351, 127, 383, 159, 415, 191, 447, 223, 479}; - const LC3_INT table2[480] = { - 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 15, 47, 79, 111, 143, 175, 207, - 239, 271, 303, 335, 367, 399, 431, 463, 30, 62, 94, 126, 158, 190, 222, 254, 286, 318, 350, 382, 414, 446, - 478, 45, 77, 109, 141, 173, 205, 237, 269, 301, 333, 365, 397, 429, 461, 13, 60, 92, 124, 156, 188, 220, - 252, 284, 316, 348, 380, 412, 444, 476, 28, 75, 107, 139, 171, 203, 235, 267, 299, 331, 363, 395, 427, 459, - 11, 43, 90, 122, 154, 186, 218, 250, 282, 314, 346, 378, 410, 442, 474, 26, 58, 105, 137, 169, 201, 233, - 265, 297, 329, 361, 393, 425, 457, 9, 41, 73, 120, 152, 184, 216, 248, 280, 312, 344, 376, 408, 440, 472, - 24, 56, 88, 135, 167, 199, 231, 263, 295, 327, 359, 391, 423, 455, 7, 39, 71, 103, 150, 182, 214, 246, - 278, 310, 342, 374, 406, 438, 470, 22, 54, 86, 118, 165, 197, 229, 261, 293, 325, 357, 389, 421, 453, 5, - 37, 69, 101, 133, 180, 212, 244, 276, 308, 340, 372, 404, 436, 468, 20, 52, 84, 116, 148, 195, 227, 259, - 291, 323, 355, 387, 419, 451, 3, 35, 67, 99, 131, 163, 210, 242, 274, 306, 338, 370, 402, 434, 466, 18, - 50, 82, 114, 146, 178, 225, 257, 289, 321, 353, 385, 417, 449, 1, 33, 65, 97, 129, 161, 193, 240, 272, - 304, 336, 368, 400, 432, 464, 16, 48, 80, 112, 144, 176, 208, 255, 287, 319, 351, 383, 415, 447, 479, 31, - 63, 95, 127, 159, 191, 223, 270, 302, 334, 366, 398, 430, 462, 14, 46, 78, 110, 142, 174, 206, 238, 285, - 317, 349, 381, 413, 445, 477, 29, 61, 93, 125, 157, 189, 221, 253, 300, 332, 364, 396, 428, 460, 12, 44, - 76, 108, 140, 172, 204, 236, 268, 315, 347, 379, 411, 443, 475, 27, 59, 91, 123, 155, 187, 219, 251, 283, - 330, 362, 394, 426, 458, 10, 42, 74, 106, 138, 170, 202, 234, 266, 298, 345, 377, 409, 441, 473, 25, 57, - 89, 121, 153, 185, 217, 249, 281, 313, 360, 392, 424, 456, 8, 40, 72, 104, 136, 168, 200, 232, 264, 296, - 328, 375, 407, 439, 471, 23, 55, 87, 119, 151, 183, 215, 247, 279, 311, 343, 390, 422, 454, 6, 38, 70, - 102, 134, 166, 198, 230, 262, 294, 326, 358, 405, 437, 469, 21, 53, 85, 117, 149, 181, 213, 245, 277, 309, - 341, 373, 420, 452, 4, 36, 68, 100, 132, 164, 196, 228, 260, 292, 324, 356, 388, 435, 467, 19, 51, 83, - 115, 147, 179, 211, 243, 275, 307, 339, 371, 403, 450, 2, 34, 66, 98, 130, 162, 194, 226, 258, 290, 322, - 354, 386, 418, 465, 17, 49, 81, 113, 145, 177, 209, 241, 273, 305, 337, 369, 401, 433}; - - const LC3_INT L = 480; - const LC3_INT A = 15; - const LC3_INT B = 32; - const LC3_INT* idx1 = table1; - const LC3_INT* idx2 = table2; - - LC3_INT k, l; - LC3_FLOAT temp[64], out[960]; - - for (k = 0; k < A; k++) { - for (l = 0; l < B; l++) { - temp[2 * l] = in[2 * *idx1]; - temp[2 * l + 1] = in[2 * *idx1 + 1]; - idx1 += A; - } - - fft32(temp); /* 32-point FFT */ - idx1 -= L; - - for (l = 0; l < B; l++) { - in[2 * *idx1] = temp[2 * l]; - in[2 * *idx1 + 1] = temp[2 * l + 1]; - idx1 += A; - } - - idx1 -= L - 1; - } - - idx1 -= A; - - for (k = 0; k < B; k++) { - for (l = 0; l < A; l++) { - temp[2 * l] = in[2 * *idx1]; - temp[2 * l + 1] = in[2 * *idx1++ + 1]; - } - - fft15(temp); /* 15-point FFT */ - - for (l = 0; l < A; l++) { - out[2 * *idx2] = temp[2 * l]; - out[2 * *idx2++ + 1] = temp[2 * l + 1]; - } - } - - memmove(in, out, 2 * L * sizeof(LC3_FLOAT)); -} diff --git a/lib_lc3plus/fft/fft_2_9.h b/lib_lc3plus/fft/fft_2_9.h deleted file mode 100644 index 55fe84f3b..000000000 --- a/lib_lc3plus/fft/fft_2_9.h +++ /dev/null @@ -1,278 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -/* guard against unindended includes */ -#ifndef INCLUDED_FROM_IISFFT_C -#error "this file must not be included" -#endif - -static __inline void butterfly(const LC3_FLOAT a, const LC3_FLOAT b, LC3_FLOAT* aPlusb, LC3_FLOAT* aMinusb) -{ - *aPlusb = a + b; - *aMinusb = a - b; -} - -static void fft2(LC3_FLOAT* vec) -{ - /* - 1.0000 1.0000 - 1.0000 -1.0000 - */ - LC3_FLOAT re1 = vec[0]; - LC3_FLOAT im1 = vec[1]; - LC3_FLOAT re2 = vec[2]; - LC3_FLOAT im2 = vec[3]; - - vec[0] = re1 + re2; - vec[1] = im1 + im2; - vec[2] = re1 - re2; - vec[3] = im1 - im2; -} - -static void fft3(LC3_FLOAT* vec) -{ - const LC3_FLOAT C31 = 0.5; /* cos(PI/3); sin(2*PI/3) */ - const LC3_FLOAT C32 = 0.866025403784439; /* cos(PI/3); sin(2*PI/3) */ - - LC3_FLOAT re1 = vec[0]; - LC3_FLOAT im1 = vec[1]; - LC3_FLOAT re2 = vec[2]; - LC3_FLOAT im2 = vec[3]; - LC3_FLOAT re3 = vec[4]; - LC3_FLOAT im3 = vec[5]; - /* - 1.0000 1.0000 1.0000 - C31 C32 - 1.0000 -0.5000 - 0.8660i -0.5000 + 0.8660i - 1.0000 -0.5000 + 0.8660i -0.5000 - 0.8660i - */ - LC3_FLOAT tmp1 = re2 + re3; - LC3_FLOAT tmp3 = im2 + im3; - LC3_FLOAT tmp2 = re2 - re3; - LC3_FLOAT tmp4 = im2 - im3; - - vec[0] = re1 + tmp1; - vec[1] = im1 + tmp3; - vec[2] = re1 - C31 * tmp1 + C32 * tmp4; - vec[4] = re1 - C31 * tmp1 - C32 * tmp4; - vec[3] = im1 - C32 * tmp2 - C31 * tmp3; - vec[5] = im1 + C32 * tmp2 - C31 * tmp3; -} - -static void fft4(LC3_FLOAT* vec) -{ - LC3_FLOAT temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; - - /* Pre-additions */ - temp0 = vec[0] + vec[4]; - temp2 = vec[0] - vec[4]; - temp1 = vec[1] + vec[5]; - temp3 = vec[1] - vec[5]; - temp4 = vec[2] + vec[6]; - temp7 = vec[2] - vec[6]; - temp5 = vec[7] + vec[3]; - temp6 = vec[7] - vec[3]; - - /* Post-additions */ - vec[0] = temp0 + temp4; - vec[1] = temp1 + temp5; - vec[2] = temp2 - temp6; - vec[3] = temp3 - temp7; - vec[4] = temp0 - temp4; - vec[5] = temp1 - temp5; - vec[6] = temp2 + temp6; - vec[7] = temp3 + temp7; -} - -static void fft5(LC3_FLOAT* vec) -{ - const LC3_FLOAT C51 = 0.309016994374947; /* cos(2*PI/5); */ - const LC3_FLOAT C52 = 0.951056516295154; /* sin(2*PI/5); */ - const LC3_FLOAT C53 = 0.809016994374947; /* cos( PI/5); */ - const LC3_FLOAT C54 = 0.587785252292473; /* sin( PI/5); */ - - LC3_FLOAT re1, im1, re2, im2, re3, im3, re4, im4, re5, im5, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; - - re1 = vec[0]; - im1 = vec[1]; - re2 = vec[2]; - im2 = vec[3]; - re3 = vec[4]; - im3 = vec[5]; - re4 = vec[6]; - im4 = vec[7]; - re5 = vec[8]; - im5 = vec[9]; - /* - 1.0000 1.0000 1.0000 1.0000 1.0000 - C51 C52 C53 C54 - 1.0000 0.3090 - 0.9511i -0.8090 - 0.5878i -0.8090 + 0.5878i 0.3090 + 0.9511i - 1.0000 -0.8090 - 0.5878i 0.3090 + 0.9511i 0.3090 - 0.9511i -0.8090 + 0.5878i - 1.0000 -0.8090 + 0.5878i 0.3090 - 0.9511i 0.3090 + 0.9511i -0.8090 - 0.5878i - 1.0000 0.3090 + 0.9511i -0.8090 + 0.5878i -0.8090 - 0.5878i 0.3090 - 0.9511i - */ - tmp1 = re2 + re5; - tmp2 = re2 - re5; - tmp3 = im2 + im5; - tmp4 = im2 - im5; - tmp5 = re3 + re4; - tmp6 = re3 - re4; - tmp7 = im3 + im4; - tmp8 = im3 - im4; - - vec[0] = re1 + tmp1 + tmp5; - vec[1] = im1 + tmp3 + tmp7; - vec[2] = re1 + C51 * tmp1 - C53 * tmp5 + C52 * tmp4 + C54 * tmp8; - vec[8] = re1 + C51 * tmp1 - C53 * tmp5 - C52 * tmp4 - C54 * tmp8; - vec[3] = im1 - C52 * tmp2 - C54 * tmp6 + C51 * tmp3 - C53 * tmp7; - vec[9] = im1 + C52 * tmp2 + C54 * tmp6 + C51 * tmp3 - C53 * tmp7; - vec[4] = re1 - C53 * tmp1 + C51 * tmp5 + C54 * tmp4 - C52 * tmp8; - vec[6] = re1 - C53 * tmp1 + C51 * tmp5 - C54 * tmp4 + C52 * tmp8; - vec[5] = im1 - C54 * tmp2 + C52 * tmp6 - C53 * tmp3 + C51 * tmp7; - vec[7] = im1 + C54 * tmp2 - C52 * tmp6 - C53 * tmp3 + C51 * tmp7; -} - - - -static void fft8(LC3_FLOAT* vec) -{ - const LC3_FLOAT INV_SQRT2 = 7.071067811865475e-1; - LC3_FLOAT temp1[16], temp2[16]; - - /* Pre-additions */ - temp1[0] = vec[0] + vec[8]; - temp1[2] = vec[0] - vec[8]; - temp1[1] = vec[1] + vec[9]; - temp1[3] = vec[1] - vec[9]; - temp1[4] = vec[2] + vec[10]; - temp1[6] = vec[2] - vec[10]; - temp1[5] = vec[3] + vec[11]; - temp1[7] = vec[3] - vec[11]; - temp1[8] = vec[4] + vec[12]; - temp1[10] = vec[4] - vec[12]; - temp1[9] = vec[5] + vec[13]; - temp1[11] = vec[5] - vec[13]; - temp1[12] = vec[6] + vec[14]; - temp1[14] = vec[6] - vec[14]; - temp1[13] = vec[7] + vec[15]; - temp1[15] = vec[7] - vec[15]; - - /* Pre-additions and core multiplications */ - temp2[0] = temp1[0] + temp1[8]; - temp2[4] = temp1[0] - temp1[8]; - temp2[1] = temp1[1] + temp1[9]; - temp2[5] = temp1[1] - temp1[9]; - temp2[8] = temp1[2] - temp1[11]; - temp2[10] = temp1[2] + temp1[11]; - temp2[9] = temp1[3] + temp1[10]; - temp2[11] = temp1[3] - temp1[10]; - temp2[2] = temp1[4] + temp1[12]; - temp2[7] = temp1[4] - temp1[12]; - temp2[3] = temp1[5] + temp1[13]; - temp2[6] = temp1[13] - temp1[5]; - - temp1[1] = temp1[6] + temp1[14]; - temp1[2] = temp1[6] - temp1[14]; - temp1[0] = temp1[7] + temp1[15]; - temp1[3] = temp1[7] - temp1[15]; - temp2[12] = (temp1[0] + temp1[2]) * INV_SQRT2; - temp2[14] = (temp1[0] - temp1[2]) * INV_SQRT2; - temp2[13] = (temp1[3] - temp1[1]) * INV_SQRT2; - temp2[15] = (temp1[1] + temp1[3]) * -INV_SQRT2; - - /* Post-additions */ - vec[0] = temp2[0] + temp2[2]; - vec[8] = temp2[0] - temp2[2]; - vec[1] = temp2[1] + temp2[3]; - vec[9] = temp2[1] - temp2[3]; - vec[4] = temp2[4] - temp2[6]; - vec[12] = temp2[4] + temp2[6]; - vec[5] = temp2[5] - temp2[7]; - vec[13] = temp2[5] + temp2[7]; - vec[6] = temp2[8] + temp2[14]; - vec[14] = temp2[8] - temp2[14]; - vec[7] = temp2[9] + temp2[15]; - vec[15] = temp2[9] - temp2[15]; - vec[2] = temp2[10] + temp2[12]; - vec[10] = temp2[10] - temp2[12]; - vec[3] = temp2[11] + temp2[13]; - vec[11] = temp2[11] - temp2[13]; -} - - -static void fft9(LC3_FLOAT* vec) -{ - const LC3_FLOAT C91 = 0.766044443118978; /* cos(2*PI/5); */ - const LC3_FLOAT C92 = 0.642787609686539; - const LC3_FLOAT C93 = 0.17364817766693; - const LC3_FLOAT C94 = 0.984807753012208; - const LC3_FLOAT C95 = 0.5; - const LC3_FLOAT C96 = 0.866025403784439; - const LC3_FLOAT C97 = 0.939692620785908; - const LC3_FLOAT C98 = 0.342020143325669; - - LC3_FLOAT re1, im1, re2_9p, re2_9m, im2_9p, im2_9m, re3_8p, re3_8m, im3_8p, im3_8m, re4_7p, re4_7m, im4_7p, im4_7m, - re5_6p, re5_6m, im5_6p, im5_6m; - - re1 = vec[0]; - im1 = vec[1]; - - butterfly(vec[1 * 2], vec[8 * 2], &re2_9p, &re2_9m); - butterfly(vec[1 * 2 + 1], vec[8 * 2 + 1], &im2_9p, &im2_9m); - butterfly(vec[2 * 2], vec[7 * 2], &re3_8p, &re3_8m); - butterfly(vec[2 * 2 + 1], vec[7 * 2 + 1], &im3_8p, &im3_8m); - butterfly(vec[3 * 2], vec[6 * 2], &re4_7p, &re4_7m); - butterfly(vec[3 * 2 + 1], vec[6 * 2 + 1], &im4_7p, &im4_7m); - butterfly(vec[4 * 2], vec[5 * 2], &re5_6p, &re5_6m); - butterfly(vec[4 * 2 + 1], vec[5 * 2 + 1], &im5_6p, &im5_6m); - - /* - 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 - 1.0000 C91 - C92i C93 - C94i -C95 - C96i -C97 - C98i -C97 + C98i -C95 + C96i C93 + C94i C91 + C92i - 1.0000 C93 - C94i -C97 - C98i -C95 + C96i C91 + C92i C91 - C92i -C95 - C96i -C97 + C98i C93 + C94i - 1.0000 -C95 - C96i -C95 + C96i 1.0000 -C95 - C96i -C95 + C96i 1.0000 -C95 - C96i -C95 + C96i - 1.0000 -C97 - C98i C91 + C92i -C95 - C96i C93 + C94i C93 - C94i -C95 + C96i C91 - C92i -C97 + C98i - 1.0000 -C97 + C98i C91 - C92i -C95 + C96i C93 - C94i C93 + C94i -C95 - C96i C91 + C92i -C97 - C98i - 1.0000 -C95 + C96i -C95 - C96i 1.0000 -C95 + C96i -C95 - C96i 1.0000 -C95 + C96i -C95 - C96i - 1.0000 C93 + C94i -C97 + C98i -C95 - C96i C91 - C92i C91 + C92i -C95 + C96i -C97 - C98i C93 - C94i - 1.0000 C91 + C92i C93 + C94i -C95 + C96i -C97 + C98i -C97 - C98i -C95 - C96i C93 - C94i C91 - C92i - */ - vec[0] = re1 + re2_9p + re3_8p + re4_7p + re5_6p; - vec[1] = im1 + im2_9p + im3_8p + im4_7p + im5_6p; - vec[2] = re1 + C91 * re2_9p + C93 * re3_8p - C95 * re4_7p - C97 * re5_6p + C92 * im2_9m + C94 * im3_8m + - C96 * im4_7m + C98 * im5_6m; - vec[16] = re1 + C91 * re2_9p + C93 * re3_8p - C95 * re4_7p - C97 * re5_6p - C92 * im2_9m - C94 * im3_8m - - C96 * im4_7m - C98 * im5_6m; - vec[3] = im1 - C92 * re2_9m - C94 * re3_8m - C96 * re4_7m - C98 * re5_6m + C91 * im2_9p + C93 * im3_8p - - C95 * im4_7p - C97 * im5_6p; - vec[17] = im1 + C92 * re2_9m + C94 * re3_8m + C96 * re4_7m + C98 * re5_6m + C91 * im2_9p + C93 * im3_8p - - C95 * im4_7p - C97 * im5_6p; - vec[4] = re1 + C93 * re2_9p - C97 * re3_8p - C95 * re4_7p + C91 * re5_6p + C94 * im2_9m + C98 * im3_8m - - C96 * im4_7m - C92 * im5_6m; - vec[14] = re1 + C93 * re2_9p - C97 * re3_8p - C95 * re4_7p + C91 * re5_6p - C94 * im2_9m - C98 * im3_8m + - C96 * im4_7m + C92 * im5_6m; - vec[5] = im1 - C94 * re2_9m - C98 * re3_8m + C96 * re4_7m + C92 * re5_6m + C93 * im2_9p - C97 * im3_8p - - C95 * im4_7p + C91 * im5_6p; - vec[15] = im1 + C94 * re2_9m + C98 * re3_8m - C96 * re4_7m - C92 * re5_6m + C93 * im2_9p - C97 * im3_8p - - C95 * im4_7p + C91 * im5_6p; - vec[6] = re1 - C95 * (re2_9p + re3_8p + re5_6p) + re4_7p + C96 * (im2_9m - im3_8m + im5_6m); - vec[12] = re1 - C95 * (re2_9p + re3_8p + re5_6p) + re4_7p - C96 * (im2_9m - im3_8m + im5_6m); - vec[7] = im1 - C96 * (re2_9m - re3_8m + re5_6m) - C95 * (im2_9p + im3_8p + im5_6p) + im4_7p; - vec[13] = im1 + C96 * (re2_9m - re3_8m + re5_6m) - C95 * (im2_9p + im3_8p + im5_6p) + im4_7p; - vec[8] = re1 - C97 * re2_9p + C91 * re3_8p - C95 * re4_7p + C93 * re5_6p + C98 * im2_9m - C92 * im3_8m + - C96 * im4_7m - C94 * im5_6m; - vec[10] = re1 - C97 * re2_9p + C91 * re3_8p - C95 * re4_7p + C93 * re5_6p - C98 * im2_9m + C92 * im3_8m - - C96 * im4_7m + C94 * im5_6m; - vec[9] = im1 - C98 * re2_9m + C92 * re3_8m - C96 * re4_7m + C94 * re5_6m - C97 * im2_9p + C91 * im3_8p - - C95 * im4_7p + C93 * im5_6p; - vec[11] = im1 + C98 * re2_9m - C92 * re3_8m + C96 * re4_7m - C94 * re5_6m - C97 * im2_9p + C91 * im3_8p - - C95 * im4_7p + C93 * im5_6p; -} - diff --git a/lib_lc3plus/fft/fft_32.h b/lib_lc3plus/fft/fft_32.h deleted file mode 100644 index 803923a01..000000000 --- a/lib_lc3plus/fft/fft_32.h +++ /dev/null @@ -1,467 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -/* guard against unindended includes */ -#ifndef INCLUDED_FROM_IISFFT_C -#error "this file must not be included" -#endif - -static void fft32(LC3_FLOAT* vec) -{ - const LC3_FLOAT INV_SQRT2 = 7.071067811865475e-1; - const LC3_FLOAT COS_PI_DIV8 = 9.238795325112867e-1; - const LC3_FLOAT COS_3PI_DIV8 = 3.826834323650898e-1; - const LC3_FLOAT SQRT2PLUS1 = 2.414213562373095; - const LC3_FLOAT SQRT2MINUS1 = 4.142135623730952e-1; - - const LC3_FLOAT c[4] = {9.807852804032304e-1, 8.314696123025452e-1, 5.555702330196023e-1, 1.950903220161283e-1}; - - LC3_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, - temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp110, temp111, temp112, - temp113, temp114, temp115, temp20, temp21, temp22, temp23, temp24, temp25, temp26, temp27, temp28, temp29, - temp210, temp211, temp212, temp213, temp214, temp215, temp30, temp31, temp32, temp33, temp34, temp35, temp36, - temp37, temp38, temp39, temp310, temp311, temp312, temp313, temp314, temp315, temp316, temp317, temp318, - temp319, temp320, temp321, temp322, temp323, temp324, temp325, temp326, temp327, temp328, temp329, temp330, - temp331, temp40, temp41, temp42, temp43, temp44, temp45, temp46, temp47, temp48, temp49, temp410, temp411, - temp412, temp413, temp414, temp415; - - temp20 = vec[2] - vec[34]; - temp21 = vec[3] - vec[35]; - temp30 = vec[0] + vec[32]; - temp31 = vec[1] + vec[33]; - temp32 = vec[2] + vec[34]; - temp33 = vec[3] + vec[35]; - - temp22 = vec[6] - vec[38]; - temp23 = vec[7] - vec[39]; - temp34 = vec[4] + vec[36]; - temp35 = vec[5] + vec[37]; - temp36 = vec[6] + vec[38]; - temp37 = vec[7] + vec[39]; - - temp24 = vec[10] - vec[42]; - temp25 = vec[11] - vec[43]; - temp38 = vec[8] + vec[40]; - temp39 = vec[9] + vec[41]; - temp310 = vec[10] + vec[42]; - temp311 = vec[11] + vec[43]; - - temp26 = vec[14] - vec[46]; - temp27 = vec[15] - vec[47]; - temp312 = vec[12] + vec[44]; - temp313 = vec[13] + vec[45]; - temp314 = vec[14] + vec[46]; - temp315 = vec[15] + vec[47]; - - temp28 = vec[18] - vec[50]; - temp29 = vec[19] - vec[51]; - temp316 = vec[16] + vec[48]; - temp317 = vec[17] + vec[49]; - temp318 = vec[18] + vec[50]; - temp319 = vec[19] + vec[51]; - - temp210 = vec[22] - vec[54]; - temp211 = vec[23] - vec[55]; - temp320 = vec[20] + vec[52]; - temp321 = vec[21] + vec[53]; - temp322 = vec[22] + vec[54]; - temp323 = vec[23] + vec[55]; - - temp212 = vec[26] - vec[58]; - temp213 = vec[27] - vec[59]; - temp324 = vec[24] + vec[56]; - temp325 = vec[25] + vec[57]; - temp326 = vec[26] + vec[58]; - temp327 = vec[27] + vec[59]; - - temp214 = vec[30] - vec[62]; - temp215 = vec[31] - vec[63]; - temp328 = vec[28] + vec[60]; - temp329 = vec[29] + vec[61]; - temp330 = vec[30] + vec[62]; - temp331 = vec[31] + vec[63]; - - /* Pre-additions */ - temp41 = -(temp20 + temp214); - temp42 = temp20 - temp214; - temp40 = temp21 + temp215; - temp43 = temp21 - temp215; - temp45 = -(temp22 + temp212); - temp46 = temp22 - temp212; - temp44 = temp23 + temp213; - temp47 = temp23 - temp213; - temp49 = -(temp24 + temp210); - temp410 = temp24 - temp210; - temp48 = temp25 + temp211; - temp411 = temp25 - temp211; - temp413 = -(temp26 + temp28); - temp414 = temp26 - temp28; - temp412 = temp27 + temp29; - temp415 = temp27 - temp29; - - /* Core multiplications */ - temp20 = temp40 * c[3] + temp44 * c[2] + temp48 * c[1] + temp412 * c[0]; - temp24 = temp40 * c[2] + temp44 * c[0] + temp48 * c[3] - temp412 * c[1]; - temp28 = temp40 * c[1] + temp44 * c[3] - temp48 * c[0] + temp412 * c[2]; - temp212 = temp40 * c[0] - temp44 * c[1] + temp48 * c[2] - temp412 * c[3]; - temp21 = temp41 * c[3] + temp45 * c[2] + temp49 * c[1] + temp413 * c[0]; - temp25 = temp41 * c[2] + temp45 * c[0] + temp49 * c[3] - temp413 * c[1]; - temp29 = temp41 * c[1] + temp45 * c[3] - temp49 * c[0] + temp413 * c[2]; - temp213 = temp41 * c[0] - temp45 * c[1] + temp49 * c[2] - temp413 * c[3]; - temp22 = temp42 * c[0] + temp46 * c[1] + temp410 * c[2] + temp414 * c[3]; - temp26 = temp42 * c[1] - temp46 * c[3] - temp410 * c[0] - temp414 * c[2]; - temp210 = temp42 * c[2] - temp46 * c[0] + temp410 * c[3] + temp414 * c[1]; - temp214 = temp42 * c[3] - temp46 * c[2] + temp410 * c[1] - temp414 * c[0]; - temp23 = temp43 * c[0] + temp47 * c[1] + temp411 * c[2] + temp415 * c[3]; - temp27 = temp43 * c[1] - temp47 * c[3] - temp411 * c[0] - temp415 * c[2]; - temp211 = temp43 * c[2] - temp47 * c[0] + temp411 * c[3] + temp415 * c[1]; - temp215 = temp43 * c[3] - temp47 * c[2] + temp411 * c[1] - temp415 * c[0]; - - /* Post-additions */ - temp40 = temp20 + temp22; - temp414 = temp20 - temp22; - temp41 = temp21 + temp23; - temp415 = temp21 - temp23; - temp42 = temp24 + temp26; - temp412 = temp24 - temp26; - temp43 = temp25 + temp27; - temp413 = temp25 - temp27; - temp44 = temp28 + temp210; - temp410 = temp28 - temp210; - temp45 = temp29 + temp211; - temp411 = temp29 - temp211; - temp46 = temp212 + temp214; - temp48 = temp212 - temp214; - temp47 = temp213 + temp215; - temp49 = temp213 - temp215; - - /* fft16(temp3); */ - /* even */ - temp10 = temp30 + temp316; - temp11 = temp31 + temp317; - temp12 = temp32 + temp318; - temp13 = temp33 + temp319; - temp14 = temp34 + temp320; - temp15 = temp35 + temp321; - temp16 = temp36 + temp322; - temp17 = temp37 + temp323; - temp18 = temp38 + temp324; - temp19 = temp39 + temp325; - temp110 = temp310 + temp326; - temp111 = temp311 + temp327; - temp112 = temp312 + temp328; - temp113 = temp313 + temp329; - temp114 = temp314 + temp330; - temp115 = temp315 + temp331; - - /* Pre-additions */ - tmp0 = temp10 + temp18; - tmp2 = temp10 - temp18; - tmp1 = temp11 + temp19; - tmp3 = temp11 - temp19; - tmp4 = temp12 + temp110; - tmp6 = temp12 - temp110; - tmp5 = temp13 + temp111; - tmp7 = temp13 - temp111; - tmp8 = temp14 + temp112; - tmp10 = temp14 - temp112; - tmp9 = temp15 + temp113; - tmp11 = temp15 - temp113; - tmp12 = temp16 + temp114; - tmp14 = temp16 - temp114; - tmp13 = temp17 + temp115; - tmp15 = temp17 - temp115; - - /* Pre-additions and core multiplications */ - temp20 = tmp0 + tmp8; - temp24 = tmp0 - tmp8; - temp21 = tmp1 + tmp9; - temp25 = tmp1 - tmp9; - temp28 = tmp2 - tmp11; - temp210 = tmp2 + tmp11; - temp29 = tmp3 + tmp10; - temp211 = tmp3 - tmp10; - temp22 = tmp4 + tmp12; - temp27 = tmp4 - tmp12; - temp23 = tmp5 + tmp13; - temp26 = tmp13 - tmp5; - - tmp1 = tmp6 + tmp14; - tmp2 = tmp6 - tmp14; - tmp0 = tmp7 + tmp15; - tmp3 = tmp7 - tmp15; - temp212 = (tmp0 + tmp2) * INV_SQRT2; - temp214 = (tmp0 - tmp2) * INV_SQRT2; - temp213 = (tmp3 - tmp1) * INV_SQRT2; - temp215 = (tmp1 + tmp3) * -INV_SQRT2; - - /* odd */ - temp10 = temp30 - temp316; - temp11 = temp31 - temp317; - temp12 = temp32 - temp318; - temp13 = temp33 - temp319; - temp14 = temp34 - temp320; - temp15 = temp35 - temp321; - temp16 = temp36 - temp322; - temp17 = temp37 - temp323; - temp18 = temp38 - temp324; - temp19 = temp39 - temp325; - temp110 = temp310 - temp326; - temp111 = temp311 - temp327; - temp112 = temp312 - temp328; - temp113 = temp313 - temp329; - temp114 = temp314 - temp330; - temp115 = temp315 - temp331; - - /* Post-additions */ - temp30 = temp20 + temp22; - temp316 = temp20 - temp22; - temp31 = temp21 + temp23; - temp317 = temp21 - temp23; - temp38 = temp24 - temp26; - temp324 = temp24 + temp26; - temp39 = temp25 - temp27; - temp325 = temp25 + temp27; - temp312 = temp28 + temp214; - temp328 = temp28 - temp214; - temp313 = temp29 + temp215; - temp329 = temp29 - temp215; - temp34 = temp210 + temp212; - temp320 = temp210 - temp212; - temp35 = temp211 + temp213; - temp321 = temp211 - temp213; - - /* Pre-additions and core multiplications */ - tmp9 = (temp12 + temp114) * -COS_3PI_DIV8; - tmp10 = (temp12 - temp114) * COS_PI_DIV8; - tmp8 = (temp13 + temp115) * COS_3PI_DIV8; - tmp11 = (temp13 - temp115) * COS_PI_DIV8; - tmp5 = (temp14 + temp112) * -INV_SQRT2; - tmp6 = (temp14 - temp112) * INV_SQRT2; - tmp4 = (temp15 + temp113) * INV_SQRT2; - tmp7 = (temp15 - temp113) * INV_SQRT2; - tmp13 = (temp16 + temp110) * -COS_PI_DIV8; - tmp14 = (temp16 - temp110) * COS_3PI_DIV8; - tmp12 = (temp17 + temp111) * COS_PI_DIV8; - tmp15 = (temp17 - temp111) * COS_3PI_DIV8; - - /* Core multiplications */ - temp12 = tmp8 * SQRT2PLUS1 - tmp12 * SQRT2MINUS1; - temp13 = tmp9 * SQRT2PLUS1 - tmp13 * SQRT2MINUS1; - temp14 = tmp10 * SQRT2MINUS1 - tmp14 * SQRT2PLUS1; - temp15 = tmp11 * SQRT2MINUS1 - tmp15 * SQRT2PLUS1; - - /* Post-additions */ - tmp8 += tmp12; - tmp9 += tmp13; - tmp10 += tmp14; - tmp11 += tmp15; - temp16 = temp10 + tmp4; - temp110 = temp10 - tmp4; - temp17 = temp11 + tmp5; - temp111 = temp11 - tmp5; - - temp112 = tmp6 - temp19; - temp114 = tmp6 + temp19; - temp113 = temp18 + tmp7; - temp115 = temp18 - tmp7; - - tmp0 = temp16 - temp114; - tmp2 = temp16 + temp114; - tmp1 = temp17 + temp115; - tmp3 = temp17 - temp115; - tmp4 = temp110 + temp112; - tmp6 = temp110 - temp112; - tmp5 = temp111 + temp113; - tmp7 = temp111 - temp113; - - temp110 = tmp8 + tmp10; - tmp10 = tmp8 - tmp10; - temp111 = tmp9 + tmp11; - tmp11 = tmp9 - tmp11; - - tmp12 = temp12 + temp14; - tmp14 = temp12 - temp14; - tmp13 = temp13 + temp15; - tmp15 = temp13 - temp15; - - temp32 = tmp2 + temp110; - temp318 = tmp2 - temp110; - temp33 = tmp3 + temp111; - temp319 = tmp3 - temp111; - temp36 = tmp0 + tmp12; - temp322 = tmp0 - tmp12; - temp37 = tmp1 + tmp13; - temp323 = tmp1 - tmp13; - temp314 = tmp4 + tmp10; - temp330 = tmp4 - tmp10; - temp315 = tmp5 + tmp11; - temp331 = tmp5 - tmp11; - temp310 = tmp6 + tmp14; - temp326 = tmp6 - tmp14; - temp311 = tmp7 + tmp15; - temp327 = tmp7 - tmp15; - /* fft16(temp3); end */ - - /* fft8even(temp1); */ - temp10 = vec[0] - vec[32]; - temp11 = vec[1] - vec[33]; - temp12 = vec[4] - vec[36]; - temp13 = vec[5] - vec[37]; - temp14 = vec[8] - vec[40]; - temp15 = vec[9] - vec[41]; - temp16 = vec[12] - vec[44]; - temp17 = vec[13] - vec[45]; - temp18 = vec[16] - vec[48]; - temp19 = vec[17] - vec[49]; - temp110 = vec[20] - vec[52]; - temp111 = vec[21] - vec[53]; - temp112 = vec[24] - vec[56]; - temp113 = vec[25] - vec[57]; - temp114 = vec[28] - vec[60]; - temp115 = vec[29] - vec[61]; - - /* Pre-additions and core multiplications */ - tmp9 = (temp12 + temp114) * -COS_3PI_DIV8; - tmp10 = (temp12 - temp114) * COS_PI_DIV8; - tmp8 = (temp13 + temp115) * COS_3PI_DIV8; - tmp11 = (temp13 - temp115) * COS_PI_DIV8; - tmp5 = (temp14 + temp112) * -INV_SQRT2; - tmp6 = (temp14 - temp112) * INV_SQRT2; - tmp4 = (temp15 + temp113) * INV_SQRT2; - tmp7 = (temp15 - temp113) * INV_SQRT2; - tmp13 = (temp16 + temp110) * -COS_PI_DIV8; - tmp14 = (temp16 - temp110) * COS_3PI_DIV8; - tmp12 = (temp17 + temp111) * COS_PI_DIV8; - tmp15 = (temp17 - temp111) * COS_3PI_DIV8; - - /* Core multiplications */ - temp12 = tmp8 * SQRT2PLUS1 - tmp12 * SQRT2MINUS1; - temp13 = tmp9 * SQRT2PLUS1 - tmp13 * SQRT2MINUS1; - temp14 = tmp10 * SQRT2MINUS1 - tmp14 * SQRT2PLUS1; - temp15 = tmp11 * SQRT2MINUS1 - tmp15 * SQRT2PLUS1; - - /* Post-additions */ - tmp8 += tmp12; - tmp9 += tmp13; - tmp10 += tmp14; - tmp11 += tmp15; - temp16 = temp10 + tmp4; - temp110 = temp10 - tmp4; - temp17 = temp11 + tmp5; - temp111 = temp11 - tmp5; - - temp112 = tmp6 - temp19; - temp114 = tmp6 + temp19; - temp113 = temp18 + tmp7; - temp115 = temp18 - tmp7; - - tmp0 = temp16 - temp114; - tmp2 = temp16 + temp114; - tmp1 = temp17 + temp115; - tmp3 = temp17 - temp115; - tmp4 = temp110 + temp112; - tmp6 = temp110 - temp112; - tmp5 = temp111 + temp113; - tmp7 = temp111 - temp113; - - temp110 = tmp8 + tmp10; - tmp10 = tmp8 - tmp10; - temp111 = tmp9 + tmp11; - tmp11 = tmp9 - tmp11; - - tmp12 = temp12 + temp14; - tmp14 = temp12 - temp14; - tmp13 = temp13 + temp15; - tmp15 = temp13 - temp15; - - temp10 = tmp2 + temp110; - temp18 = tmp2 - temp110; - temp11 = tmp3 + temp111; - temp19 = tmp3 - temp111; - temp12 = tmp0 + tmp12; - temp110 = tmp0 - tmp12; - temp13 = tmp1 + tmp13; - temp111 = tmp1 - tmp13; - temp16 = tmp4 + tmp10; - temp114 = tmp4 - tmp10; - temp17 = tmp5 + tmp11; - temp115 = tmp5 - tmp11; - temp14 = tmp6 + tmp14; - temp112 = tmp6 - tmp14; - temp15 = tmp7 + tmp15; - temp113 = tmp7 - tmp15; - /* fft8even(temp1); end */ - - *vec++ = temp30; - *vec++ = temp31; - *vec++ = temp10 + temp40; - *vec++ = temp11 + temp41; - *vec++ = temp32; - *vec++ = temp33; - *vec++ = temp12 + temp42; - *vec++ = temp13 + temp43; - *vec++ = temp34; - *vec++ = temp35; - *vec++ = temp14 + temp44; - *vec++ = temp15 + temp45; - *vec++ = temp36; - *vec++ = temp37; - *vec++ = temp16 + temp46; - *vec++ = temp17 + temp47; - *vec++ = temp38; - *vec++ = temp39; - *vec++ = temp18 + temp48; - *vec++ = temp19 + temp49; - *vec++ = temp310; - *vec++ = temp311; - *vec++ = temp110 + temp410; - *vec++ = temp111 + temp411; - *vec++ = temp312; - *vec++ = temp313; - *vec++ = temp112 + temp412; - *vec++ = temp113 + temp413; - *vec++ = temp314; - *vec++ = temp315; - *vec++ = temp114 + temp414; - *vec++ = temp115 + temp415; - *vec++ = temp316; - *vec++ = temp317; - *vec++ = temp10 - temp40; - *vec++ = temp11 - temp41; - *vec++ = temp318; - *vec++ = temp319; - *vec++ = temp12 - temp42; - *vec++ = temp13 - temp43; - *vec++ = temp320; - *vec++ = temp321; - *vec++ = temp14 - temp44; - *vec++ = temp15 - temp45; - *vec++ = temp322; - *vec++ = temp323; - *vec++ = temp16 - temp46; - *vec++ = temp17 - temp47; - *vec++ = temp324; - *vec++ = temp325; - *vec++ = temp18 - temp48; - *vec++ = temp19 - temp49; - *vec++ = temp326; - *vec++ = temp327; - *vec++ = temp110 - temp410; - *vec++ = temp111 - temp411; - *vec++ = temp328; - *vec++ = temp329; - *vec++ = temp112 - temp412; - *vec++ = temp113 - temp413; - *vec++ = temp330; - *vec++ = temp331; - *vec++ = temp114 - temp414; - *vec++ = temp115 - temp415; -} diff --git a/lib_lc3plus/fft/fft_384_768.h b/lib_lc3plus/fft/fft_384_768.h deleted file mode 100644 index bd89393c1..000000000 --- a/lib_lc3plus/fft/fft_384_768.h +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -/* guard against unindended includes */ -#ifndef INCLUDED_FROM_IISFFT_C -#error "this file must not be included" -#endif - -static void fft384(LC3_FLOAT* restrict in) -{ - const LC3_INT table1[384] = { - 0, 256, 128, 129, 1, 257, 258, 130, 2, 3, 259, 131, 132, 4, 260, 261, 133, 5, 6, 262, 134, 135, - 7, 263, 264, 136, 8, 9, 265, 137, 138, 10, 266, 267, 139, 11, 12, 268, 140, 141, 13, 269, 270, 142, - 14, 15, 271, 143, 144, 16, 272, 273, 145, 17, 18, 274, 146, 147, 19, 275, 276, 148, 20, 21, 277, 149, - 150, 22, 278, 279, 151, 23, 24, 280, 152, 153, 25, 281, 282, 154, 26, 27, 283, 155, 156, 28, 284, 285, - 157, 29, 30, 286, 158, 159, 31, 287, 288, 160, 32, 33, 289, 161, 162, 34, 290, 291, 163, 35, 36, 292, - 164, 165, 37, 293, 294, 166, 38, 39, 295, 167, 168, 40, 296, 297, 169, 41, 42, 298, 170, 171, 43, 299, - 300, 172, 44, 45, 301, 173, 174, 46, 302, 303, 175, 47, 48, 304, 176, 177, 49, 305, 306, 178, 50, 51, - 307, 179, 180, 52, 308, 309, 181, 53, 54, 310, 182, 183, 55, 311, 312, 184, 56, 57, 313, 185, 186, 58, - 314, 315, 187, 59, 60, 316, 188, 189, 61, 317, 318, 190, 62, 63, 319, 191, 192, 64, 320, 321, 193, 65, - 66, 322, 194, 195, 67, 323, 324, 196, 68, 69, 325, 197, 198, 70, 326, 327, 199, 71, 72, 328, 200, 201, - 73, 329, 330, 202, 74, 75, 331, 203, 204, 76, 332, 333, 205, 77, 78, 334, 206, 207, 79, 335, 336, 208, - 80, 81, 337, 209, 210, 82, 338, 339, 211, 83, 84, 340, 212, 213, 85, 341, 342, 214, 86, 87, 343, 215, - 216, 88, 344, 345, 217, 89, 90, 346, 218, 219, 91, 347, 348, 220, 92, 93, 349, 221, 222, 94, 350, 351, - 223, 95, 96, 352, 224, 225, 97, 353, 354, 226, 98, 99, 355, 227, 228, 100, 356, 357, 229, 101, 102, 358, - 230, 231, 103, 359, 360, 232, 104, 105, 361, 233, 234, 106, 362, 363, 235, 107, 108, 364, 236, 237, 109, 365, - 366, 238, 110, 111, 367, 239, 240, 112, 368, 369, 241, 113, 114, 370, 242, 243, 115, 371, 372, 244, 116, 117, - 373, 245, 246, 118, 374, 375, 247, 119, 120, 376, 248, 249, 121, 377, 378, 250, 122, 123, 379, 251, 252, 124, - 380, 381, 253, 125, 126, 382, 254, 255, 127, 383}; - const LC3_INT table2[384] = { - 0, 128, 256, 3, 131, 259, 6, 134, 262, 9, 137, 265, 12, 140, 268, 15, 143, 271, 18, 146, 274, 21, - 149, 277, 24, 152, 280, 27, 155, 283, 30, 158, 286, 33, 161, 289, 36, 164, 292, 39, 167, 295, 42, 170, - 298, 45, 173, 301, 48, 176, 304, 51, 179, 307, 54, 182, 310, 57, 185, 313, 60, 188, 316, 63, 191, 319, - 66, 194, 322, 69, 197, 325, 72, 200, 328, 75, 203, 331, 78, 206, 334, 81, 209, 337, 84, 212, 340, 87, - 215, 343, 90, 218, 346, 93, 221, 349, 96, 224, 352, 99, 227, 355, 102, 230, 358, 105, 233, 361, 108, 236, - 364, 111, 239, 367, 114, 242, 370, 117, 245, 373, 120, 248, 376, 123, 251, 379, 126, 254, 382, 129, 257, 1, - 132, 260, 4, 135, 263, 7, 138, 266, 10, 141, 269, 13, 144, 272, 16, 147, 275, 19, 150, 278, 22, 153, - 281, 25, 156, 284, 28, 159, 287, 31, 162, 290, 34, 165, 293, 37, 168, 296, 40, 171, 299, 43, 174, 302, - 46, 177, 305, 49, 180, 308, 52, 183, 311, 55, 186, 314, 58, 189, 317, 61, 192, 320, 64, 195, 323, 67, - 198, 326, 70, 201, 329, 73, 204, 332, 76, 207, 335, 79, 210, 338, 82, 213, 341, 85, 216, 344, 88, 219, - 347, 91, 222, 350, 94, 225, 353, 97, 228, 356, 100, 231, 359, 103, 234, 362, 106, 237, 365, 109, 240, 368, - 112, 243, 371, 115, 246, 374, 118, 249, 377, 121, 252, 380, 124, 255, 383, 127, 258, 2, 130, 261, 5, 133, - 264, 8, 136, 267, 11, 139, 270, 14, 142, 273, 17, 145, 276, 20, 148, 279, 23, 151, 282, 26, 154, 285, - 29, 157, 288, 32, 160, 291, 35, 163, 294, 38, 166, 297, 41, 169, 300, 44, 172, 303, 47, 175, 306, 50, - 178, 309, 53, 181, 312, 56, 184, 315, 59, 187, 318, 62, 190, 321, 65, 193, 324, 68, 196, 327, 71, 199, - 330, 74, 202, 333, 77, 205, 336, 80, 208, 339, 83, 211, 342, 86, 214, 345, 89, 217, 348, 92, 220, 351, - 95, 223, 354, 98, 226, 357, 101, 229, 360, 104, 232, 363, 107, 235, 366, 110, 238, 369, 113, 241, 372, 116, - 244, 375, 119, 247, 378, 122, 250, 381, 125, 253}; - - const LC3_INT L = 384; - const LC3_INT A = 3; - const LC3_INT B = 128; - const LC3_INT* idx1 = table1; - const LC3_INT* idx2 = table2; - - LC3_INT k, l; - LC3_FLOAT temp[256], out[768]; - - for (k = 0; k < A; k++) { - for (l = 0; l < B; l++) { - temp[2 * l] = in[2 * *idx1]; - temp[2 * l + 1] = in[2 * *idx1 + 1]; - idx1 += A; - } - - fft128(temp); /* 128-point FFT */ - idx1 -= L; - - for (l = 0; l < B; l++) { - in[2 * *idx1] = temp[2 * l]; - in[2 * *idx1 + 1] = temp[2 * l + 1]; - idx1 += A; - } - - idx1 -= L - 1; - } - - idx1 -= A; - - for (k = 0; k < B; k++) { - for (l = 0; l < A; l++) { - temp[2 * l] = in[2 * *idx1]; - temp[2 * l + 1] = in[2 * *idx1++ + 1]; - } - - fft3(temp); /* 3-point FFT */ - - for (l = 0; l < A; l++) { - out[2 * *idx2] = temp[2 * l]; - out[2 * *idx2++ + 1] = temp[2 * l + 1]; - } - } - - memmove(in, out, 2 * L * sizeof(LC3_FLOAT)); -} - diff --git a/lib_lc3plus/fft/fft_60_128.h b/lib_lc3plus/fft/fft_60_128.h deleted file mode 100644 index e5a88ccad..000000000 --- a/lib_lc3plus/fft/fft_60_128.h +++ /dev/null @@ -1,161 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -/* guard against unindended includes */ -#ifndef INCLUDED_FROM_IISFFT_C -#error "this file must not be included" -#endif - -static void fft60(LC3_FLOAT* in) -{ - const LC3_INT table1[] = {0, 45, 30, 15, 16, 1, 46, 31, 32, 17, 2, 47, 48, 33, 18, 3, 4, 49, 34, 19, - 20, 5, 50, 35, 36, 21, 6, 51, 52, 37, 22, 7, 8, 53, 38, 23, 24, 9, 54, 39, - 40, 25, 10, 55, 56, 41, 26, 11, 12, 57, 42, 27, 28, 13, 58, 43, 44, 29, 14, 59}; - const LC3_INT table2[] = {0, 15, 30, 45, 4, 19, 34, 49, 8, 23, 38, 53, 12, 27, 42, 57, 16, 31, 46, 1, - 20, 35, 50, 5, 24, 39, 54, 9, 28, 43, 58, 13, 32, 47, 2, 17, 36, 51, 6, 21, - 40, 55, 10, 25, 44, 59, 14, 29, 48, 3, 18, 33, 52, 7, 22, 37, 56, 11, 26, 41}; - const LC3_INT a = 4; - const LC3_INT b = 15; - const LC3_INT L = 60; - const LC3_INT* idx1 = table1; - const LC3_INT* idx2 = table2; - - LC3_FLOAT temp[30], out[120]; - LC3_INT k, l; - - for (k = 0; k < a; k++) { - for (l = 0; l < b; l++) { - temp[2 * l] = in[2 * *idx1]; - temp[2 * l + 1] = in[2 * *idx1 + 1]; - idx1 += a; - } - - fft15(temp); /* 15-point FFT */ - idx1 -= L; - - for (l = 0; l < b; l++) { - in[2 * *idx1] = temp[2 * l]; - in[2 * *idx1 + 1] = temp[2 * l + 1]; - idx1 += a; - } - idx1 -= L - 1; - } - - idx1 -= a; - - for (k = 0; k < b; k++) { - for (l = 0; l < a; l++) { - temp[2 * l] = in[2 * *idx1]; - temp[2 * l + 1] = in[2 * *idx1++ + 1]; - } - - fft4(temp); /* 4-point FFT */ - - for (l = 0; l < a; l++) { - out[2 * *idx2] = temp[2 * l]; - out[2 * *idx2++ + 1] = temp[2 * l + 1]; - } - } - memmove(in, out, 2 * L * sizeof(LC3_FLOAT)); -} - -static void fft64(LC3_FLOAT* vec) -{ - const LC3_FLOAT w[] = { - 1.0000000000f, 0.9951847267f, 0.9807852804f, 0.9569403357f, 0.9238795325f, 0.8819212643f, 0.8314696123f, - 0.7730104534f, 0.7071067812f, 0.6343932842f, 0.5555702330f, 0.4713967368f, 0.3826834324f, 0.2902846773f, - 0.1950903220f, 0.0980171403f, 0.0000000000f, -0.0980171403f, -0.1950903220f, -0.2902846773f, -0.3826834324f, - -0.4713967368f, -0.5555702330f, -0.6343932842f, -0.7071067812f, -0.7730104534f, -0.8314696123f, -0.8819212643f, - -0.9238795325f, -0.9569403357f, -0.9807852804f, -0.9951847267f, -1.0000000000f, -0.9951847267f, -0.9807852804f, - -0.9569403357f, -0.9238795325f, -0.8819212643f, -0.8314696123f, -0.7730104534f, -0.7071067812f, -0.6343932842f, - -0.5555702330f, -0.4713967368f, -0.3826834324f, -0.2902846773f, -0.1950903220f, -0.0980171403f}; - - LC3_FLOAT temp1[64], temp2[64]; - LC3_INT i; - - for (i = 0; i < 32; i++) { - temp1[2 * i] = vec[4 * i]; - temp1[2 * i + 1] = vec[4 * i + 1]; - temp2[2 * i] = vec[4 * i + 2]; - temp2[2 * i + 1] = vec[4 * i + 3]; - } - - fft32(temp1); - fft32(temp2); - - for (i = 0; i < 32; i++) { - LC3_FLOAT re, im, wre, wim, tre, tim; - - re = temp2[2 * i]; - im = temp2[2 * i + 1]; - - wre = w[i]; - wim = w[i + 16]; - - tre = re * wre - im * wim; - tim = re * wim + im * wre; - - vec[2 * i] = temp1[2 * i] + tre; - vec[2 * i + 1] = temp1[2 * i + 1] + tim; - vec[2 * i + 64] = temp1[2 * i] - tre; - vec[2 * i + 65] = temp1[2 * i + 1] - tim; - } -} - -static void fft128(LC3_FLOAT* vec) -{ - const LC3_FLOAT w[] = { - 1.0000000000f, 0.9987954562f, 0.9951847267f, 0.9891765100f, 0.9807852804f, 0.9700312532f, 0.9569403357f, - 0.9415440652f, 0.9238795325f, 0.9039892931f, 0.8819212643f, 0.8577286100f, 0.8314696123f, 0.8032075315f, - 0.7730104534f, 0.7409511254f, 0.7071067812f, 0.6715589548f, 0.6343932842f, 0.5956993045f, 0.5555702330f, - 0.5141027442f, 0.4713967368f, 0.4275550934f, 0.3826834324f, 0.3368898534f, 0.2902846773f, 0.2429801799f, - 0.1950903220f, 0.1467304745f, 0.0980171403f, 0.0490676743f, 0.0000000000f, -0.0490676743f, -0.0980171403f, - -0.1467304745f, -0.1950903220f, -0.2429801799f, -0.2902846773f, -0.3368898534f, -0.3826834324f, -0.4275550934f, - -0.4713967368f, -0.5141027442f, -0.5555702330f, -0.5956993045f, -0.6343932842f, -0.6715589548f, -0.7071067812f, - -0.7409511254f, -0.7730104534f, -0.8032075315f, -0.8314696123f, -0.8577286100f, -0.8819212643f, -0.9039892931f, - -0.9238795325f, -0.9415440652f, -0.9569403357f, -0.9700312532f, -0.9807852804f, -0.9891765100f, -0.9951847267f, - -0.9987954562f, -1.0000000000f, -0.9987954562f, -0.9951847267f, -0.9891765100f, -0.9807852804f, -0.9700312532f, - -0.9569403357f, -0.9415440652f, -0.9238795325f, -0.9039892931f, -0.8819212643f, -0.8577286100f, -0.8314696123f, - -0.8032075315f, -0.7730104534f, -0.7409511254f, -0.7071067812f, -0.6715589548f, -0.6343932842f, -0.5956993045f, - -0.5555702330f, -0.5141027442f, -0.4713967368f, -0.4275550934f, -0.3826834324f, -0.3368898534f, -0.2902846773f, - -0.2429801799f, -0.1950903220f, -0.1467304745f, -0.0980171403f, -0.0490676743f, - }; - - LC3_FLOAT temp1[128], temp2[128]; - LC3_INT i; - - for (i = 0; i < 64; i++) { - temp1[2 * i] = vec[4 * i]; - temp1[2 * i + 1] = vec[4 * i + 1]; - temp2[2 * i] = vec[4 * i + 2]; - temp2[2 * i + 1] = vec[4 * i + 3]; - } - - fft64(temp1); - fft64(temp2); - - for (i = 0; i < 64; i++) { - LC3_FLOAT re, im, wre, wim, tre, tim; - - re = temp2[2 * i]; - im = temp2[2 * i + 1]; - - wre = w[i]; - wim = w[i + 32]; - - tre = re * wre - im * wim; - tim = re * wim + im * wre; - - vec[2 * i] = temp1[2 * i] + tre; - vec[2 * i + 1] = temp1[2 * i + 1] + tim; - vec[2 * i + 128] = temp1[2 * i] - tre; - vec[2 * i + 129] = temp1[2 * i + 1] - tim; - } -} diff --git a/lib_lc3plus/fft/fft_generic.h b/lib_lc3plus/fft/fft_generic.h deleted file mode 100644 index 903875ab5..000000000 --- a/lib_lc3plus/fft/fft_generic.h +++ /dev/null @@ -1,699 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -/* guard against unindended includes */ -#ifndef INCLUDED_FROM_IISFFT_C -#error "this file must not be included" -#endif - -#define FFT_INTERNAL_TRIG_PREC double -#define BORDER_FOR_SECOND_SCRATCH 100 - -static const LC3_INT primeFactors[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, - 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, - 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, - 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 0}; - -/* fft, returns 1 if length is supported and fft was applied */ -static LC3_INT fft_n(LC3_FLOAT* x, LC3_INT length) -{ - switch (length) { - case 2: - fft2(x); - return 1; - case 3: - fft3(x); - return 1; - case 4: - fft4(x); - return 1; - case 5: - fft5(x); - return 1; - case 8: - fft8(x); - return 1; - case 9: - fft9(x); - return 1; - case 15: - fft15(x); - return 1; - case 16: - fft16(x); - return 1; - case 32: - fft32(x); - return 1; - case 60: - fft60(x); - return 1; - case 64: - fft64(x); - return 1; - case 128: - fft128(x); - return 1; - case 240: - fft240(x); - return 1; - case 256: - LC3_cfft(x, x + 1, 256, 2, -1); - return 1; - case 384: - fft384(x); - return 1; - case 480: - fft480(x); - return 1; - case 512: - LC3_cfft(x, x + 1, 512, 2, -1); - return 1; - case 1024: - LC3_cfft(x, x + 1, 1024, 2, -1); - return 1; - default: - return 0; - } -} - - -/* returns 1 on success or 0 if IISFFT_MAXFACTORS is too small */ -static LC3_INT factorize(LC3_INT length, LC3_INT* restrict numFactors, LC3_INT* restrict factor, - LC3_INT* restrict isPrime) -{ - LC3_INT remainder = length; - LC3_INT idx = 0, cnt = 0; - LC3_INT actFac = primeFactors[idx]; - LC3_INT inc = 0; - - *numFactors = 0; - - while (remainder > 1 && actFac != 0) { - if (remainder % actFac == 0) { - if (inc == 0) { - inc = 1; - (*numFactors)++; - } - remainder /= actFac; - } else { - actFac = primeFactors[++idx]; - inc = 0; - } - } - if (remainder > 1) { - (*numFactors)++; - } - - if (*numFactors > IISFFT_MAXFACTORS) - return 0; - - idx = 0, cnt = 0, inc = 0; - remainder = length; - actFac = primeFactors[idx]; - (factor)[cnt] = 1; - while (remainder > 1 && actFac != 0) { - if (remainder % actFac == 0) { - (factor)[cnt] *= actFac; - remainder /= actFac; - inc = 1; - if (factor[cnt] == actFac) { /* first appearance of the factor */ - isPrime[cnt] = 1; - } else { - isPrime[cnt] = 0; - } - } else { - actFac = primeFactors[++idx]; - if (inc == 1) { - cnt++; - } - inc = 0; - (factor)[cnt] = 1; - } - } - if (remainder > 1) { - factor[cnt] = remainder; - } - return 1; -} - -static void oddFFT(LC3_FLOAT* restrict x, LC3_INT length, LC3_FLOAT* restrict scratch) -{ - LC3_INT i, k, n; - LC3_FLOAT * src1, *src2, *dest1, *dest2; - FFT_INTERNAL_TRIG_PREC sinValOrg, cosValOrg; - - dest1 = scratch + 1; - dest2 = scratch + length + 1; - src1 = x + 2; - src2 = x + 2 * length - 1; - - scratch[0] = x[0]; - scratch[length] = x[1]; - - for (i = 2; i < length; i += 2) { - LC3_FLOAT tmp1R, tmp1I, tmp2R, tmp2I; - tmp1R = *src1++; - tmp1I = *src1++; - tmp2I = *src2--; - tmp2R = *src2--; - *dest1++ = tmp1R + tmp2R; - *dest1++ = tmp1R - tmp2R; - *dest2++ = tmp1I + tmp2I; - *dest2++ = tmp1I - tmp2I; - - x[0] += tmp1R + tmp2R; - x[1] += tmp1I + tmp2I; - } - - dest1 = x + 2; - dest2 = x + 2 * length - 2; - for (k = 2; k < length; k += 2) { - FFT_INTERNAL_TRIG_PREC sinVal = 0, cosVal = 1; - cosValOrg = LC3_COS(-M_PIl * k / length); - sinValOrg = LC3_SIN(-M_PIl * k / length); - - *dest1 = *dest2 = scratch[0]; - *(dest1 + 1) = *(dest2 + 1) = scratch[length]; - - src1 = scratch + 1; - src2 = scratch + length + 1; - - for (n = 2; n < length; n += 2) { - LC3_FLOAT rePre, reMre, imPim, imMim; - /* - cos(x+y) = cox(x) cos(y) - sin(x) sin(y); - sin(x+y) = sin(x) cos(y) + cos(x) sin(y); - */ - FFT_INTERNAL_TRIG_PREC tmp = cosVal * cosValOrg - sinVal * sinValOrg; - sinVal = sinVal * cosValOrg + cosVal * sinValOrg; - cosVal = tmp; - - rePre = *src1++; - reMre = *src1++; - imPim = *src2++; - imMim = *src2++; - - *dest1 += (LC3_FLOAT)cosVal * rePre - (LC3_FLOAT)sinVal * imMim; - *(dest1 + 1) += (LC3_FLOAT)sinVal * reMre + (LC3_FLOAT)cosVal * imPim; - *dest2 += (LC3_FLOAT)cosVal * rePre + (LC3_FLOAT)sinVal * imMim; - *(dest2 + 1) += (LC3_FLOAT)-sinVal * reMre + (LC3_FLOAT)cosVal * imPim; - } - dest1 += 2; - dest2 -= 2; - } -} - -static LC3_INT findInverse(LC3_INT a, LC3_INT b) -{ - LC3_INT b0 = b, t, q; - LC3_INT x0 = 0, x1 = 1; - - if (b == 1) { - return 1; - } - - while (a > 1) { - q = a / b; - t = b, b = a % b, a = t; - t = x0, x0 = x1 - q * x0, x1 = t; - } - - if (x1 < 0) { - x1 += b0; - } - - return x1; -} - -static LC3_INT getGeneratorStupid(LC3_INT groupLength) -{ - LC3_INT generator = 2; /* start value */ - LC3_INT count = 1, number = generator; - - while (generator < 100) { /* hopefully the generator is smaller than 100 */ - while (number != 1) { - number = (number * generator) % groupLength; - count++; - } - if (count == groupLength - 1) { - return generator; - } else { - generator++; - count = 1; - number = generator; - } - } - - return -1; -} - -static LC3_INT getGenerator(LC3_INT groupLength) -{ - LC3_INT generator = 2; /* start value */ - LC3_INT count, number, factorCount, found, count2; - LC3_INT factors[16] = {0}; - - /* factorize: only for a group length with factors < 300 */ - factorCount = 0; - number = groupLength - 1; - found = 0; - count = 0; - while (number != 1) { - if (primeFactors[count] == 0) { - /* Not all factors listed */ - return getGeneratorStupid(groupLength); - } - if (number % primeFactors[count] == 0) { - number /= primeFactors[count]; - if (found == 0) { - factors[factorCount++] = primeFactors[count]; - found = 1; - } - } else { - count++; - found = 0; - } - } - - for (count = 0; factors[count] != 0; count++) { - factors[count] = (groupLength - 1) / factors[count]; - } - - /* calculate generator */ - number = generator; - count = 0; - while (factors[count] != 0) { - for (count2 = 0; count2 < factors[count] - 1; count2++) { - number = (number * generator) % groupLength; - } - if (number != 1) { - count++; - number = generator; - if (factors[count] == 0) { - return generator; - } - } else { - count = 0; - generator++; - number = generator; - } - } - - return -1; -} - -static void primeFFT(LC3_FLOAT* restrict x, LC3_INT length, LC3_FLOAT* restrict scratch, LC3_INT* restrict scratch2) -{ - LC3_INT i, k, middle = (length - 1) / 2; - LC3_FLOAT *src1, *src2, *dest1, *dest2; - LC3_INT * mapping, *map; - LC3_INT generator; - - LC3_INT mappingTable[25][97] = { - {0, 2}, - {0, 2, 4}, - {0, 2, 4, 8, 6}, - {0, 2, 6, 4, 12, 8, 10}, - {0, 2, 4, 8, 16, 10, 20, 18, 14, 6, 12}, - {0, 2, 4, 8, 16, 6, 12, 24, 22, 18, 10, 20, 14}, - {0, 2, 6, 18, 20, 26, 10, 30, 22, 32, 28, 16, 14, 8, 24, 4, 12}, - {0, 2, 4, 8, 16, 32, 26, 14, 28, 18, 36, 34, 30, 22, 6, 12, 24, 10, 20}, - {0, 2, 10, 4, 20, 8, 40, 16, 34, 32, 22, 18, 44, 36, 42, 26, 38, 6, 30, 12, 14, 24, 28}, - {0, 2, 4, 8, 16, 32, 6, 12, 24, 48, 38, 18, 36, 14, 28, 56, 54, 50, 42, 26, 52, 46, 34, 10, 20, 40, 22, 44, 30}, - {0, 2, 6, 18, 54, 38, 52, 32, 34, 40, 58, 50, 26, 16, 48, 20, - 60, 56, 44, 8, 24, 10, 30, 28, 22, 4, 12, 36, 46, 14, 42}, - {0, 2, 4, 8, 16, 32, 64, 54, 34, 68, 62, 50, 26, 52, 30, 60, 46, 18, 36, - 72, 70, 66, 58, 42, 10, 20, 40, 6, 12, 24, 48, 22, 44, 14, 28, 56, 38}, - {0, 2, 12, 72, 22, 50, 54, 78, 58, 20, 38, 64, 56, 8, 48, 42, 6, 36, 52, 66, 68, - 80, 70, 10, 60, 32, 28, 4, 24, 62, 44, 18, 26, 74, 34, 40, 76, 46, 30, 16, 14}, - {0, 2, 6, 18, 54, 76, 56, 82, 74, 50, 64, 20, 60, 8, 24, 72, 44, 46, 52, 70, 38, 28, - 84, 80, 68, 32, 10, 30, 4, 12, 36, 22, 66, 26, 78, 62, 14, 42, 40, 34, 16, 48, 58}, - {0, 2, 10, 50, 62, 28, 46, 42, 22, 16, 80, 24, 26, 36, 86, 54, 82, 34, 76, 4, 20, 6, 30, 56, - 92, 84, 44, 32, 66, 48, 52, 72, 78, 14, 70, 68, 58, 8, 40, 12, 60, 18, 90, 74, 88, 64, 38}, - {0, 2, 4, 8, 16, 32, 64, 22, 44, 88, 70, 34, 68, 30, 60, 14, 28, 56, 6, 12, 24, 48, 96, 86, 66, 26, 52, - 104, 102, 98, 90, 74, 42, 84, 62, 18, 36, 72, 38, 76, 46, 92, 78, 50, 100, 94, 82, 58, 10, 20, 40, 80, 54}, - {0, 2, 4, 8, 16, 32, 64, 10, 20, 40, 80, 42, 84, 50, 100, 82, 46, 92, 66, 14, - 28, 56, 112, 106, 94, 70, 22, 44, 88, 58, 116, 114, 110, 102, 86, 54, 108, 98, 78, 38, - 76, 34, 68, 18, 36, 72, 26, 52, 104, 90, 62, 6, 12, 24, 48, 96, 74, 30, 60}, - {0, 2, 4, 8, 16, 32, 64, 6, 12, 24, 48, 96, 70, 18, 36, 72, 22, 44, 88, 54, 108, - 94, 66, 10, 20, 40, 80, 38, 76, 30, 60, 120, 118, 114, 106, 90, 58, 116, 110, 98, 74, 26, - 52, 104, 86, 50, 100, 78, 34, 68, 14, 28, 56, 112, 102, 82, 42, 84, 46, 92, 62}, - {0, 2, 4, 8, 16, 32, 64, 128, 122, 110, 86, 38, 76, 18, 36, 72, 10, 20, 40, 80, 26, 52, 104, - 74, 14, 28, 56, 112, 90, 46, 92, 50, 100, 66, 132, 130, 126, 118, 102, 70, 6, 12, 24, 48, 96, 58, - 116, 98, 62, 124, 114, 94, 54, 108, 82, 30, 60, 120, 106, 78, 22, 44, 88, 42, 84, 34, 68}, - {0, 2, 14, 98, 118, 116, 102, 4, 28, 54, 94, 90, 62, 8, 56, 108, 46, 38, 124, 16, 112, 74, 92, 76, - 106, 32, 82, 6, 42, 10, 70, 64, 22, 12, 84, 20, 140, 128, 44, 24, 26, 40, 138, 114, 88, 48, 52, 80, - 134, 86, 34, 96, 104, 18, 126, 30, 68, 50, 66, 36, 110, 60, 136, 100, 132, 72, 78, 120, 130, 58, 122}, - {0, 2, 10, 50, 104, 82, 118, 6, 30, 4, 20, 100, 62, 18, 90, 12, 60, 8, 40, - 54, 124, 36, 34, 24, 120, 16, 80, 108, 102, 72, 68, 48, 94, 32, 14, 70, 58, 144, - 136, 96, 42, 64, 28, 140, 116, 142, 126, 46, 84, 128, 56, 134, 86, 138, 106, 92, 22, - 110, 112, 122, 26, 130, 66, 38, 44, 74, 78, 98, 52, 114, 132, 76, 88}, - {0, 2, 6, 18, 54, 4, 12, 36, 108, 8, 24, 72, 58, 16, 48, 144, 116, 32, 96, 130, - 74, 64, 34, 102, 148, 128, 68, 46, 138, 98, 136, 92, 118, 38, 114, 26, 78, 76, 70, 52, - 156, 152, 140, 104, 154, 146, 122, 50, 150, 134, 86, 100, 142, 110, 14, 42, 126, 62, 28, 84, - 94, 124, 56, 10, 30, 90, 112, 20, 60, 22, 66, 40, 120, 44, 132, 80, 82, 88, 106}, - {0, 2, 4, 8, 16, 32, 64, 128, 90, 14, 28, 56, 112, 58, 116, 66, 132, 98, 30, 60, 120, - 74, 148, 130, 94, 22, 44, 88, 10, 20, 40, 80, 160, 154, 142, 118, 70, 140, 114, 62, 124, 82, - 164, 162, 158, 150, 134, 102, 38, 76, 152, 138, 110, 54, 108, 50, 100, 34, 68, 136, 106, 46, 92, - 18, 36, 72, 144, 122, 78, 156, 146, 126, 86, 6, 12, 24, 48, 96, 26, 52, 104, 42, 84}, - {0, 2, 6, 18, 54, 162, 130, 34, 102, 128, 28, 84, 74, 44, 132, 40, 120, 4, - 12, 36, 108, 146, 82, 68, 26, 78, 56, 168, 148, 88, 86, 80, 62, 8, 24, 72, - 38, 114, 164, 136, 52, 156, 112, 158, 118, 176, 172, 160, 124, 16, 48, 144, 76, 50, - 150, 94, 104, 134, 46, 138, 58, 174, 166, 142, 70, 32, 96, 110, 152, 100, 122, 10, - 30, 90, 92, 98, 116, 170, 154, 106, 140, 64, 14, 42, 126, 22, 66, 20, 60}, - {0, 2, 10, 50, 56, 86, 42, 16, 80, 12, 60, 106, 142, 128, 58, 96, 92, 72, 166, 54, - 76, 186, 154, 188, 164, 44, 26, 130, 68, 146, 148, 158, 14, 70, 156, 4, 20, 100, 112, 172, - 84, 32, 160, 24, 120, 18, 90, 62, 116, 192, 184, 144, 138, 108, 152, 178, 114, 182, 134, 88, - 52, 66, 136, 98, 102, 122, 28, 140, 118, 8, 40, 6, 30, 150, 168, 64, 126, 48, 46, 36, - 180, 124, 38, 190, 174, 94, 82, 22, 110, 162, 34, 170, 74, 176, 104, 132, 78}}; - - if (length < BORDER_FOR_SECOND_SCRATCH) { - for (i = 1;; i++) { - if (primeFactors[i] == length) { - mapping = mappingTable[i]; - break; - } - assert(primeFactors[i] != 0); - } - } else { - mapping = scratch2; - - /* get primitive root */ - generator = getGenerator(length); - assert(generator != -1); - - /* init mapping */ - mapping[0] = 0; - mapping[1] = 1; - for (i = 2; i < length; i++) { - mapping[i] = mapping[i - 1] * generator; - if (mapping[i] > length - 1) { - mapping[i] = (mapping[i] % length - 1) + 1; - } - } - - /* double mapping value */ - for (i = 1; i < length; i++) { - mapping[i] *= 2; - } - } - - /* remap input to scratch */ - scratch[0] = x[0]; - scratch[1] = x[1]; - scratch[2] = x[2]; - scratch[3] = x[3]; - map = mapping + length - 1; - for (i = 4; i < 2 * length; map--) { - scratch[i++] = x[(*map)]; - scratch[i++] = x[(*map) + 1]; - } - - /* print sums and diffs into scratch by using symmetry */ - x[length] = x[1]; /* imaginary und real part */ - dest1 = x + 1; - dest2 = x + length + 1; - src1 = scratch + 2; - src2 = scratch + length + 1; - - for (i = 2; i < length; i += 2) { - LC3_FLOAT tmp1R, tmp1I, tmp2R, tmp2I; - tmp1R = *src1++; - tmp1I = *src1++; - tmp2R = *src2++; - tmp2I = *src2++; - *dest1++ = tmp1R + tmp2R; - *dest1++ = tmp1R - tmp2R; - *dest2++ = tmp1I + tmp2I; - *dest2++ = tmp1I - tmp2I; - - scratch[0] += tmp1R + tmp2R; - scratch[1] += tmp1I + tmp2I; - } - - /* init with values from the first column */ - dest1 = scratch + 2; - for (i = 1; i < length; i++) { - *dest1++ = x[0]; /* add real part of x(0)(factor = 1) */ - *dest1++ = x[length]; /* add imaginary part of x(0)(factor = 1) */ - } - - for (k = 1; k <= middle; k++) { - /* loop through all cos/sin values */ - LC3_FLOAT sinVal, cosVal; - LC3_INT length1, length2; - LC3_FLOAT rePre, reMre, imPim, imMim; - - cosVal = (LC3_FLOAT)LC3_COS(-M_PIl * mapping[k] / length); - sinVal = (LC3_FLOAT)LC3_SIN(-M_PIl * mapping[k] / length); - - /* compute in two parts (length1, length2) to avoid if() in for loop */ - length1 = middle - k + 1; - length2 = middle - length1; - src1 = x + 1; - src2 = x + length + 1; - dest1 = scratch + 2 * k; - dest2 = scratch + 2 * (middle + k); - - for (i = 0; i < length1; i++) { - rePre = *src1++; - reMre = *src1++; - imPim = *src2++; - imMim = *src2++; - - *dest1++ += cosVal * rePre - sinVal * imMim; - *dest1++ += cosVal * imPim + sinVal * reMre; - - *dest2++ += cosVal * rePre + sinVal * imMim; - *dest2++ += cosVal * imPim - sinVal * reMre; - } - if (dest2 == scratch + 2 * length) { - dest2 = scratch + 2; - } - for (i = 0; i < length2; i++) { - rePre = *src1++; - reMre = *src1++; - imPim = *src2++; - imMim = *src2++; - - *dest1++ += cosVal * rePre - sinVal * imMim; - *dest1++ += cosVal * imPim + sinVal * reMre; - - *dest2++ += cosVal * rePre + sinVal * imMim; - *dest2++ += cosVal * imPim - sinVal * reMre; - } - } - - /* remap output to x */ - x[0] = scratch[0]; - x[1] = scratch[1]; - map = mapping + 1; - for (i = 2; i < 2 * length; map++) { - x[(*map)] = scratch[i++]; - x[(*map) + 1] = scratch[i++]; - } -} - -static void nextFFT(LC3_FLOAT* x, LC3_INT length, LC3_FLOAT* scratch) -{ - if (fft_n(x, length)) /* have function for length */ - return; - - assert(length % 2 != 0); - oddFFT(x, length, scratch); -} - -static inline LC3_INT findFactor(const LC3_INT length) -{ - static const LC3_INT factors[] = {16, 9, 8, 7, 5, 4, 3, 2, 0}; - LC3_INT i = 0, factor = 0; - for (i = 0; factors[i] != 0; i++) { - if (length % factors[i] == 0) { - factor = factors[i]; - break; - } - } - return factor; -} - -static inline void twiddle(LC3_FLOAT* x, const LC3_INT length, const LC3_INT n1, const LC3_INT n2) -{ - LC3_INT i, ii; - FFT_INTERNAL_TRIG_PREC sinValOrg, cosValOrg; - FFT_INTERNAL_TRIG_PREC sinVal = 0, cosVal = 1; - FFT_INTERNAL_TRIG_PREC twReal = 0, twImag = 1; - - cosValOrg = LC3_COS(-2 * (LC3_FLOAT)M_PIl / length); - sinValOrg = LC3_SIN(-2 * (LC3_FLOAT)M_PIl / length); - - for (i = 1; i < n1; i++) { - FFT_INTERNAL_TRIG_PREC tmp = 0.; - twReal = 1; - twImag = 0; - - tmp = cosVal * cosValOrg - sinVal * sinValOrg; - sinVal = sinVal * cosValOrg + cosVal * sinValOrg; - cosVal = tmp; - - for (ii = 1; ii < n2; ii++) { - LC3_FLOAT xRe, xIm; - FFT_INTERNAL_TRIG_PREC tmpReal; - - tmpReal = twReal * cosVal - twImag * sinVal; - twImag = twImag * cosVal + sinVal * twReal; - twReal = tmpReal; - - xRe = x[2 * (i * n2 + ii)]; - xIm = x[2 * (i * n2 + ii) + 1]; - - x[2 * (i * n2 + ii)] = (LC3_FLOAT)twReal * xRe - (LC3_FLOAT)twImag * xIm; - x[2 * (i * n2 + ii) + 1] = (LC3_FLOAT)twImag * xRe + (LC3_FLOAT)twReal * xIm; - } - } -} - -static void cooleyTukeyFFT(LC3_FLOAT* restrict x, const LC3_INT length, LC3_FLOAT* restrict scratch, - LC3_INT* restrict scratch2, LC3_INT isPrime) -{ - LC3_INT factor; - LC3_INT i, ii; - LC3_INT n1, n2; - LC3_INT cnt = 0; - LC3_FLOAT *src, *dest; - - if (fft_n(x, length)) - return; - - factor = findFactor(length); - if (factor > 0 && (length / factor > 1)) { - n1 = factor; - n2 = length / factor; - - /* DATA Resorting for stage1 */ - dest = scratch; - for (i = 0; i < 2 * n1; i += 2) { - src = x + i; - for (ii = 0; ii < n2; ii++) { - /* *dest++ = x[2*(i+ii*n1)]; */ - /* *dest++ = x[2*(i+ii*n1)+1]; */ - *dest++ = *src; - *dest++ = *(src + 1); - src += 2 * n1; - } - } - src = scratch; - dest = x; - for (i = 0; i < length; i++) { - *dest++ = *src++; - *dest++ = *src++; - } - /* perform n1 ffts of length n2 */ - for (i = 0; i < n1; i++) { - cooleyTukeyFFT(x + 2 * i * n2, n2, scratch + 2 * i * n2, scratch2, isPrime); - } - /*data twiddeling */ - twiddle(x, length, n1, n2); - /* DATA Resorting for stage2 */ - cnt = 0; - for (i = 0; i < n2; i++) { - for (ii = 0; ii < n1; ii++) { - scratch[2 * cnt] = x[2 * (i + ii * n2)]; - scratch[2 * cnt + 1] = x[2 * (i + ii * n2) + 1]; - cnt++; - } - } - /* perform n2 ffts of length n1 */ - for (i = 0; i < n2; i++) { - nextFFT(scratch + 2 * i * n1, n1, x + 2 * i * n1); - } - cnt = 0; - for (i = 0; i < n1; i++) { - for (ii = 0; ii < n2; ii++) { - x[2 * cnt] = scratch[2 * (i + ii * n1)]; - x[2 * cnt + 1] = scratch[2 * (i + ii * n1) + 1]; - cnt++; - } - } - } else { - if (isPrime == 1 && length > 23) { - primeFFT(x, length, scratch, scratch2); - } else { - oddFFT(x, length, scratch); - } - } -} - -static void pfaDFT(LC3_FLOAT* restrict x, const LC3_INT length, LC3_FLOAT* restrict scratch1, const LC3_INT numFactors, - const LC3_INT* const factor, LC3_INT* restrict scratch2, const LC3_INT* const isPrime) -{ - LC3_FLOAT* tmp = scratch1; - LC3_INT i, ii, n1, n2, idx, incr, cnt; - LC3_INT n1_inv = 1; - - if (numFactors <= 1) { - cooleyTukeyFFT(x, length, scratch1, scratch2, isPrime[0]); - return; - } - - n2 = factor[0]; - n1 = length / n2; - - n1_inv = findInverse(n1, n2); - - idx = 0; - incr = n1 * n1_inv; - cnt = 0; - for (i = 0; i < n1; i++) { - for (ii = 0; ii < n2 - 1; ii++) { - tmp[cnt++] = x[2 * idx]; - tmp[cnt++] = x[2 * idx + 1]; - - idx += incr; - if (idx > length) { - idx -= length; - } - } - tmp[cnt++] = x[2 * idx]; - tmp[cnt++] = x[2 * idx + 1]; - idx++; - } - - for (cnt = 0; cnt < length; cnt += n2) { - cooleyTukeyFFT(tmp + 2 * cnt, n2, x + 2 * cnt, scratch2, isPrime[0]); - } - for (cnt = 0; cnt < n1; cnt++) { - for (i = 0; i < n2; i++) { - x[2 * (cnt + i * n1)] = tmp[2 * (cnt * n2 + i)]; - x[2 * (cnt + i * n1) + 1] = tmp[2 * (cnt * n2 + i) + 1]; - } - } - for (cnt = 0; cnt < length; cnt += n1) { - pfaDFT(x + 2 * cnt, n1, tmp, numFactors - 1, &factor[1], scratch2, &isPrime[1]); - } - - cnt = 0; - for (i = 0; i < n2; i++) { - idx = i * n1; - for (ii = 0; ii < n1; ii++) { - tmp[2 * idx] = x[cnt++]; - tmp[2 * idx + 1] = x[cnt++]; - idx += n2; - if (idx > length) { - idx -= length; - } - } - } - - for (cnt = 0; cnt < length; cnt++) { - x[2 * cnt] = tmp[2 * cnt]; - x[2 * cnt + 1] = tmp[2 * cnt + 1]; - } -} diff --git a/lib_lc3plus/fft/iis_fft.c b/lib_lc3plus/fft/iis_fft.c deleted file mode 100644 index be71d8e4a..000000000 --- a/lib_lc3plus/fft/iis_fft.c +++ /dev/null @@ -1,172 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include -#include -#include -#include -#include -#include -#include "iis_fft.h" - -/**************************************************************************************************/ - -/* AFFT uses two fft implementations - * cfft is used for lengths of power of two, >= 256. - * iisfft is used for everything else. it is optimized for certain lengths. for a list of - fast lengths, check the fft_n function. -*/ - -#define FFT_COMPLEX 1 -#define FFT_REAL 2 - - -static IIS_FFT_ERROR create(HANDLE_IIS_FFT* handle, LC3_INT type, LC3_INT len, IIS_FFT_DIR sign) -{ - IIS_FFT_ERROR err = IIS_FFT_MEMORY_ERROR; - - /* for real transforms the actual performed fft is half length */ - LC3_INT trlen = (type == FFT_COMPLEX) ? len : len / 2; - - /* check argument sanity */ - if ((sign != IIS_FFT_FWD) && (sign != IIS_FFT_BWD)) - { - return IIS_FFT_INTERNAL_ERROR; - } - - if (!(*handle)) - { - (*handle) = (HANDLE_IIS_FFT)calloc(1, sizeof(IIS_FFT)); - } - - if (!(*handle)) - { - return IIS_FFT_MEMORY_ERROR; - } - - (*handle)->len = len; - (*handle)->sign = sign; - - /* create sine lookup table for real ffts */ - if (type == FFT_REAL) - { - LC3_create_sine_table(len, (*handle)->sine_table); - if (!(*handle)->sine_table) - { - goto handle_error1; - } - } - - /* set default cfft_plan to 0(length). (and default iisfft_plan to zero length) */ - (*handle)->cfft.len = 0; /* 0 length means that cfft should not be called */ - (*handle)->iisfft.length = 0; /*saftey setting for iisfft length struct */ - - /* use cfft for legth of power two larger than 256. for length below iisfft is faster */ - if (trlen >= 256 && CFFT_PLAN_SUPPORT(trlen)) { - LC3_INT s = (type == FFT_REAL) ? IIS_FFT_FWD : sign; - err = LC3_cfft_plan(&(*handle)->cfft, trlen, s) ? IIS_FFT_NO_ERROR : IIS_FFT_INTERNAL_ERROR; - } else { - LC3_INT s = (type == FFT_REAL) ? IIS_FFT_FWD : sign; - err = LC3_iisfft_plan(&(*handle)->iisfft, trlen, s); - } - - return IIS_FFT_NO_ERROR; - -handle_error1: - free((*handle)); - - return err; -} - -IIS_FFT_ERROR LC3_IIS_RFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT32 len, IIS_FFT_DIR sign) -{ - return create(handle, FFT_REAL, len, sign); -} - -static IIS_FFT_ERROR destroy(HANDLE_IIS_FFT* handle) -{ - if (handle && *handle) { - LC3_iisfft_free(&(*handle)->iisfft); - LC3_cfft_free(&(*handle)->cfft); - free(*handle); - *handle = NULL; - } - return IIS_FFT_NO_ERROR; -} - -IIS_FFT_ERROR LC3_IIS_CFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT len, IIS_FFT_DIR sign) -{ - return create(handle, FFT_COMPLEX, len, sign); -} - - -IIS_FFT_ERROR LC3_IIS_xFFT_Destroy(HANDLE_IIS_FFT* handle) { return destroy(handle); } - -IIS_FFT_ERROR LC3_IIS_CFFT_Destroy(HANDLE_IIS_FFT* handle) { return destroy(handle); } - -static IIS_FFT_ERROR real_destroy(HANDLE_IIS_FFT* handle) -{ - if (handle && *handle) { - LC3_iisfft_free(&(*handle)->iisfft); - *handle = NULL; - } - return IIS_FFT_NO_ERROR; -} - -IIS_FFT_ERROR LC3_IIS_RFFT_Destroy(HANDLE_IIS_FFT* handle) { return real_destroy(handle); } - -IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input, Complex* output) -{ - LC3_FLOAT* dummy; - if (!handle) - { - return IIS_FFT_INTERNAL_ERROR; - } - - /* check for inplace operation */ - memmove(output, input, sizeof(*input) * handle->len); - dummy = (LC3_FLOAT*)output; - if (handle->cfft.len > 0) { - LC3_cfft_apply(&handle->cfft, dummy, dummy + 1, 2); - } else { - LC3_iisfft_apply(&handle->iisfft, dummy); - } - - return IIS_FFT_NO_ERROR; -} - - -IIS_FFT_ERROR LC3_IIS_FFT_Apply_RFFT(HANDLE_IIS_FFT handle, const LC3_FLOAT* in, LC3_FLOAT* out) -{ - if (!handle) { - return IIS_FFT_INTERNAL_ERROR; - } - - memmove(out, in, sizeof(LC3_FLOAT) * handle->len); - - if (handle->sign == IIS_FFT_BWD) { - LC3_rfft_pre(handle->sine_table, out, handle->len); - } - - if (handle->cfft.len > 0) { - LC3_cfft_apply(&handle->cfft, out, out + 1, 2); - } - else { - LC3_iisfft_apply(&handle->iisfft, out); - } - - if (handle->sign == IIS_FFT_FWD) { - LC3_rfft_post(handle->sine_table, out, handle->len); - } - - return IIS_FFT_NO_ERROR; -} diff --git a/lib_lc3plus/fft/iis_fft.h b/lib_lc3plus/fft/iis_fft.h deleted file mode 100644 index a145c490d..000000000 --- a/lib_lc3plus/fft/iis_fft.h +++ /dev/null @@ -1,144 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#ifndef IIS_FFT_H -#define IIS_FFT_H - -#include "options.h" -#include "wmc_auto.h" -#include "../structs.h" -#include "../defines.h" -#include "cfft.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/*! - * \brief n-point complex FFT - * - * There are optimized FFTs for lengths 2, 3, 4, 7, 8, 9, 15, 16, 32, 60, 64, 128, - * 240, 256, 384, 480, 512, 768, 1024. Other lengths below 1024 use a stack allocated - * buffer and offer reasonable speed. Above 1024 a buffer is allocated each time - * iis_fftf() is called resulting in reduced performance. - * - * >>>>>> DO NOT USE UNOPTIMIZED LENGTHS IN PRODUCTION CODE! <<<<<< - * - * \param[in,out] vec pointer to data, interleaved real / imaginary - * \param[in] length length of fft (number of real/imaginary pairs) - * - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_iis_fftf(LC3_FLOAT* vec, LC3_INT length); -/*! - * \brief n-point inverse complex FFT - * - * The output is not normalized. See iis_fftf() for optimized lengths. - * - * >>>>>> DO NOT USE UNOPTIMIZED LENGTHS IN PRODUCTION CODE! <<<<<< - * - * \param[in,out] vec pointer to data, interleaved real / imaginary - * \param[in] length length of fft (number of real/imaginary pairs) - * - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_iis_ifftf(LC3_FLOAT* vec, LC3_INT length); - -/*! - * \brief allocate and initialize a new real FFT instance. - * - * \param[in,out] handle pointer to FFT handle - * \param[in] len transform length, must be an even number - * \param[in] sign IIS_FFT_FWD(-1) for forward, IIS_FFT_BWD(1) for backward transform - * BEWARE OF THE SIGNS! - * - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_IIS_RFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT len, IIS_FFT_DIR sign); - -/*! - * \brief allocate and initialize a new complex FFT instance - * - * \param[in,out] handle pointer to FFT handle - * \param[in] len transform length - * \param[in] sign IIS_FFT_FWD(-1) for forward, IIS_FFT_BWD(1) for backward transform - * BEWARE OF THE SIGNS !!!!!! - * - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_IIS_CFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT len, IIS_FFT_DIR sign); - -/*! - * \brief computes the forward or backward fourier transform of a real signal - * - * For complex data (in or out) the real part of the Nyquist band (len / 2 + 1) is stored - * in the imaginary part of the DC band (0). This allows for the complex data of - * real to complex transforms to fit into the same buffer. For this to work length must be even. - * - * Complex to real transforms are normalized (1.0/len). Input and ouput buffers may - *be identical. - * - * \param[in] handle FFT handle - * \param[in] in pointer to the input array containing real values for the forward transform (FFT) - * or packed complex values (Perm) for the backward transform (IFFT) - * \param[out] out pointer to the output array containing real values resulted from the backward transform - * (IFFT) or packed complex (perm) values reulted from the forward transform - * - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_IIS_FFT_Apply_RFFT(HANDLE_IIS_FFT handle, const LC3_FLOAT* in, LC3_FLOAT* out); - -/*! - * \brief compute complex backward or forward FFT - * - * Input and ouput buffers may be identical. Real/imaginary parts may be interleaved. - * The output is not normalized. - * - * \param[in] handle FFT handle - * \param[in] in_re pointer to the input array containing real parts of the signal for the - * forward transform (FFT) or for the backward transform (IFFT) - * \param[in] in_im pointer to the input array containing imaginary parts of the signal for - * the forward transform (FFT) or for the backward transform (IFFT) - * \param[out] out_re pointer to the output array containing real values resulted from the - * forward transform (FFT) or from the backward transform (IFFT) - * \param[out] out_im pointer to the output array containing imaginary values resulted from - * the forward transform (FFT) or from the backward transform (IFFT) - * - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input, Complex* output); - -/*! - * \brief deallocate a FFT instance (complex or real) - * \param[in,out] handle pointer to FFT handle, set to NULL if call succeeds - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_IIS_xFFT_Destroy(HANDLE_IIS_FFT* handle); - -/*! - * \brief deallocate a real FFT instance - * \param[in,out] handle pointer to FFT handle, set to NULL if call succeeds - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_IIS_RFFT_Destroy(HANDLE_IIS_FFT* handle); - -/*! - * \brief deallocate a complex FFT instance - * \param[in,out] handle pointer to FFT handle, set to NULL if call succeeds - * \return IIS_FFT_NO_ERROR on success - */ -IIS_FFT_ERROR LC3_IIS_CFFT_Destroy(HANDLE_IIS_FFT* handle); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib_lc3plus/fft/iisfft.c b/lib_lc3plus/fft/iisfft.c deleted file mode 100644 index bcd00503f..000000000 --- a/lib_lc3plus/fft/iisfft.c +++ /dev/null @@ -1,175 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - - -#include "options.h" -#include "wmc_auto.h" -#include -#include /* for mmove */ -#include -#include -#include "iisfft.h" -#include "cfft.h" - -/* the fixed length fft functions have been split into sevelral headers to - have smaller files. to give the compiler more room to optimize the ffts - can't be in separate compilation units. the header approach seemed to be - the best compromise. to prevent them being included from anywhere else, - they are guarded by the INCLUDED_FROM_IISFFT_C macro. -*/ -#define INCLUDED_FROM_IISFFT_C -#include "fft_2_9.h" -#include "fft_15_16.h" -#include "fft_32.h" -#include "fft_60_128.h" -#include "fft_240_480.h" -#include "fft_384_768.h" -#include "fft_generic.h" - - -void LC3_iisfft_apply(Iisfft* handle, LC3_FLOAT* x) -{ - if (handle->sign == -1) { - if (!fft_n(x, handle->length)) - { - LC3_FLOAT scratch[2*MAX_LEN]; - pfaDFT(x, handle->length, scratch, handle->num_factors, handle->factors, handle->scratch2, - handle->isPrime); - } - } else { - assert(0); - } -} - -/* returns 1 if there is no specialized function for length or 1 if a scratch needs to be allocated. - check the fft_n function */ -static LC3_INT need_scratch(LC3_INT n) -{ - return n != 2 && n != 3 && n != 4 && n != 5 && n != 7 && n != 8 && n != 9 && n != 15 && n != 16 && n != 32 && - n != 60 && n != 64 && n != 128 && n != 192 && n != 240 && n != 256 && n != 384 && n != 480 && n != 512 && n != 768 && - n != 1024; -} - -IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign) -{ - memset(handle, 0, sizeof(Iisfft)); - if (length < 2) - { - return IIS_FFT_LENGTH_ERROR; - } - handle->length = length; - handle->sign = sign; - if (need_scratch(length)) { - /* only needed for prime numbers bigger than BORDER_FOR_SECOND_SCRATCH */ - LC3_INT i = 0; - LC3_INT lengthOfPrimeScratch = BORDER_FOR_SECOND_SCRATCH; - if (!factorize(length, &handle->num_factors, handle->factors, handle->isPrime)) - { - return IIS_FFT_LENGTH_ERROR; - } - /* create additional scratch for primeFFT() */ - for (i = 0; i < handle->num_factors; i++) { - if (handle->isPrime[i] == 1 && handle->factors[i] > lengthOfPrimeScratch) { - lengthOfPrimeScratch = handle->factors[i]; - } - } - if (lengthOfPrimeScratch > BORDER_FOR_SECOND_SCRATCH) { - handle->scratch2 = (LC3_INT*)malloc(sizeof(LC3_INT) * lengthOfPrimeScratch); - if (!handle->scratch2) - { - return IIS_FFT_MEMORY_ERROR; - } - } - } - - return IIS_FFT_NO_ERROR; -} - -void LC3_iisfft_free(Iisfft* handle) -{ - handle->length = 0; - if (handle->scratch2) - { - free(handle->scratch2); - } -} - - - -/* generate sine table needed by LC3_rfft_pre/rfft/post. the table must be freed with iisFree */ -void LC3_create_sine_table(LC3_INT32 len, LC3_FLOAT *sine_table) -{ - LC3_INT32 i; - - for (i = 0; i < len / 2 + 1; i++) { - sine_table[i] = (LC3_FLOAT)sin(2.0 * M_PIl * i / len); - } -} - -void LC3_rfft_post(const LC3_FLOAT* restrict sine_table, LC3_FLOAT* restrict buf, LC3_INT32 len) -{ - LC3_FLOAT tmp1, tmp2, tmp3, tmp4, s, c; - LC3_INT32 i; - - tmp1 = buf[0] + buf[1]; - buf[1] = buf[0] - buf[1]; - buf[0] = tmp1; - - for (i = 1; i <= (len + 2) / 4; i++) { - s = sine_table[i]; /* sin(pi*i/(len/2)) */ - c = sine_table[i + len / 4]; /* cos(pi*i/(len/2)) */ - - tmp1 = buf[2 * i] - buf[len - 2 * i]; - tmp2 = buf[2 * i + 1] + buf[len - 2 * i + 1]; - tmp3 = s * tmp1 - c * tmp2; /* real part of j*W(k,N)*[T(k) - T'(N-k)] */ - tmp4 = c * tmp1 + s * tmp2; /* imag part of j*W(k,N)*[T(k) - T'(N-k)] */ - tmp1 = buf[2 * i] + buf[len - 2 * i]; - tmp2 = buf[2 * i + 1] - buf[len - 2 * i + 1]; - - buf[2 * i] = 0.5f * (tmp1 - tmp3); - buf[2 * i + 1] = 0.5f * (tmp2 - tmp4); - buf[len - 2 * i] = 0.5f * (tmp1 + tmp3); - buf[len - 2 * i + 1] = -0.5f * (tmp2 + tmp4); - } - - return; -} - -void LC3_rfft_pre(const LC3_FLOAT* restrict sine_table, LC3_FLOAT* restrict buf, LC3_INT32 len) -{ - LC3_FLOAT scale ; - LC3_FLOAT tmp1, tmp2, tmp3, tmp4, s, c; - LC3_INT32 i; - - scale = 1.0f / len; /* constant */ - - tmp1 = buf[0] + buf[1]; - buf[1] = scale * (buf[0] - buf[1]); - buf[0] = scale * tmp1; - - for (i = 1; i <= (len + 2) / 4; i++) { - s = sine_table[i]; /* sin(pi*i/(len/2)) */ - c = sine_table[i + len / 4]; /* cos(pi*i/(len/2)) */ - - tmp1 = buf[2 * i] - buf[len - 2 * i]; - tmp2 = buf[2 * i + 1] + buf[len - 2 * i + 1]; - tmp3 = s * tmp1 + c * tmp2; /* real part of j*W(k,N)*[T(k) - T'(N-k)] */ - tmp4 = -c * tmp1 + s * tmp2; /* imag part of j*W(k,N)*[T(k) - T'(N-k)] */ - tmp1 = buf[2 * i] + buf[len - 2 * i]; - tmp2 = buf[2 * i + 1] - buf[len - 2 * i + 1]; - - buf[2 * i] = scale * (tmp1 + tmp3); - buf[2 * i + 1] = -scale * (tmp2 + tmp4); - buf[len - 2 * i] = scale * (tmp1 - tmp3); - buf[len - 2 * i + 1] = scale * (tmp2 - tmp4); - } - return; -} - diff --git a/lib_lc3plus/fft/iisfft.h b/lib_lc3plus/fft/iisfft.h deleted file mode 100644 index a77a1af7e..000000000 --- a/lib_lc3plus/fft/iisfft.h +++ /dev/null @@ -1,88 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#ifndef IISFFT_H -#define IISFFT_H - -#include "options.h" -#include "wmc_auto.h" -#include "../defines.h" - -#ifndef M_PIl -#define M_PIl 3.1415926535897932384626433832795029L /* pi */ -#endif - -/* compiler specific macros - - the restrict keyword only gives a improvelent if more than one pointers are - passed to a function. also note that the MSVC __restrict behaves differently - from c99, the restrict property is not transferred to aliases. - - alloca is a bit problematic because behavior is not defined in case of stack - overflow. most probably the program will crash. it might be possible to catch - those errors but it depends on compiler support. msvc has a safer _malloca - but gcc has nothing similar. */ -#if defined _MSC_VER || defined __INTEL_COMPILER -#include -#define ALLOCA(size) _alloca(size) -#define restrict __restrict -#define inline __inline -#elif defined __GNUC__ || defined __clang__ -#define ALLOCA(size) __builtin_alloca(size) -#define restrict __restrict__ -#define inline __inline -#elif defined __TI_COMPILER_VERSION__ -#include -#define ALLOCA(size) (assert(0 && "ALLOCA is not present for your compiler"), NULL) -#warn "no stack allocation for you compiler" -#else -#error "no stack allocation for your compiler" -#endif - - -#define IISFFT_MAXSTACKLENGTH 1024 -#define IISFFT_MAXFACTORS 10 - -typedef struct { - LC3_INT* scratch2; - LC3_INT length; - LC3_INT sign; - LC3_INT num_factors; - LC3_INT factors[IISFFT_MAXFACTORS]; - LC3_INT isPrime[IISFFT_MAXFACTORS]; -} Iisfft; - -typedef enum { - IIS_FFT_NO_ERROR = 0, - IIS_FFT_INTERNAL_ERROR, /**< a mystical error appeard */ - IIS_FFT_LENGTH_ERROR, /**< the requested fft length is not supported */ - IIS_FFT_MEMORY_ERROR /**< memory allocation failed */ -} IIS_FFT_ERROR; - -typedef enum { - IIS_FFT_FWD = -1, /**< forward transform */ - IIS_FFT_BWD = 1 /**< inverse / backward transform */ -} IIS_FFT_DIR; - -/* plan, apply and free forward / backward fft */ -IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign); -void LC3_iisfft_apply(Iisfft* handle, LC3_FLOAT* x); -void LC3_iisfft_free(Iisfft* handle); - -/* fft related helper functions */ -void LC3_create_sine_table(LC3_INT32 len, LC3_FLOAT *sine_table); - -void LC3_rfft_pre(const LC3_FLOAT* restrict sine_table, LC3_FLOAT* restrict buf, LC3_INT len); -void LC3_rfft_post(const LC3_FLOAT* restrict sine_table, LC3_FLOAT* restrict buf, LC3_INT len); -void LC3_fftf_interleave(const LC3_FLOAT* restrict re, const LC3_FLOAT* restrict im, LC3_FLOAT* restrict out, - LC3_INT len); -void LC3_fftf_deinterleave(const LC3_FLOAT* restrict in, LC3_FLOAT* restrict re, LC3_FLOAT* restrict im, LC3_INT len); - -#endif /* IISFFT_H */ diff --git a/lib_lc3plus/fft_lc3plus.c b/lib_lc3plus/fft_lc3plus.c new file mode 100644 index 000000000..a86286d04 --- /dev/null +++ b/lib_lc3plus/fft_lc3plus.c @@ -0,0 +1,4537 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" +#include "rom_basop_util.h" + +#ifdef ENABLE_FFT_RESCALE +#ifndef FFT_RESCALE_HR +#define FFT_RESCALE_HR 3 +#endif +#endif + +#define SCALEFACTORN2 3 +#define SCALEFACTOR4 3 +#define SCALEFACTOR5 4 +#define SCALEFACTOR8 4 +#define SCALEFACTOR15 5 +#define SCALEFACTOR30_1 5 +#define SCALEFACTOR30_2 1 +#define SCALEFACTOR32_1 5 +#define SCALEFACTOR32_2 1 + +#ifdef ENABLE_HR_MODE +#define Mpy_32_xx Mpy_32_32_lc3plus +#else +#define Mpy_32_xx Mpy_32_16_lc3plus +#endif + +#ifdef CR8_G_ADD_75MS +#define SCALEFACTOR6 4 +#define C61_32 (0x6ed9eba1) +#endif + +#define SCALEFACTOR10 5 +#define SCALEFACTOR16 5 +#define SCALEFACTOR20 5 +#define SCALEFACTOR30 6 +#define SCALEFACTOR32 6 +#define SCALEFACTOR40 7 +#define SCALEFACTOR48 8 +#define SCALEFACTOR60 7 +#define SCALEFACTOR64 7 +#define SCALEFACTOR80 8 +#define SCALEFACTOR90 9 +#define SCALEFACTOR96 9 +#define SCALEFACTOR120 8 +#define SCALEFACTOR128 8 +#define SCALEFACTOR160 8 +#define SCALEFACTOR180 10 +#define SCALEFACTOR192 10 +#define SCALEFACTOR240 9 +#define SCALEFACTOR256 9 +#define SCALEFACTOR384 11 + +#ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS +#define SCALEFACTOR360 11 +#endif +#ifndef ENABLE_FFT_30X16 +#define SCALEFACTOR480 10 +#else +#define SCALEFACTOR480 11 +#endif +#endif + +#ifdef ENABLE_HR_MODE +#undef L_shr_pos +#define L_shr_pos(x, y) (L_shr(L_add(L_shr((x), ((y)-1)),1),1)) +#endif + +#ifdef ENABLE_HR_MODE +#define FFTC(x) ((Word32)x) +#else +#define FFTC(x) WORD322WORD16((Word32)x) +#endif + +#define C31 (FFTC(0x91261468)) /* FL2WORD32( -0.86602540) -sqrt(3)/2 */ + +#define C51 (FFTC(0x79bc3854)) /* FL2WORD32( 0.95105652) */ +#define C52 (FFTC(0x9d839db0)) /* FL2WORD32(-1.53884180/2) */ +#define C53 (FFTC(0xd18053ce)) /* FL2WORD32(-0.36327126) */ +#define C54 (FFTC(0x478dde64)) /* FL2WORD32( 0.55901699) */ +#define C55 (FFTC(0xb0000001)) /* FL2WORD32(-1.25/2) */ + +#define C81 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) */ +#define C82 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) */ + +#define C161 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) INV_SQRT2 */ +#define C162 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) -INV_SQRT2 */ + +#define C163 (FFTC(0x7641af3d)) /* FL2WORD32( 9.238795325112867e-1) COS_PI_DIV8 */ +#define C164 (FFTC(0x89be50c3)) /* FL2WORD32(-9.238795325112867e-1) -COS_PI_DIV8 */ + +#define C165 (FFTC(0x30fbc54d)) /* FL2WORD32( 3.826834323650898e-1) COS_3PI_DIV8 */ +#define C166 (FFTC(0xcf043ab3)) /* FL2WORD32(-3.826834323650898e-1) -COS_3PI_DIV8 */ + +#define C51_32 (0x79bc3854) /* FL2WORD32( 0.95105652) */ +#define C52_32 (0x9d839db0) /* FL2WORD32(-1.53884180/2) */ +#define C53_32 (0xd18053ce) /* FL2WORD32(-0.36327126) */ +#define C54_32 (0x478dde64) /* FL2WORD32( 0.55901699) */ +#define C55_32 (0xb0000001) /* FL2WORD32(-1.25/2) */ + + +#define C81_32 (0x5a82799a) /* FL2WORD32( 7.071067811865475e-1) */ +#define C82_32 (0xa57d8666) /* FL2WORD32(-7.071067811865475e-1) */ + +#if defined(ENABLE_HR_MODE) + +# define cplxMpy4_16_0(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)); \ + move32(); \ + im = L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)); \ + move32(); \ + } while (0) + +# define cplxMpy4_16_1(re, im, a, b) \ + do \ + { \ + re = a; \ + move32(); \ + im = b; \ + move32(); \ + } while (0) + +# endif + +#define Mpy3_0(s12, s13, s14, s15, t0, t1, t2, t3) \ + do \ + { \ + s12 = Mpy_32_32_lc3plus(L_add(t0, t2), C81_32); \ + s14 = Mpy_32_32_lc3plus(L_sub(t0, t2), C81_32); \ + s13 = Mpy_32_32_lc3plus(L_sub(t3, t1), C81_32); \ + s15 = Mpy_32_32_lc3plus(L_add(t1, t3), C82_32); \ + } while (0) + +#define cplxMpy3_0(a, b, c, d) \ + do \ + { \ + as = L_shr_pos(a, 1); \ + bs = L_shr_pos(b, 1); \ + a = L_sub(Mpy_32_32_lc3plus(as, c), Mpy_32_32_lc3plus(bs, d)); \ + b = L_add(Mpy_32_32_lc3plus(as, d), Mpy_32_32_lc3plus(bs, c)); \ + } while (0) + +#ifdef ENABLE_HR_MODE +#define cplxMpy4_4_0(re, im, a, b, c, d) \ + re = L_shr_pos(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), SCALEFACTOR60 - SCALEFACTOR15); \ + im = L_shr_pos(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), SCALEFACTOR60 - SCALEFACTOR15); + +# define cplxMpy4_4_1(re, im, a, b) \ + re = L_shr_pos(a, SCALEFACTOR60 - SCALEFACTOR15); \ + im = L_shr_pos(b, SCALEFACTOR60 - SCALEFACTOR15); +#else +#define cplxMpy4_4_0(re, im, a, b, c, d) \ + re = L_shr(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), SCALEFACTOR60 - SCALEFACTOR15); \ + im = L_shr(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), SCALEFACTOR60 - SCALEFACTOR15); + +#define cplxMpy4_4_1(re, im, a, b) \ + re = L_shr(a, SCALEFACTOR60 - SCALEFACTOR15); \ + im = L_shr(b, SCALEFACTOR60 - SCALEFACTOR15); +#endif + +#define cplxMpy4_8_0(re, im, a, b, c, d) \ + do \ + { \ + re = L_shr_pos(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), 1); \ + im = L_shr_pos(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), 1); \ + } while (0) + + +#define cplxMpy4_8_1(re, im, a, b) \ + do \ + { \ + re = L_shr_pos(a, 1); \ + im = L_shr_pos(b, 1); \ + } while (0) + + +#define cplxMpy4_8_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_shr_pos(L_add(Mpy_32_32_lc3plus(a, c), Mpy_32_32_lc3plus(b, d)), 1); \ + im = L_shr_pos(L_sub(Mpy_32_32_lc3plus(b, c), Mpy_32_32_lc3plus(a, d)), 1); \ + } while (0) + + +#define cplxMpy4_12_0(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)); \ + move32(); \ + im = L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)); \ + move32(); \ + } while (0) + +#define cplxMpy4_12_1(re, im, a, b) \ + do \ + { \ + re = a; \ + move32(); \ + im = b; \ + move32(); \ + } while (0) + + +static void fft4(Word32 *x) +{ + Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5, x6, x7; Word32 t0, t1, t2, t3, t4, t5, t6, t7;); + + x0 = L_shr_pos(x[0], SCALEFACTOR4); + x1 = L_shr_pos(x[1], SCALEFACTOR4); + x2 = L_shr_pos(x[2], SCALEFACTOR4); + x3 = L_shr_pos(x[3], SCALEFACTOR4); + x4 = L_shr_pos(x[4], SCALEFACTOR4); + x5 = L_shr_pos(x[5], SCALEFACTOR4); + x6 = L_shr_pos(x[6], SCALEFACTOR4); + x7 = L_shr_pos(x[7], SCALEFACTOR4); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + x[0] = L_add(t0, t4); + x[1] = L_add(t1, t5); + x[2] = L_sub(t2, t6); + x[3] = L_sub(t3, t7); + x[4] = L_sub(t0, t4); + x[5] = L_sub(t1, t5); + x[6] = L_add(t2, t6); + x[7] = L_add(t3, t7); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 5-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR5 bits. + * + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + + +static void fft5(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; Word32 t;); + + /* real part */ + x0 = L_shr_pos(re[s * 0], SCALEFACTOR5); + x1 = L_shr_pos(re[s * 1], SCALEFACTOR5); + x2 = L_shr_pos(re[s * 2], SCALEFACTOR5); + x3 = L_shr_pos(re[s * 3], SCALEFACTOR5); + x4 = L_shr_pos(re[s * 4], SCALEFACTOR5); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_32_lc3plus(L_sub(r1, r3), C54_32); + r1 = L_add(r1, r3); + re[0] = L_add(x0, r1); + move32(); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + r1 = L_add(re[0], (L_shl_pos(Mpy_32_32_lc3plus(r1, C55_32), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_32_lc3plus(L_add(r4, r2), C51_32); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + r4 = L_add(t, L_shl_pos(Mpy_32_32_lc3plus(r4, C52_32), 1)); + r2 = L_add(t, Mpy_32_32_lc3plus(r2, C53_32)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 0], SCALEFACTOR5); + x1 = L_shr_pos(im[s * 1], SCALEFACTOR5); + x2 = L_shr_pos(im[s * 2], SCALEFACTOR5); + x3 = L_shr_pos(im[s * 3], SCALEFACTOR5); + x4 = L_shr_pos(im[s * 4], SCALEFACTOR5); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_32_lc3plus(L_sub(s1, s3), C54_32); + s1 = L_add(s1, s3); + im[0] = L_add(x0, s1); + move32(); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + s1 = L_add(im[0], L_shl_pos(Mpy_32_32_lc3plus(s1, C55_32), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_32_lc3plus(L_add(s4, s2), C51_32); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + s4 = L_add(t, L_shl_pos(Mpy_32_32_lc3plus(s4, C52_32), 1)); + s2 = L_add(t, Mpy_32_32_lc3plus(s2, C53_32)); + + /* combination */ + re[s * 1] = L_add(r1, s2); + move32(); + re[s * 4] = L_sub(r1, s2); + move32(); + re[s * 2] = L_sub(r3, s4); + move32(); + re[s * 3] = L_add(r3, s4); + move32(); + + im[s * 1] = L_sub(s1, r2); + move32(); + im[s * 4] = L_add(s1, r2); + move32(); + im[s * 2] = L_add(s3, r4); + move32(); + im[s * 3] = L_sub(s3, r4); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 6-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR6 bits. + * + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] st stride real and imag input / output + * + * \return void + */ + +#ifdef CR8_G_ADD_75MS +static void fft6(Word32 *re, Word32 *im, Word16 st) +{ + Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5; Word32 r1o, r2o, i1e, i2e, i1o, i2o; Word32 t, s;); + + /* process real parts */ + + x0 = L_shr_pos(re[0 * st], SCALEFACTOR6); + x1 = L_shr_pos(re[1 * st], SCALEFACTOR6); + x2 = L_shr_pos(re[2 * st], SCALEFACTOR6); + x3 = L_shr_pos(re[3 * st], SCALEFACTOR6); + x4 = L_shr_pos(re[4 * st], SCALEFACTOR6); + x5 = L_shr_pos(re[5 * st], SCALEFACTOR6); + + t = L_add(x0, L_add(x2, x4)); + s = L_add(x1, L_add(x3, x5)); + re[0 * st] = L_add(t, s); + move32(); + re[3 * st] = L_sub(t, s); + move32(); + t = L_sub(x0, L_shr_pos(L_add(x2, x4), 1)); + + re[1 * st] = t; + move32(); + re[2 * st] = t; + move32(); + re[4 * st] = t; + move32(); + re[5 * st] = t; + move32(); + + s = Mpy_32_32_lc3plus(L_sub(x4, x2), C61_32); + + i1e = s; + i2e = -s; + + t = L_sub(x1, L_shr_pos(L_add(x3, x5), 1)); + s = Mpy_32_32_lc3plus(L_sub(x5, x3), C61_32); + + r1o = r2o = t; + i1o = s; + i2o = -s; + + x0 = L_shr_pos(im[0 * st], SCALEFACTOR6); + x1 = L_shr_pos(im[1 * st], SCALEFACTOR6); + x2 = L_shr_pos(im[2 * st], SCALEFACTOR6); + x3 = L_shr_pos(im[3 * st], SCALEFACTOR6); + x4 = L_shr_pos(im[4 * st], SCALEFACTOR6); + x5 = L_shr_pos(im[5 * st], SCALEFACTOR6); + + t = L_add(x0, L_add(x2, x4)); + s = L_add(x1, L_add(x3, x5)); + + im[0 * st] = L_add(t, s); + move32(); + im[3 * st] = L_sub(t, s); + move32(); + + t = Mpy_32_32_lc3plus(L_sub(x2, x4), C61_32); + s = L_sub(x0, L_shr_pos(L_add(x2, x4), 1)); + + re[1 * st] = L_add(re[1 * st], t); + move32(); + re[2 * st] = L_sub(re[2 * st], t); + move32(); + re[4 * st] = L_add(re[4 * st], t); + move32(); + re[5 * st] = L_sub(re[5 * st], t); + move32(); + + i1e = L_add(i1e, s); + i2e = L_add(i2e, s); + + t = Mpy_32_32_lc3plus(L_sub(x3, x5), C61_32); + s = L_sub(x1, L_shr_pos(L_add(x5, x3), 1)); + + r1o = L_add(r1o, t); + r2o = L_sub(r2o, t); + + i1o = L_add(i1o, s); + i2o = L_add(i2o, s); + + t = L_add(L_shr_pos(r1o, 1), Mpy_32_32_lc3plus(i1o, C61_32)); + s = L_sub(L_shr_pos(i1o, 1), Mpy_32_32_lc3plus(r1o, C61_32)); + + re[1 * st] = L_add(re[1 * st], t); + move32(); + im[1 * st] = L_add(i1e, s); + move32(); + + re[4 * st] = L_sub(re[4 * st], t); + move32(); + im[4 * st] = L_sub(i1e, s); + move32(); + + t = L_sub(Mpy_32_32_lc3plus(i2o, C61_32), L_shr_pos(r2o, 1)); + s = L_negate(L_add(Mpy_32_32_lc3plus(r2o, C61_32), L_shr_pos(i2o, 1))); + + re[2 * st] = L_add(re[2 * st], t); + move32(); + im[2 * st] = L_add(i2e, s); + move32(); + + re[5 * st] = L_sub(re[5 * st], t); + move32(); + im[5 * st] = L_sub(i2e, s); + move32(); + + Dyn_Mem_Deluxe_Out(); +} +#endif + +/** + * \brief Function performs a complex 8-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR8 bits. + * + * WOPS with 32x16 bit multiplications: 108 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft8(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 x00, x01, x02, x03, x04, x05, x06, x07; Word32 x08, x09, x10, x11, x12, x13, x14, x15; + Word32 t00, t01, t02, t03, t04, t05, t06, t07; Word32 t08, t09, t10, t11, t12, t13, t14, t15; + Word32 s00, s01, s02, s03, s04, s05, s06, s07; Word32 s08, s09, s10, s11, s12, s13, s14, s15;); + + /* Pre-additions */ + + x00 = L_shr_pos(re[s * 0], SCALEFACTOR8); + x01 = L_shr_pos(im[s * 0], SCALEFACTOR8); + x02 = L_shr_pos(re[s * 1], SCALEFACTOR8); + x03 = L_shr_pos(im[s * 1], SCALEFACTOR8); + x04 = L_shr_pos(re[s * 2], SCALEFACTOR8); + x05 = L_shr_pos(im[s * 2], SCALEFACTOR8); + x06 = L_shr_pos(re[s * 3], SCALEFACTOR8); + x07 = L_shr_pos(im[s * 3], SCALEFACTOR8); + x08 = L_shr_pos(re[s * 4], SCALEFACTOR8); + x09 = L_shr_pos(im[s * 4], SCALEFACTOR8); + x10 = L_shr_pos(re[s * 5], SCALEFACTOR8); + x11 = L_shr_pos(im[s * 5], SCALEFACTOR8); + x12 = L_shr_pos(re[s * 6], SCALEFACTOR8); + x13 = L_shr_pos(im[s * 6], SCALEFACTOR8); + x14 = L_shr_pos(re[s * 7], SCALEFACTOR8); + x15 = L_shr_pos(im[s * 7], SCALEFACTOR8); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + s12 = Mpy_32_xx(L_add(t00, t02), C81); + s14 = Mpy_32_xx(L_sub(t00, t02), C81); + s13 = Mpy_32_xx(L_sub(t03, t01), C81); + s15 = Mpy_32_xx(L_add(t01, t03), C82); + + /* Post-additions */ + + re[s * 0] = L_add(s00, s02); + move32(); + re[s * 4] = L_sub(s00, s02); + move32(); + im[s * 0] = L_add(s01, s03); + move32(); + im[s * 4] = L_sub(s01, s03); + move32(); + re[s * 2] = L_sub(s04, s06); + move32(); + re[s * 6] = L_add(s04, s06); + move32(); + im[s * 2] = L_sub(s05, s07); + move32(); + im[s * 6] = L_add(s05, s07); + move32(); + re[s * 3] = L_add(s08, s14); + move32(); + re[s * 7] = L_sub(s08, s14); + move32(); + im[s * 3] = L_add(s09, s15); + move32(); + im[s * 7] = L_sub(s09, s15); + move32(); + re[s * 1] = L_add(s10, s12); + move32(); + re[s * 5] = L_sub(s10, s12); + move32(); + im[s * 1] = L_add(s11, s13); + move32(); + im[s * 5] = L_sub(s11, s13); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 10-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR10 bits. + * + * WOPS with 32x16 bit multiplications: 196 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + + +static void fft10(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 t; Word32 x0, x1, x2, x3, x4; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; + Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09; + Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;); + + /* 2 fft5 stages */ + + /* real part */ + x0 = L_shr_pos(re[s * 0], SCALEFACTOR10); + x1 = L_shr_pos(re[s * 2], SCALEFACTOR10); + x2 = L_shr_pos(re[s * 4], SCALEFACTOR10); + x3 = L_shr_pos(re[s * 6], SCALEFACTOR10); + x4 = L_shr_pos(re[s * 8], SCALEFACTOR10); + + r1 = L_add(x3, x2); + r4 = L_sub(x3, x2); + r3 = L_add(x1, x4); + r2 = L_sub(x1, x4); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x0, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 0], SCALEFACTOR10); + x1 = L_shr_pos(im[s * 2], SCALEFACTOR10); + x2 = L_shr_pos(im[s * 4], SCALEFACTOR10); + x3 = L_shr_pos(im[s * 6], SCALEFACTOR10); + x4 = L_shr_pos(im[s * 8], SCALEFACTOR10); + + s1 = L_add(x3, x2); + s4 = L_sub(x3, x2); + s3 = L_add(x1, x4); + s2 = L_sub(x1, x4); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x0, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y04 = L_add(r1, s2); + y16 = L_sub(r1, s2); + y08 = L_sub(r3, s4); + y12 = L_add(r3, s4); + + y05 = L_sub(s1, r2); + y17 = L_add(s1, r2); + y09 = L_add(s3, r4); + y13 = L_sub(s3, r4); + + /* real part */ + x0 = L_shr_pos(re[s * 5], SCALEFACTOR10); + x1 = L_shr_pos(re[s * 1], SCALEFACTOR10); + x2 = L_shr_pos(re[s * 3], SCALEFACTOR10); + x3 = L_shr_pos(re[s * 7], SCALEFACTOR10); + x4 = L_shr_pos(re[s * 9], SCALEFACTOR10); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x3, x2); + r2 = L_sub(x3, x2); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y02 = L_add(x0, r1); + r1 = L_add(y02, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 5], SCALEFACTOR10); + x1 = L_shr_pos(im[s * 1], SCALEFACTOR10); + x2 = L_shr_pos(im[s * 3], SCALEFACTOR10); + x3 = L_shr_pos(im[s * 7], SCALEFACTOR10); + x4 = L_shr_pos(im[s * 9], SCALEFACTOR10); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x3, x2); + s2 = L_sub(x3, x2); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y03 = L_add(x0, s1); + s1 = L_add(y03, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y06 = L_add(r1, s2); + y18 = L_sub(r1, s2); + y10 = L_sub(r3, s4); + y14 = L_add(r3, s4); + + y07 = L_sub(s1, r2); + y19 = L_add(s1, r2); + y11 = L_add(s3, r4); + y15 = L_sub(s3, r4); + + /* 5 fft2 stages */ + re[s * 0] = L_add(y00, y02); + move32(); + im[s * 0] = L_add(y01, y03); + move32(); + re[s * 5] = L_sub(y00, y02); + move32(); + im[s * 5] = L_sub(y01, y03); + move32(); + + re[s * 2] = L_add(y04, y06); + move32(); + im[s * 2] = L_add(y05, y07); + move32(); + re[s * 7] = L_sub(y04, y06); + move32(); + im[s * 7] = L_sub(y05, y07); + move32(); + + re[s * 4] = L_add(y08, y10); + move32(); + im[s * 4] = L_add(y09, y11); + move32(); + re[s * 9] = L_sub(y08, y10); + move32(); + im[s * 9] = L_sub(y09, y11); + move32(); + + re[s * 6] = L_add(y12, y14); + move32(); + im[s * 6] = L_add(y13, y15); + move32(); + re[s * 1] = L_sub(y12, y14); + move32(); + im[s * 1] = L_sub(y13, y15); + move32(); + + re[s * 8] = L_add(y16, y18); + move32(); + im[s * 8] = L_add(y17, y19); + move32(); + re[s * 3] = L_sub(y16, y18); + move32(); + im[s * 3] = L_sub(y17, y19); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 15-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR15 bits. + * + * WOPS with 32x16 bit multiplications: 354 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft15(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 t; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; + Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09; + Word32 x10, x11, x12, x13, x14, x15, x16, x17, x18, x19; + Word32 x20, x21, x22, x23, x24, x25, x26, x27, x28, x29; + Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09; + Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29;); + + x00 = L_shr_pos(re[s * 0], SCALEFACTOR15); + x01 = L_shr_pos(im[s * 0], SCALEFACTOR15); + x02 = L_shr_pos(re[s * 3], SCALEFACTOR15); + x03 = L_shr_pos(im[s * 3], SCALEFACTOR15); + x04 = L_shr_pos(re[s * 6], SCALEFACTOR15); + x05 = L_shr_pos(im[s * 6], SCALEFACTOR15); + x06 = L_shr_pos(re[s * 9], SCALEFACTOR15); + x07 = L_shr_pos(im[s * 9], SCALEFACTOR15); + x08 = L_shr_pos(re[s * 12], SCALEFACTOR15); + x09 = L_shr_pos(im[s * 12], SCALEFACTOR15); + + x10 = L_shr_pos(re[s * 5], SCALEFACTOR15); + x11 = L_shr_pos(im[s * 5], SCALEFACTOR15); + x12 = L_shr_pos(re[s * 8], SCALEFACTOR15); + x13 = L_shr_pos(im[s * 8], SCALEFACTOR15); + x14 = L_shr_pos(re[s * 11], SCALEFACTOR15); + x15 = L_shr_pos(im[s * 11], SCALEFACTOR15); + x16 = L_shr_pos(re[s * 14], SCALEFACTOR15); + x17 = L_shr_pos(im[s * 14], SCALEFACTOR15); + x18 = L_shr_pos(re[s * 2], SCALEFACTOR15); + x19 = L_shr_pos(im[s * 2], SCALEFACTOR15); + + x20 = L_shr_pos(re[s * 10], SCALEFACTOR15); + x21 = L_shr_pos(im[s * 10], SCALEFACTOR15); + x22 = L_shr_pos(re[s * 13], SCALEFACTOR15); + x23 = L_shr_pos(im[s * 13], SCALEFACTOR15); + x24 = L_shr_pos(re[s * 1], SCALEFACTOR15); + x25 = L_shr_pos(im[s * 1], SCALEFACTOR15); + x26 = L_shr_pos(re[s * 4], SCALEFACTOR15); + x27 = L_shr_pos(im[s * 4], SCALEFACTOR15); + x28 = L_shr_pos(re[s * 7], SCALEFACTOR15); + x29 = L_shr_pos(im[s * 7], SCALEFACTOR15); + + /* 1. FFT5 stage */ + + /* real part */ + r1 = L_add(x02, x08); + r4 = L_sub(x02, x08); + r3 = L_add(x04, x06); + r2 = L_sub(x04, x06); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x00, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x03, x09); + s4 = L_sub(x03, x09); + s3 = L_add(x05, x07); + s2 = L_sub(x05, x07); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x01, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y02 = L_add(r1, s2); + y08 = L_sub(r1, s2); + y04 = L_sub(r3, s4); + y06 = L_add(r3, s4); + + y03 = L_sub(s1, r2); + y09 = L_add(s1, r2); + y05 = L_add(s3, r4); + y07 = L_sub(s3, r4); + + /* 2. FFT5 stage */ + + /* real part */ + r1 = L_add(x12, x18); + r4 = L_sub(x12, x18); + r3 = L_add(x14, x16); + r2 = L_sub(x14, x16); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y10 = L_add(x10, r1); + r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x13, x19); + s4 = L_sub(x13, x19); + s3 = L_add(x15, x17); + s2 = L_sub(x15, x17); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y11 = L_add(x11, s1); + s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y12 = L_add(r1, s2); + y18 = L_sub(r1, s2); + y14 = L_sub(r3, s4); + y16 = L_add(r3, s4); + + y13 = L_sub(s1, r2); + y19 = L_add(s1, r2); + y15 = L_add(s3, r4); + y17 = L_sub(s3, r4); + + /* 3. FFT5 stage */ + + /* real part */ + r1 = L_add(x22, x28); + r4 = L_sub(x22, x28); + r3 = L_add(x24, x26); + r2 = L_sub(x24, x26); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y20 = L_add(x20, r1); + r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x23, x29); + s4 = L_sub(x23, x29); + s3 = L_add(x25, x27); + s2 = L_sub(x25, x27); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y21 = L_add(x21, s1); + s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y22 = L_add(r1, s2); + y28 = L_sub(r1, s2); + y24 = L_sub(r3, s4); + y26 = L_add(r3, s4); + + y23 = L_sub(s1, r2); + y29 = L_add(s1, r2); + y25 = L_add(s3, r4); + y27 = L_sub(s3, r4); + + /* 1. FFT3 stage */ + + /* real part */ + r1 = L_add(y10, y20); + r2 = Mpy_32_xx(L_sub(y10, y20), C31); + re[s * 0] = L_add(y00, r1); + move32(); + r1 = L_sub(y00, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y11, y21); + s2 = Mpy_32_xx(L_sub(y11, y21), C31); + im[s * 0] = L_add(y01, s1); + move32(); + s1 = L_sub(y01, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 10] = L_sub(r1, s2); + move32(); + re[s * 5] = L_add(r1, s2); + move32(); + im[s * 10] = L_add(s1, r2); + move32(); + im[s * 5] = L_sub(s1, r2); + move32(); + + /* 2. FFT3 stage */ + + /* real part */ + r1 = L_add(y12, y22); + r2 = Mpy_32_xx(L_sub(y12, y22), C31); + re[s * 6] = L_add(y02, r1); + move32(); + r1 = L_sub(y02, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y13, y23); + s2 = Mpy_32_xx(L_sub(y13, y23), C31); + im[s * 6] = L_add(y03, s1); + move32(); + s1 = L_sub(y03, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 1] = L_sub(r1, s2); + move32(); + re[s * 11] = L_add(r1, s2); + move32(); + im[s * 1] = L_add(s1, r2); + move32(); + im[s * 11] = L_sub(s1, r2); + move32(); + + /* 3. FFT3 stage */ + + /* real part */ + r1 = L_add(y14, y24); + r2 = Mpy_32_xx(L_sub(y14, y24), C31); + re[s * 12] = L_add(y04, r1); + move32(); + r1 = L_sub(y04, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y15, y25); + s2 = Mpy_32_xx(L_sub(y15, y25), C31); + im[s * 12] = L_add(y05, s1); + move32(); + s1 = L_sub(y05, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 7] = L_sub(r1, s2); + move32(); + re[s * 2] = L_add(r1, s2); + move32(); + im[s * 7] = L_add(s1, r2); + move32(); + im[s * 2] = L_sub(s1, r2); + move32(); + + /* 4. FFT3 stage */ + + /* real part */ + r1 = L_add(y16, y26); + r2 = Mpy_32_xx(L_sub(y16, y26), C31); + re[s * 3] = L_add(y06, r1); + move32(); + r1 = L_sub(y06, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y17, y27); + s2 = Mpy_32_xx(L_sub(y17, y27), C31); + im[s * 3] = L_add(y07, s1); + move32(); + s1 = L_sub(y07, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 13] = L_sub(r1, s2); + move32(); + re[s * 8] = L_add(r1, s2); + move32(); + im[s * 13] = L_add(s1, r2); + move32(); + im[s * 8] = L_sub(s1, r2); + move32(); + + /* 5. FFT3 stage */ + + /* real part */ + r1 = L_add(y18, y28); + r2 = Mpy_32_xx(L_sub(y18, y28), C31); + re[s * 9] = L_add(y08, r1); + move32(); + r1 = L_sub(y08, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y19, y29); + s2 = Mpy_32_xx(L_sub(y19, y29), C31); + im[s * 9] = L_add(y09, s1); + move32(); + s1 = L_sub(y09, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 4] = L_sub(r1, s2); + move32(); + re[s * 14] = L_add(r1, s2); + move32(); + im[s * 4] = L_add(s1, r2); + move32(); + im[s * 14] = L_sub(s1, r2); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +#ifdef CR8_G_ADD_75MS + +#define STC(x) (x) +const Word32 RotVectorReal12[] = +{ + STC(0x6ed9eba1), STC(0x40000000), + STC(0x40000000), STC(0xc0000000), +#ifndef FFT12_UNROLLED_ENABLE + STC(0x00000000), STC(0x80000000), +#endif +}; + +const Word32 RotVectorImag12[] = +{ + STC(0x40000000), STC(0x6ed9eba1), + STC(0x6ed9eba1), STC(0x6ed9eba1), +#ifndef FFT12_UNROLLED_ENABLE + STC(0x7fffffff), STC(0x00000000), +#endif +}; + +static void fft12(Word32 *pInput) +{ + Dyn_Mem_Deluxe_In(Word32 aDst[24]; Word32 * pSrc, *pDst; Counter i; Word32 r1, r2, s1, s2, pD; Word32 re, im; + Word32 vre, vim;); + + pSrc = pInput; + move16(); + pDst = aDst; + move16(); + + /* First 3*2 samples are shifted right by 2 before output */ + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + pDst[2] = L_sub(r1, s2); + pDst[3] = L_add(s1, r2); + pDst[4] = L_add(r1, s2); + pDst[5] = L_sub(s1, r2); + pSrc += 2; + pDst += 6; + + const Word32 *pVecRe = RotVectorReal12; + const Word32 *pVecIm = RotVectorImag12; + + + + FOR (i = 0; i < 2; i++) + { + /* sample 0,1 are shifted right by 2 before output */ + /* sample 2,3 4,5 are shifted right by 1 and complex multiplied before output */ + + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + re = L_sub(r1, s2); + im = L_add(s1, r2); + vre = *pVecRe++; + vim = *pVecIm++; + cplxMpy_32_32(&pDst[3], &pDst[2], im, re, vre, vim); + + re = L_add(r1, s2); + im = L_sub(s1, r2); + + vre = *pVecRe++; + vim = *pVecIm++; + cplxMpy_32_32(&pDst[5], &pDst[4], im, re, vre, vim); + + pDst += 6; + pSrc += 2; + } + /* sample 0,1 are shifted right by 2 before output */ + /* sample 2,3 is shifted right by 1 and complex multiplied with (0.0,+1.0) */ + /* sample 4,5 is shifted right by 1 and complex multiplied with (-1.0,0.0) */ + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + + pDst[2] = L_add(s1, r2); + move32(); + pDst[3] = L_sub(s2, r1); + move32(); + pDst[4] = L_negate(L_add(r1, s2)); + move32(); + pDst[5] = L_sub(r2, s1); + move32(); + /* Perform 3 times the fft of length 4. The input samples are at the address of aDst and the + output samples are at the address of pInput. The input vector for the fft of length 4 is built + of the interleaved samples in aDst, the output samples are stored consecutively at the address + of pInput. + */ + move16(); + move16(); + pSrc = aDst; + pDst = pInput; + FOR (i = 0; i < 3; i++) + { + /* inline FFT4 merged with incoming resorting loop */ + r1 = L_add(L_shr_pos(pSrc[0], 2), L_shr_pos(pSrc[12], 2)); /* Re A + Re B */ + r2 = L_add(L_shr_pos(pSrc[6], 2), L_shr_pos(pSrc[18], 2)); /* Re C + Re D */ + s1 = L_add(L_shr_pos(pSrc[1], 2), L_shr_pos(pSrc[13], 2)); /* Im A + Im B */ + s2 = L_add(L_shr_pos(pSrc[7], 2), L_shr_pos(pSrc[19], 2)); /* Im C + Im D */ + + pDst[0] = L_add(r1, r2); /* Re A' = Re A + Re B + Re C + Re D */ + pDst[1] = L_add(s1, s2); /* Im A' = Im A + Im B + Im C + Im D */ + + re = L_sub(r1, L_shr_pos(pSrc[12], 1)); /* Re A - Re B */ + im = L_sub(s1, L_shr_pos(pSrc[13], 1)); /* Im A - Im B */ + + pDst[12] = L_sub(r1, r2); /* Re C' = Re A + Re B - Re C - Re D */ + pDst[13] = L_sub(s1, s2); /* Im C' = Im A + Im B - Im C - Im D */ + + r2 = L_sub(r2, L_shr_pos(pSrc[18], 1)); /* Re C - Re D */ + s2 = L_sub(s2, L_shr_pos(pSrc[19], 1)); /* Im C - Im D */ + + pDst[6] = L_add(re, s2); /* Re B' = Re A - Re B + Im C - Im D */ + pDst[18] = L_sub(re, s2); /* Re D' = Re A - Re B - Im C + Im D */ + pDst[7] = L_sub(im, r2); /* Im B' = Im A - Im B - Re C + Re D */ + pDst[19] = L_add(im, r2); /* Im D' = Im A - Im B + Re C - Re D */ + + pSrc += 2; + pDst += 2; + } + + Dyn_Mem_Deluxe_Out(); +} + +#else /* CR8_G_ADD_75MS */ + +static void fft12(Word32 *pInput) +{ + Dyn_Mem_Deluxe_In(Word32 aDst[24]; Word32 * pSrc, *pDst; Counter i; Word32 r1, r2, s1, s2, pD; Word32 re, im; + Word16 vre, vim;); + + pSrc = pInput; + move16(); + pDst = aDst; + move16(); + + /* First 3*2 samples are shifted right by 2 before output */ + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + pDst[2] = L_sub(r1, s2); + pDst[3] = L_add(s1, r2); + pDst[4] = L_add(r1, s2); + pDst[5] = L_sub(s1, r2); + pSrc += 2; + pDst += 6; + + vre = add(0x6eda, 0); + vim = add(0x4000, 0); + + FOR (i = 0; i < 2; i++) + { + /* sample 0,1 are shifted right by 2 before output */ + /* sample 2,3 4,5 are shifted right by 1 and complex multiplied before output */ + + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + re = L_sub(r1, s2); + im = L_add(s1, r2); + cplxMpy_32_16(&pDst[3], &pDst[2], im, re, vre, vim); + re = L_add(r1, s2); + im = L_sub(s1, r2); + vre = add(0x4000, 0); + if (i == 1) + vre = negate(vre); /* 0xC000 */ + if (i == 0) + vim = add(0x6eda, 0); + cplxMpy_32_16(&pDst[5], &pDst[4], im, re, vre, vim); + + pDst += 6; + pSrc += 2; + } + /* sample 0,1 are shifted right by 2 before output */ + /* sample 2,3 is shifted right by 1 and complex multiplied with (0.0,+1.0) */ + /* sample 4,5 is shifted right by 1 and complex multiplied with (-1.0,0.0) */ + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + + pDst[2] = L_add(s1, r2); + move32(); + pDst[3] = L_sub(s2, r1); + move32(); + pDst[4] = L_negate(L_add(r1, s2)); + move32(); + pDst[5] = L_sub(r2, s1); + move32(); + /* Perform 3 times the fft of length 4. The input samples are at the address of aDst and the + output samples are at the address of pInput. The input vector for the fft of length 4 is built + of the interleaved samples in aDst, the output samples are stored consecutively at the address + of pInput. + */ + move16(); + move16(); + pSrc = aDst; + pDst = pInput; + FOR (i = 0; i < 3; i++) + { + /* inline FFT4 merged with incoming resorting loop */ + r1 = L_add(L_shr_pos(pSrc[0], 2), L_shr_pos(pSrc[12], 2)); /* Re A + Re B */ + r2 = L_add(L_shr_pos(pSrc[6], 2), L_shr_pos(pSrc[18], 2)); /* Re C + Re D */ + s1 = L_add(L_shr_pos(pSrc[1], 2), L_shr_pos(pSrc[13], 2)); /* Im A + Im B */ + s2 = L_add(L_shr_pos(pSrc[7], 2), L_shr_pos(pSrc[19], 2)); /* Im C + Im D */ + + pDst[0] = L_add(r1, r2); /* Re A' = Re A + Re B + Re C + Re D */ + pDst[1] = L_add(s1, s2); /* Im A' = Im A + Im B + Im C + Im D */ + + re = L_sub(r1, L_shr_pos(pSrc[12], 1)); /* Re A - Re B */ + im = L_sub(s1, L_shr_pos(pSrc[13], 1)); /* Im A - Im B */ + + pDst[12] = L_sub(r1, r2); /* Re C' = Re A + Re B - Re C - Re D */ + pDst[13] = L_sub(s1, s2); /* Im C' = Im A + Im B - Im C - Im D */ + + r2 = L_sub(r2, L_shr_pos(pSrc[18], 1)); /* Re C - Re D */ + s2 = L_sub(s2, L_shr_pos(pSrc[19], 1)); /* Im C - Im D */ + + pDst[6] = L_add(re, s2); /* Re B' = Re A - Re B + Im C - Im D */ + pDst[18] = L_sub(re, s2); /* Re D' = Re A - Re B - Im C + Im D */ + pDst[7] = L_sub(im, r2); /* Im B' = Im A - Im B - Re C + Re D */ + pDst[19] = L_add(im, r2); /* Im D' = Im A - Im B + Re C - Re D */ + + pSrc += 2; + pDst += 2; + } + + Dyn_Mem_Deluxe_Out(); +} + +#endif + +/** + * \brief Function performs a complex 16-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR16 bits. + * + * WOPS with 32x16 bit multiplications (scale on ): 288 cycles + * WOPS with 32x16 bit multiplications (scale off): 256 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + + +static void fft16(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5, x6, x7; Word32 t0, t1, t2, t3, t4, t5, t6, t7; + Word32 y00, y01, y02, y03, y04, y05, y06, y07; Word32 y08, y09, y10, y11, y12, y13, y14, y15; + Word32 y16, y17, y18, y19, y20, y21, y22, y23; Word32 y24, y25, y26, y27, y28, y29, y30, y31;); + + x0 = L_shr_pos(re[s * 0], SCALEFACTOR16); + x1 = L_shr_pos(im[s * 0], SCALEFACTOR16); + x2 = L_shr_pos(re[s * 4], SCALEFACTOR16); + x3 = L_shr_pos(im[s * 4], SCALEFACTOR16); + x4 = L_shr_pos(re[s * 8], SCALEFACTOR16); + x5 = L_shr_pos(im[s * 8], SCALEFACTOR16); + x6 = L_shr_pos(re[s * 12], SCALEFACTOR16); + x7 = L_shr_pos(im[s * 12], SCALEFACTOR16); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + y00 = L_add(t0, t4); + y01 = L_add(t1, t5); + y02 = L_sub(t2, t6); + y03 = L_sub(t3, t7); + y04 = L_sub(t0, t4); + y05 = L_sub(t1, t5); + y06 = L_add(t2, t6); + y07 = L_add(t3, t7); + + x0 = L_shr_pos(re[s * 1], SCALEFACTOR16); + x1 = L_shr_pos(im[s * 1], SCALEFACTOR16); + x2 = L_shr_pos(re[s * 5], SCALEFACTOR16); + x3 = L_shr_pos(im[s * 5], SCALEFACTOR16); + x4 = L_shr_pos(re[s * 9], SCALEFACTOR16); + x5 = L_shr_pos(im[s * 9], SCALEFACTOR16); + x6 = L_shr_pos(re[s * 13], SCALEFACTOR16); + x7 = L_shr_pos(im[s * 13], SCALEFACTOR16); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + y08 = L_add(t0, t4); + y09 = L_add(t1, t5); + y10 = L_sub(t2, t6); + y11 = L_sub(t3, t7); + y12 = L_sub(t0, t4); + y13 = L_sub(t1, t5); + y14 = L_add(t2, t6); + y15 = L_add(t3, t7); + + x0 = L_shr_pos(re[s * 2], SCALEFACTOR16); + x1 = L_shr_pos(im[s * 2], SCALEFACTOR16); + x2 = L_shr_pos(re[s * 6], SCALEFACTOR16); + x3 = L_shr_pos(im[s * 6], SCALEFACTOR16); + x4 = L_shr_pos(re[s * 10], SCALEFACTOR16); + x5 = L_shr_pos(im[s * 10], SCALEFACTOR16); + x6 = L_shr_pos(re[s * 14], SCALEFACTOR16); + x7 = L_shr_pos(im[s * 14], SCALEFACTOR16); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + y16 = L_add(t0, t4); + y17 = L_add(t1, t5); + y18 = L_sub(t2, t6); + y19 = L_sub(t3, t7); + y20 = L_sub(t1, t5); + y21 = L_sub(t4, t0); + y22 = L_add(t2, t6); + y23 = L_add(t3, t7); + + x0 = L_shr_pos(re[s * 3], SCALEFACTOR16); + x1 = L_shr_pos(im[s * 3], SCALEFACTOR16); + x2 = L_shr_pos(re[s * 7], SCALEFACTOR16); + x3 = L_shr_pos(im[s * 7], SCALEFACTOR16); + x4 = L_shr_pos(re[s * 11], SCALEFACTOR16); + x5 = L_shr_pos(im[s * 11], SCALEFACTOR16); + x6 = L_shr_pos(re[s * 15], SCALEFACTOR16); + x7 = L_shr_pos(im[s * 15], SCALEFACTOR16); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + y24 = L_add(t0, t4); + y25 = L_add(t1, t5); + y26 = L_sub(t2, t6); + y27 = L_sub(t3, t7); + y28 = L_sub(t0, t4); + y29 = L_sub(t1, t5); + y30 = L_add(t2, t6); + y31 = L_add(t3, t7); + + /* rotation */ + + x0 = Mpy_32_xx(y22, C162); + x1 = Mpy_32_xx(y23, C162); + y22 = L_sub(x0, x1); + y23 = L_add(x0, x1); + + x0 = Mpy_32_xx(y28, C162); + x1 = Mpy_32_xx(y29, C162); + y28 = L_sub(x0, x1); + y29 = L_add(x0, x1); + + x0 = Mpy_32_xx(y12, C161); + x1 = Mpy_32_xx(y13, C161); + y12 = L_add(x0, x1); + y13 = L_sub(x1, x0); + + x0 = Mpy_32_xx(y18, C161); + x1 = Mpy_32_xx(y19, C161); + y18 = L_add(x0, x1); + y19 = L_sub(x1, x0); + + x0 = Mpy_32_xx(y10, C163); + x1 = Mpy_32_xx(y11, C166); + x2 = Mpy_32_xx(y10, C166); + x3 = Mpy_32_xx(y11, C163); + y10 = L_sub(x0, x1); + y11 = L_add(x2, x3); + + x0 = Mpy_32_xx(y14, C165); + x1 = Mpy_32_xx(y15, C164); + x2 = Mpy_32_xx(y14, C164); + x3 = Mpy_32_xx(y15, C165); + y14 = L_sub(x0, x1); + y15 = L_add(x2, x3); + + x0 = Mpy_32_xx(y26, C165); + x1 = Mpy_32_xx(y27, C164); + x2 = Mpy_32_xx(y26, C164); + x3 = Mpy_32_xx(y27, C165); + y26 = L_sub(x0, x1); + y27 = L_add(x2, x3); + + x0 = Mpy_32_xx(y30, C164); + x1 = Mpy_32_xx(y31, C165); + x2 = Mpy_32_xx(y30, C165); + x3 = Mpy_32_xx(y31, C164); + y30 = L_sub(x0, x1); + y31 = L_add(x2, x3); + + /* Pre-additions */ + + t0 = L_add(y00, y16); + t2 = L_sub(y00, y16); + t1 = L_add(y01, y17); + t3 = L_sub(y01, y17); + t4 = L_add(y08, y24); + t7 = L_sub(y08, y24); + t5 = L_add(y25, y09); + t6 = L_sub(y25, y09); + + /* Post-additions */ + + re[s * 0] = L_add(t0, t4); + move32(); + im[s * 0] = L_add(t1, t5); + move32(); + re[s * 4] = L_sub(t2, t6); + move32(); + im[s * 4] = L_sub(t3, t7); + move32(); + re[s * 8] = L_sub(t0, t4); + move32(); + im[s * 8] = L_sub(t1, t5); + move32(); + re[s * 12] = L_add(t2, t6); + move32(); + im[s * 12] = L_add(t3, t7); + move32(); + + /* Pre-additions */ + + t0 = L_add(y02, y18); + t2 = L_sub(y02, y18); + t1 = L_add(y03, y19); + t3 = L_sub(y03, y19); + t4 = L_add(y10, y26); + t7 = L_sub(y10, y26); + t5 = L_add(y27, y11); + t6 = L_sub(y27, y11); + + /* Post-additions */ + + re[s * 1] = L_add(t0, t4); + move32(); + im[s * 1] = L_add(t1, t5); + move32(); + re[s * 5] = L_sub(t2, t6); + move32(); + im[s * 5] = L_sub(t3, t7); + move32(); + re[s * 9] = L_sub(t0, t4); + move32(); + im[s * 9] = L_sub(t1, t5); + move32(); + re[s * 13] = L_add(t2, t6); + move32(); + im[s * 13] = L_add(t3, t7); + move32(); + + /* Pre-additions */ + + t0 = L_add(y04, y20); + t2 = L_sub(y04, y20); + t1 = L_add(y05, y21); + t3 = L_sub(y05, y21); + t4 = L_add(y12, y28); + t7 = L_sub(y12, y28); + t5 = L_add(y29, y13); + t6 = L_sub(y29, y13); + + /* Post-additions */ + + re[s * 2] = L_add(t0, t4); + move32(); + im[s * 2] = L_add(t1, t5); + move32(); + re[s * 6] = L_sub(t2, t6); + move32(); + im[s * 6] = L_sub(t3, t7); + move32(); + re[s * 10] = L_sub(t0, t4); + move32(); + im[s * 10] = L_sub(t1, t5); + move32(); + re[s * 14] = L_add(t2, t6); + move32(); + im[s * 14] = L_add(t3, t7); + move32(); + + /* Pre-additions */ + + t0 = L_add(y06, y22); + t2 = L_sub(y06, y22); + t1 = L_add(y07, y23); + t3 = L_sub(y07, y23); + t4 = L_add(y14, y30); + t7 = L_sub(y14, y30); + t5 = L_add(y31, y15); + t6 = L_sub(y31, y15); + + /* Post-additions */ + + re[s * 3] = L_add(t0, t4); + move32(); + im[s * 3] = L_add(t1, t5); + move32(); + re[s * 7] = L_sub(t2, t6); + move32(); + im[s * 7] = L_sub(t3, t7); + move32(); + re[s * 11] = L_sub(t0, t4); + move32(); + im[s * 11] = L_sub(t1, t5); + move32(); + re[s * 15] = L_add(t2, t6); + move32(); + im[s * 15] = L_add(t3, t7); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 20-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR20 bits. + * + * WOPS with 32x16 bit multiplications: 432 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft20(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; Word32 x0, x1, x2, x3, x4; + Word32 t, t0, t1, t2, t3, t4, t5, t6, t7; Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09; + Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29; + Word32 y30, y31, y32, y33, y34, y35, y36, y37, y38, y39;); + + /* 1. FFT5 stage */ + + /* real part */ + x0 = L_shr_pos(re[s * 0], SCALEFACTOR20); + x1 = L_shr_pos(re[s * 16], SCALEFACTOR20); + x2 = L_shr_pos(re[s * 12], SCALEFACTOR20); + x3 = L_shr_pos(re[s * 8], SCALEFACTOR20); + x4 = L_shr_pos(re[s * 4], SCALEFACTOR20); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x0, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 0], SCALEFACTOR20); + x1 = L_shr_pos(im[s * 16], SCALEFACTOR20); + x2 = L_shr_pos(im[s * 12], SCALEFACTOR20); + x3 = L_shr_pos(im[s * 8], SCALEFACTOR20); + x4 = L_shr_pos(im[s * 4], SCALEFACTOR20); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x0, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y08 = L_add(r1, s2); + y32 = L_sub(r1, s2); + y16 = L_sub(r3, s4); + y24 = L_add(r3, s4); + + y09 = L_sub(s1, r2); + y33 = L_add(s1, r2); + y17 = L_add(s3, r4); + y25 = L_sub(s3, r4); + + /* 2. FFT5 stage */ + + /* real part */ + x0 = L_shr_pos(re[s * 5], SCALEFACTOR20); + x1 = L_shr_pos(re[s * 1], SCALEFACTOR20); + x2 = L_shr_pos(re[s * 17], SCALEFACTOR20); + x3 = L_shr_pos(re[s * 13], SCALEFACTOR20); + x4 = L_shr_pos(re[s * 9], SCALEFACTOR20); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y02 = L_add(x0, r1); + r1 = L_add(y02, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 5], SCALEFACTOR20); + x1 = L_shr_pos(im[s * 1], SCALEFACTOR20); + x2 = L_shr_pos(im[s * 17], SCALEFACTOR20); + x3 = L_shr_pos(im[s * 13], SCALEFACTOR20); + x4 = L_shr_pos(im[s * 9], SCALEFACTOR20); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y03 = L_add(x0, s1); + s1 = L_add(y03, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y10 = L_add(r1, s2); + y34 = L_sub(r1, s2); + y18 = L_sub(r3, s4); + y26 = L_add(r3, s4); + + y11 = L_sub(s1, r2); + y35 = L_add(s1, r2); + y19 = L_add(s3, r4); + y27 = L_sub(s3, r4); + + /* 3. FFT5 stage */ + + /* real part */ + x0 = L_shr_pos(re[s * 10], SCALEFACTOR20); + x1 = L_shr_pos(re[s * 6], SCALEFACTOR20); + x2 = L_shr_pos(re[s * 2], SCALEFACTOR20); + x3 = L_shr_pos(re[s * 18], SCALEFACTOR20); + x4 = L_shr_pos(re[s * 14], SCALEFACTOR20); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y04 = L_add(x0, r1); + r1 = L_add(y04, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 10], SCALEFACTOR20); + x1 = L_shr_pos(im[s * 6], SCALEFACTOR20); + x2 = L_shr_pos(im[s * 2], SCALEFACTOR20); + x3 = L_shr_pos(im[s * 18], SCALEFACTOR20); + x4 = L_shr_pos(im[s * 14], SCALEFACTOR20); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y05 = L_add(x0, s1); + s1 = L_add(y05, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y12 = L_add(r1, s2); + y36 = L_sub(r1, s2); + y20 = L_sub(r3, s4); + y28 = L_add(r3, s4); + + y13 = L_sub(s1, r2); + y37 = L_add(s1, r2); + y21 = L_add(s3, r4); + y29 = L_sub(s3, r4); + + /* 4. FFT5 stage */ + + /* real part */ + x0 = L_shr_pos(re[s * 15], SCALEFACTOR20); + x1 = L_shr_pos(re[s * 11], SCALEFACTOR20); + x2 = L_shr_pos(re[s * 7], SCALEFACTOR20); + x3 = L_shr_pos(re[s * 3], SCALEFACTOR20); + x4 = L_shr_pos(re[s * 19], SCALEFACTOR20); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y06 = L_add(x0, r1); + r1 = L_add(y06, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 15], SCALEFACTOR20); + x1 = L_shr_pos(im[s * 11], SCALEFACTOR20); + x2 = L_shr_pos(im[s * 7], SCALEFACTOR20); + x3 = L_shr_pos(im[s * 3], SCALEFACTOR20); + x4 = L_shr_pos(im[s * 19], SCALEFACTOR20); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y07 = L_add(x0, s1); + s1 = L_add(y07, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y14 = L_add(r1, s2); + y38 = L_sub(r1, s2); + y22 = L_sub(r3, s4); + y30 = L_add(r3, s4); + + y15 = L_sub(s1, r2); + y39 = L_add(s1, r2); + y23 = L_add(s3, r4); + y31 = L_sub(s3, r4); + + /* 1. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y00, y04); + t2 = L_sub(y00, y04); + t1 = L_add(y01, y05); + t3 = L_sub(y01, y05); + t4 = L_add(y02, y06); + t7 = L_sub(y02, y06); + t5 = L_add(y07, y03); + t6 = L_sub(y07, y03); + + /* Post-additions */ + re[s * 0] = L_add(t0, t4); + move32(); + im[s * 0] = L_add(t1, t5); + move32(); + re[s * 5] = L_sub(t2, t6); + move32(); + im[s * 5] = L_sub(t3, t7); + move32(); + re[s * 10] = L_sub(t0, t4); + move32(); + im[s * 10] = L_sub(t1, t5); + move32(); + re[s * 15] = L_add(t2, t6); + move32(); + im[s * 15] = L_add(t3, t7); + move32(); + + /* 2. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y08, y12); + t2 = L_sub(y08, y12); + t1 = L_add(y09, y13); + t3 = L_sub(y09, y13); + t4 = L_add(y10, y14); + t7 = L_sub(y10, y14); + t5 = L_add(y15, y11); + t6 = L_sub(y15, y11); + + /* Post-additions */ + re[s * 4] = L_add(t0, t4); + move32(); + im[s * 4] = L_add(t1, t5); + move32(); + re[s * 9] = L_sub(t2, t6); + move32(); + im[s * 9] = L_sub(t3, t7); + move32(); + re[s * 14] = L_sub(t0, t4); + move32(); + im[s * 14] = L_sub(t1, t5); + move32(); + re[s * 19] = L_add(t2, t6); + move32(); + im[s * 19] = L_add(t3, t7); + move32(); + + /* 3. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y16, y20); + t2 = L_sub(y16, y20); + t1 = L_add(y17, y21); + t3 = L_sub(y17, y21); + t4 = L_add(y18, y22); + t7 = L_sub(y18, y22); + t5 = L_add(y23, y19); + t6 = L_sub(y23, y19); + + /* Post-additions */ + re[s * 8] = L_add(t0, t4); + move32(); + im[s * 8] = L_add(t1, t5); + move32(); + re[s * 13] = L_sub(t2, t6); + move32(); + im[s * 13] = L_sub(t3, t7); + move32(); + re[s * 18] = L_sub(t0, t4); + move32(); + im[s * 18] = L_sub(t1, t5); + move32(); + re[s * 3] = L_add(t2, t6); + move32(); + im[s * 3] = L_add(t3, t7); + move32(); + + /* 4. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y24, y28); + t2 = L_sub(y24, y28); + t1 = L_add(y25, y29); + t3 = L_sub(y25, y29); + t4 = L_add(y26, y30); + t7 = L_sub(y26, y30); + t5 = L_add(y31, y27); + t6 = L_sub(y31, y27); + + /* Post-additions */ + re[s * 12] = L_add(t0, t4); + move32(); + im[s * 12] = L_add(t1, t5); + move32(); + re[s * 17] = L_sub(t2, t6); + move32(); + im[s * 17] = L_sub(t3, t7); + move32(); + re[s * 2] = L_sub(t0, t4); + move32(); + im[s * 2] = L_sub(t1, t5); + move32(); + re[s * 7] = L_add(t2, t6); + move32(); + im[s * 7] = L_add(t3, t7); + move32(); + + /* 5. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y32, y36); + t2 = L_sub(y32, y36); + t1 = L_add(y33, y37); + t3 = L_sub(y33, y37); + t4 = L_add(y34, y38); + t7 = L_sub(y34, y38); + t5 = L_add(y39, y35); + t6 = L_sub(y39, y35); + + /* Post-additions */ + re[s * 16] = L_add(t0, t4); + move32(); + im[s * 16] = L_add(t1, t5); + move32(); + re[s * 1] = L_sub(t2, t6); + move32(); + im[s * 1] = L_sub(t3, t7); + move32(); + re[s * 6] = L_sub(t0, t4); + move32(); + im[s * 6] = L_sub(t1, t5); + move32(); + re[s * 11] = L_add(t2, t6); + move32(); + im[s * 11] = L_add(t3, t7); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 30-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR30 bits. + * + * WOPS with 32x16 bit multiplications: 828 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft30(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 t; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; + Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09; + Word32 x10, x11, x12, x13, x14, x15, x16, x17, x18, x19; + Word32 x20, x21, x22, x23, x24, x25, x26, x27, x28, x29; + + Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09; + Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29; + + Word32 z00, z01, z02, z03, z04, z05, z06, z07, z08, z09; + Word32 z10, z11, z12, z13, z14, z15, z16, z17, z18, z19; + Word32 z20, z21, z22, z23, z24, z25, z26, z27, z28, z29; + Word32 z30, z31, z32, z33, z34, z35, z36, z37, z38, z39; + Word32 z40, z41, z42, z43, z44, z45, z46, z47, z48, z49; + Word32 z50, z51, z52, z53, z54, z55, z56, z57, z58, z59; + + Word32 * rel, *reh, *iml, *imh;); + + rel = &re[s * 0]; + reh = &re[s * 15]; + iml = &im[s * 0]; + imh = &im[s * 15]; + + /* 1. FFT15 stage */ + x00 = L_shr_pos(re[s * 0], SCALEFACTOR30_1); + x01 = L_shr_pos(im[s * 0], SCALEFACTOR30_1); + x02 = L_shr_pos(re[s * 18], SCALEFACTOR30_1); + x03 = L_shr_pos(im[s * 18], SCALEFACTOR30_1); + x04 = L_shr_pos(re[s * 6], SCALEFACTOR30_1); + x05 = L_shr_pos(im[s * 6], SCALEFACTOR30_1); + x06 = L_shr_pos(re[s * 24], SCALEFACTOR30_1); + x07 = L_shr_pos(im[s * 24], SCALEFACTOR30_1); + x08 = L_shr_pos(re[s * 12], SCALEFACTOR30_1); + x09 = L_shr_pos(im[s * 12], SCALEFACTOR30_1); + + x10 = L_shr_pos(re[s * 20], SCALEFACTOR30_1); + x11 = L_shr_pos(im[s * 20], SCALEFACTOR30_1); + x12 = L_shr_pos(re[s * 8], SCALEFACTOR30_1); + x13 = L_shr_pos(im[s * 8], SCALEFACTOR30_1); + x14 = L_shr_pos(re[s * 26], SCALEFACTOR30_1); + x15 = L_shr_pos(im[s * 26], SCALEFACTOR30_1); + x16 = L_shr_pos(re[s * 14], SCALEFACTOR30_1); + x17 = L_shr_pos(im[s * 14], SCALEFACTOR30_1); + x18 = L_shr_pos(re[s * 2], SCALEFACTOR30_1); + x19 = L_shr_pos(im[s * 2], SCALEFACTOR30_1); + + x20 = L_shr_pos(re[s * 10], SCALEFACTOR30_1); + x21 = L_shr_pos(im[s * 10], SCALEFACTOR30_1); + x22 = L_shr_pos(re[s * 28], SCALEFACTOR30_1); + x23 = L_shr_pos(im[s * 28], SCALEFACTOR30_1); + x24 = L_shr_pos(re[s * 16], SCALEFACTOR30_1); + x25 = L_shr_pos(im[s * 16], SCALEFACTOR30_1); + x26 = L_shr_pos(re[s * 4], SCALEFACTOR30_1); + x27 = L_shr_pos(im[s * 4], SCALEFACTOR30_1); + x28 = L_shr_pos(re[s * 22], SCALEFACTOR30_1); + x29 = L_shr_pos(im[s * 22], SCALEFACTOR30_1); + + /* 1. FFT5 stage */ + + /* real part */ + r1 = L_add(x02, x08); + r4 = L_sub(x02, x08); + r3 = L_add(x04, x06); + r2 = L_sub(x04, x06); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x00, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x03, x09); + s4 = L_sub(x03, x09); + s3 = L_add(x05, x07); + s2 = L_sub(x05, x07); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x01, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y02 = L_add(r1, s2); + y08 = L_sub(r1, s2); + y04 = L_sub(r3, s4); + y06 = L_add(r3, s4); + + y03 = L_sub(s1, r2); + y09 = L_add(s1, r2); + y05 = L_add(s3, r4); + y07 = L_sub(s3, r4); + + /* 2. FFT5 stage */ + + /* real part */ + r1 = L_add(x12, x18); + r4 = L_sub(x12, x18); + r3 = L_add(x14, x16); + r2 = L_sub(x14, x16); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y10 = L_add(x10, r1); + r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x13, x19); + s4 = L_sub(x13, x19); + s3 = L_add(x15, x17); + s2 = L_sub(x15, x17); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y11 = L_add(x11, s1); + s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y12 = L_add(r1, s2); + y18 = L_sub(r1, s2); + y14 = L_sub(r3, s4); + y16 = L_add(r3, s4); + + y13 = L_sub(s1, r2); + y19 = L_add(s1, r2); + y15 = L_add(s3, r4); + y17 = L_sub(s3, r4); + + /* 3. FFT5 stage */ + + /* real part */ + r1 = L_add(x22, x28); + r4 = L_sub(x22, x28); + r3 = L_add(x24, x26); + r2 = L_sub(x24, x26); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y20 = L_add(x20, r1); + r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x23, x29); + s4 = L_sub(x23, x29); + s3 = L_add(x25, x27); + s2 = L_sub(x25, x27); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y21 = L_add(x21, s1); + s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y22 = L_add(r1, s2); + y28 = L_sub(r1, s2); + y24 = L_sub(r3, s4); + y26 = L_add(r3, s4); + + y23 = L_sub(s1, r2); + y29 = L_add(s1, r2); + y25 = L_add(s3, r4); + y27 = L_sub(s3, r4); + + /* 1. FFT3 stage */ + + /* real part */ + r1 = L_add(y10, y20); + r2 = Mpy_32_xx(L_sub(y10, y20), C31); + z00 = L_add(y00, r1); + r1 = L_sub(y00, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y11, y21); + s2 = Mpy_32_xx(L_sub(y11, y21), C31); + z01 = L_add(y01, s1); + s1 = L_sub(y01, L_shr_pos(s1, 1)); + + /* combination */ + z20 = L_sub(r1, s2); + z10 = L_add(r1, s2); + z21 = L_add(s1, r2); + z11 = L_sub(s1, r2); + + /* 2. FFT3 stage */ + + /* real part */ + r1 = L_add(y12, y22); + r2 = Mpy_32_xx(L_sub(y12, y22), C31); + z12 = L_add(y02, r1); + r1 = L_sub(y02, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y13, y23); + s2 = Mpy_32_xx(L_sub(y13, y23), C31); + z13 = L_add(y03, s1); + s1 = L_sub(y03, L_shr_pos(s1, 1)); + + /* combination */ + z02 = L_sub(r1, s2); + z22 = L_add(r1, s2); + z03 = L_add(s1, r2); + z23 = L_sub(s1, r2); + + /* 3. FFT3 stage */ + + /* real part */ + r1 = L_add(y14, y24); + r2 = Mpy_32_xx(L_sub(y14, y24), C31); + z24 = L_add(y04, r1); + r1 = L_sub(y04, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y15, y25); + s2 = Mpy_32_xx(L_sub(y15, y25), C31); + z25 = L_add(y05, s1); + s1 = L_sub(y05, L_shr_pos(s1, 1)); + + /* combination */ + z14 = L_sub(r1, s2); + z04 = L_add(r1, s2); + z15 = L_add(s1, r2); + z05 = L_sub(s1, r2); + + /* 4. FFT3 stage */ + + /* real part */ + r1 = L_add(y16, y26); + r2 = Mpy_32_xx(L_sub(y16, y26), C31); + z06 = L_add(y06, r1); + r1 = L_sub(y06, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y17, y27); + s2 = Mpy_32_xx(L_sub(y17, y27), C31); + z07 = L_add(y07, s1); + s1 = L_sub(y07, L_shr_pos(s1, 1)); + + /* combination */ + z26 = L_sub(r1, s2); + z16 = L_add(r1, s2); + z27 = L_add(s1, r2); + z17 = L_sub(s1, r2); + + /* 5. FFT3 stage */ + + /* real part */ + r1 = L_add(y18, y28); + r2 = Mpy_32_xx(L_sub(y18, y28), C31); + z18 = L_add(y08, r1); + r1 = L_sub(y08, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y19, y29); + s2 = Mpy_32_xx(L_sub(y19, y29), C31); + z19 = L_add(y09, s1); + s1 = L_sub(y09, L_shr_pos(s1, 1)); + + /* combination */ + z08 = L_sub(r1, s2); + z28 = L_add(r1, s2); + z09 = L_add(s1, r2); + z29 = L_sub(s1, r2); + + /* 2. FFT15 stage */ + x00 = L_shr_pos(re[s * 15], SCALEFACTOR30_1); + x01 = L_shr_pos(im[s * 15], SCALEFACTOR30_1); + x02 = L_shr_pos(re[s * 3], SCALEFACTOR30_1); + x03 = L_shr_pos(im[s * 3], SCALEFACTOR30_1); + x04 = L_shr_pos(re[s * 21], SCALEFACTOR30_1); + x05 = L_shr_pos(im[s * 21], SCALEFACTOR30_1); + x06 = L_shr_pos(re[s * 9], SCALEFACTOR30_1); + x07 = L_shr_pos(im[s * 9], SCALEFACTOR30_1); + x08 = L_shr_pos(re[s * 27], SCALEFACTOR30_1); + x09 = L_shr_pos(im[s * 27], SCALEFACTOR30_1); + + x10 = L_shr_pos(re[s * 5], SCALEFACTOR30_1); + x11 = L_shr_pos(im[s * 5], SCALEFACTOR30_1); + x12 = L_shr_pos(re[s * 23], SCALEFACTOR30_1); + x13 = L_shr_pos(im[s * 23], SCALEFACTOR30_1); + x14 = L_shr_pos(re[s * 11], SCALEFACTOR30_1); + x15 = L_shr_pos(im[s * 11], SCALEFACTOR30_1); + x16 = L_shr_pos(re[s * 29], SCALEFACTOR30_1); + x17 = L_shr_pos(im[s * 29], SCALEFACTOR30_1); + x18 = L_shr_pos(re[s * 17], SCALEFACTOR30_1); + x19 = L_shr_pos(im[s * 17], SCALEFACTOR30_1); + + x20 = L_shr_pos(re[s * 25], SCALEFACTOR30_1); + x21 = L_shr_pos(im[s * 25], SCALEFACTOR30_1); + x22 = L_shr_pos(re[s * 13], SCALEFACTOR30_1); + x23 = L_shr_pos(im[s * 13], SCALEFACTOR30_1); + x24 = L_shr_pos(re[s * 1], SCALEFACTOR30_1); + x25 = L_shr_pos(im[s * 1], SCALEFACTOR30_1); + x26 = L_shr_pos(re[s * 19], SCALEFACTOR30_1); + x27 = L_shr_pos(im[s * 19], SCALEFACTOR30_1); + x28 = L_shr_pos(re[s * 7], SCALEFACTOR30_1); + x29 = L_shr_pos(im[s * 7], SCALEFACTOR30_1); + + /* 1. FFT5 stage */ + + /* real part */ + r1 = L_add(x02, x08); + r4 = L_sub(x02, x08); + r3 = L_add(x04, x06); + r2 = L_sub(x04, x06); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x00, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x03, x09); + s4 = L_sub(x03, x09); + s3 = L_add(x05, x07); + s2 = L_sub(x05, x07); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x01, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y02 = L_add(r1, s2); + y08 = L_sub(r1, s2); + y04 = L_sub(r3, s4); + y06 = L_add(r3, s4); + + y03 = L_sub(s1, r2); + y09 = L_add(s1, r2); + y05 = L_add(s3, r4); + y07 = L_sub(s3, r4); + + /* 2. FFT5 stage */ + + /* real part */ + r1 = L_add(x12, x18); + r4 = L_sub(x12, x18); + r3 = L_add(x14, x16); + r2 = L_sub(x14, x16); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y10 = L_add(x10, r1); + r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x13, x19); + s4 = L_sub(x13, x19); + s3 = L_add(x15, x17); + s2 = L_sub(x15, x17); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y11 = L_add(x11, s1); + s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y12 = L_add(r1, s2); + y18 = L_sub(r1, s2); + y14 = L_sub(r3, s4); + y16 = L_add(r3, s4); + + y13 = L_sub(s1, r2); + y19 = L_add(s1, r2); + y15 = L_add(s3, r4); + y17 = L_sub(s3, r4); + + /* 3. FFT5 stage */ + + /* real part */ + r1 = L_add(x22, x28); + r4 = L_sub(x22, x28); + r3 = L_add(x24, x26); + r2 = L_sub(x24, x26); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y20 = L_add(x20, r1); + r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x23, x29); + s4 = L_sub(x23, x29); + s3 = L_add(x25, x27); + s2 = L_sub(x25, x27); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y21 = L_add(x21, s1); + s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y22 = L_add(r1, s2); + y28 = L_sub(r1, s2); + y24 = L_sub(r3, s4); + y26 = L_add(r3, s4); + + y23 = L_sub(s1, r2); + y29 = L_add(s1, r2); + y25 = L_add(s3, r4); + y27 = L_sub(s3, r4); + + /* 1. FFT3 stage */ + + /* real part */ + r1 = L_add(y10, y20); + r2 = Mpy_32_xx(L_sub(y10, y20), C31); + z30 = L_add(y00, r1); + r1 = L_sub(y00, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y11, y21); + s2 = Mpy_32_xx(L_sub(y11, y21), C31); + z31 = L_add(y01, s1); + s1 = L_sub(y01, L_shr_pos(s1, 1)); + + /* combination */ + z50 = L_sub(r1, s2); + z40 = L_add(r1, s2); + z51 = L_add(s1, r2); + z41 = L_sub(s1, r2); + + /* 2. FFT3 stage */ + + /* real part */ + r1 = L_add(y12, y22); + r2 = Mpy_32_xx(L_sub(y12, y22), C31); + z42 = L_add(y02, r1); + r1 = L_sub(y02, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y13, y23); + s2 = Mpy_32_xx(L_sub(y13, y23), C31); + z43 = L_add(y03, s1); + s1 = L_sub(y03, L_shr_pos(s1, 1)); + + /* combination */ + z32 = L_sub(r1, s2); + z52 = L_add(r1, s2); + z33 = L_add(s1, r2); + z53 = L_sub(s1, r2); + + /* 3. FFT3 stage */ + + /* real part */ + r1 = L_add(y14, y24); + r2 = Mpy_32_xx(L_sub(y14, y24), C31); + z54 = L_add(y04, r1); + r1 = L_sub(y04, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y15, y25); + s2 = Mpy_32_xx(L_sub(y15, y25), C31); + z55 = L_add(y05, s1); + s1 = L_sub(y05, L_shr_pos(s1, 1)); + + /* combination */ + z44 = L_sub(r1, s2); + z34 = L_add(r1, s2); + z45 = L_add(s1, r2); + z35 = L_sub(s1, r2); + + /* 4. FFT3 stage */ + + /* real part */ + r1 = L_add(y16, y26); + r2 = Mpy_32_xx(L_sub(y16, y26), C31); + z36 = L_add(y06, r1); + r1 = L_sub(y06, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y17, y27); + s2 = Mpy_32_xx(L_sub(y17, y27), C31); + z37 = L_add(y07, s1); + s1 = L_sub(y07, L_shr_pos(s1, 1)); + + /* combination */ + z56 = L_sub(r1, s2); + z46 = L_add(r1, s2); + z57 = L_add(s1, r2); + z47 = L_sub(s1, r2); + + /* 5. FFT3 stage */ + + /* real part */ + r1 = L_add(y18, y28); + r2 = Mpy_32_xx(L_sub(y18, y28), C31); + z48 = L_add(y08, r1); + r1 = L_sub(y08, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y19, y29); + s2 = Mpy_32_xx(L_sub(y19, y29), C31); + z49 = L_add(y09, s1); + s1 = L_sub(y09, L_shr_pos(s1, 1)); + + /* combination */ + z38 = L_sub(r1, s2); + z58 = L_add(r1, s2); + z39 = L_add(s1, r2); + z59 = L_sub(s1, r2); + + /* 1. FFT2 stage */ + r1 = L_shr_pos(z00, SCALEFACTOR30_2); + r2 = L_shr_pos(z30, SCALEFACTOR30_2); + r3 = L_shr_pos(z01, SCALEFACTOR30_2); + r4 = L_shr_pos(z31, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 2. FFT2 stage */ + r1 = L_shr_pos(z16, SCALEFACTOR30_2); + r2 = L_shr_pos(z46, SCALEFACTOR30_2); + r3 = L_shr_pos(z17, SCALEFACTOR30_2); + r4 = L_shr_pos(z47, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 3. FFT2 stage */ + r1 = L_shr_pos(z02, SCALEFACTOR30_2); + r2 = L_shr_pos(z32, SCALEFACTOR30_2); + r3 = L_shr_pos(z03, SCALEFACTOR30_2); + r4 = L_shr_pos(z33, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 4. FFT2 stage */ + r1 = L_shr_pos(z18, SCALEFACTOR30_2); + r2 = L_shr_pos(z48, SCALEFACTOR30_2); + r3 = L_shr_pos(z19, SCALEFACTOR30_2); + r4 = L_shr_pos(z49, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 5. FFT2 stage */ + r1 = L_shr_pos(z04, SCALEFACTOR30_2); + r2 = L_shr_pos(z34, SCALEFACTOR30_2); + r3 = L_shr_pos(z05, SCALEFACTOR30_2); + r4 = L_shr_pos(z35, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 6. FFT2 stage */ + r1 = L_shr_pos(z20, SCALEFACTOR30_2); + r2 = L_shr_pos(z50, SCALEFACTOR30_2); + r3 = L_shr_pos(z21, SCALEFACTOR30_2); + r4 = L_shr_pos(z51, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 7. FFT2 stage */ + r1 = L_shr_pos(z06, SCALEFACTOR30_2); + r2 = L_shr_pos(z36, SCALEFACTOR30_2); + r3 = L_shr_pos(z07, SCALEFACTOR30_2); + r4 = L_shr_pos(z37, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 8. FFT2 stage */ + r1 = L_shr_pos(z22, SCALEFACTOR30_2); + r2 = L_shr_pos(z52, SCALEFACTOR30_2); + r3 = L_shr_pos(z23, SCALEFACTOR30_2); + r4 = L_shr_pos(z53, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 9. FFT2 stage */ + r1 = L_shr_pos(z08, SCALEFACTOR30_2); + r2 = L_shr_pos(z38, SCALEFACTOR30_2); + r3 = L_shr_pos(z09, SCALEFACTOR30_2); + r4 = L_shr_pos(z39, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 10. FFT2 stage */ + r1 = L_shr_pos(z24, SCALEFACTOR30_2); + r2 = L_shr_pos(z54, SCALEFACTOR30_2); + r3 = L_shr_pos(z25, SCALEFACTOR30_2); + r4 = L_shr_pos(z55, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 11. FFT2 stage */ + r1 = L_shr_pos(z10, SCALEFACTOR30_2); + r2 = L_shr_pos(z40, SCALEFACTOR30_2); + r3 = L_shr_pos(z11, SCALEFACTOR30_2); + r4 = L_shr_pos(z41, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 12. FFT2 stage */ + r1 = L_shr_pos(z26, SCALEFACTOR30_2); + r2 = L_shr_pos(z56, SCALEFACTOR30_2); + r3 = L_shr_pos(z27, SCALEFACTOR30_2); + r4 = L_shr_pos(z57, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 13. FFT2 stage */ + r1 = L_shr_pos(z12, SCALEFACTOR30_2); + r2 = L_shr_pos(z42, SCALEFACTOR30_2); + r3 = L_shr_pos(z13, SCALEFACTOR30_2); + r4 = L_shr_pos(z43, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 14. FFT2 stage */ + r1 = L_shr_pos(z28, SCALEFACTOR30_2); + r2 = L_shr_pos(z58, SCALEFACTOR30_2); + r3 = L_shr_pos(z29, SCALEFACTOR30_2); + r4 = L_shr_pos(z59, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 15. FFT2 stage */ + r1 = L_shr_pos(z14, SCALEFACTOR30_2); + r2 = L_shr_pos(z44, SCALEFACTOR30_2); + r3 = L_shr_pos(z15, SCALEFACTOR30_2); + r4 = L_shr_pos(z45, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 32-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR32 bits. + * + * WOPS with 32x16 bit multiplications: 752 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft32(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 as, bs; Word32 x00, x01, x02, x03, x04, x05, x06, x07; + Word32 x08, x09, x10, x11, x12, x13, x14, x15; Word32 t00, t01, t02, t03, t04, t05, t06, t07; + Word32 t08, t09, t10, t11, t12, t13, t14, t15; Word32 s00, s01, s02, s03, s04, s05, s06, s07; + Word32 s08, s09, s10, s11, s12, s13, s14, s15; + + Word32 y00, y01, y02, y03, y04, y05, y06, y07; Word32 y08, y09, y10, y11, y12, y13, y14, y15; + Word32 y16, y17, y18, y19, y20, y21, y22, y23; Word32 y24, y25, y26, y27, y28, y29, y30, y31; + Word32 y32, y33, y34, y35, y36, y37, y38, y39; Word32 y40, y41, y42, y43, y44, y45, y46, y47; + Word32 y48, y49, y50, y51, y52, y53, y54, y55; Word32 y56, y57, y58, y59, y60, y61, y62, y63;); + + /* 1. FFT8 stage */ + x00 = L_shr_pos(re[s * 0], SCALEFACTOR32_1); + x01 = L_shr_pos(im[s * 0], SCALEFACTOR32_1); + x02 = L_shr_pos(re[s * 4], SCALEFACTOR32_1); + x03 = L_shr_pos(im[s * 4], SCALEFACTOR32_1); + x04 = L_shr_pos(re[s * 8], SCALEFACTOR32_1); + x05 = L_shr_pos(im[s * 8], SCALEFACTOR32_1); + x06 = L_shr_pos(re[s * 12], SCALEFACTOR32_1); + x07 = L_shr_pos(im[s * 12], SCALEFACTOR32_1); + x08 = L_shr_pos(re[s * 16], SCALEFACTOR32_1); + x09 = L_shr_pos(im[s * 16], SCALEFACTOR32_1); + x10 = L_shr_pos(re[s * 20], SCALEFACTOR32_1); + x11 = L_shr_pos(im[s * 20], SCALEFACTOR32_1); + x12 = L_shr_pos(re[s * 24], SCALEFACTOR32_1); + x13 = L_shr_pos(im[s * 24], SCALEFACTOR32_1); + x14 = L_shr_pos(re[s * 28], SCALEFACTOR32_1); + x15 = L_shr_pos(im[s * 28], SCALEFACTOR32_1); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03); + + /* Post-additions */ + y00 = L_add(s00, s02); + y08 = L_sub(s00, s02); + y01 = L_add(s01, s03); + y09 = L_sub(s01, s03); + y04 = L_sub(s04, s06); + y12 = L_add(s04, s06); + y05 = L_sub(s05, s07); + y13 = L_add(s05, s07); + y06 = L_add(s08, s14); + y14 = L_sub(s08, s14); + y07 = L_add(s09, s15); + y15 = L_sub(s09, s15); + y02 = L_add(s10, s12); + y10 = L_sub(s10, s12); + y03 = L_add(s11, s13); + y11 = L_sub(s11, s13); + + /* 2. FFT8 stage */ + x00 = L_shr_pos(re[s * 1], SCALEFACTOR32_1); + x01 = L_shr_pos(im[s * 1], SCALEFACTOR32_1); + x02 = L_shr_pos(re[s * 5], SCALEFACTOR32_1); + x03 = L_shr_pos(im[s * 5], SCALEFACTOR32_1); + x04 = L_shr_pos(re[s * 9], SCALEFACTOR32_1); + x05 = L_shr_pos(im[s * 9], SCALEFACTOR32_1); + x06 = L_shr_pos(re[s * 13], SCALEFACTOR32_1); + x07 = L_shr_pos(im[s * 13], SCALEFACTOR32_1); + x08 = L_shr_pos(re[s * 17], SCALEFACTOR32_1); + x09 = L_shr_pos(im[s * 17], SCALEFACTOR32_1); + x10 = L_shr_pos(re[s * 21], SCALEFACTOR32_1); + x11 = L_shr_pos(im[s * 21], SCALEFACTOR32_1); + x12 = L_shr_pos(re[s * 25], SCALEFACTOR32_1); + x13 = L_shr_pos(im[s * 25], SCALEFACTOR32_1); + x14 = L_shr_pos(re[s * 29], SCALEFACTOR32_1); + x15 = L_shr_pos(im[s * 29], SCALEFACTOR32_1); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03); + + /* Post-additions */ + y16 = L_add(s00, s02); + y24 = L_sub(s00, s02); + y17 = L_add(s01, s03); + y25 = L_sub(s01, s03); + y20 = L_sub(s04, s06); + y28 = L_add(s04, s06); + y21 = L_sub(s05, s07); + y29 = L_add(s05, s07); + y22 = L_add(s08, s14); + y30 = L_sub(s08, s14); + y23 = L_add(s09, s15); + y31 = L_sub(s09, s15); + y18 = L_add(s10, s12); + y26 = L_sub(s10, s12); + y19 = L_add(s11, s13); + y27 = L_sub(s11, s13); + + /* 3. FFT8 stage */ + x00 = L_shr_pos(re[s * 2], SCALEFACTOR32_1); + x01 = L_shr_pos(im[s * 2], SCALEFACTOR32_1); + x02 = L_shr_pos(re[s * 6], SCALEFACTOR32_1); + x03 = L_shr_pos(im[s * 6], SCALEFACTOR32_1); + x04 = L_shr_pos(re[s * 10], SCALEFACTOR32_1); + x05 = L_shr_pos(im[s * 10], SCALEFACTOR32_1); + x06 = L_shr_pos(re[s * 14], SCALEFACTOR32_1); + x07 = L_shr_pos(im[s * 14], SCALEFACTOR32_1); + x08 = L_shr_pos(re[s * 18], SCALEFACTOR32_1); + x09 = L_shr_pos(im[s * 18], SCALEFACTOR32_1); + x10 = L_shr_pos(re[s * 22], SCALEFACTOR32_1); + x11 = L_shr_pos(im[s * 22], SCALEFACTOR32_1); + x12 = L_shr_pos(re[s * 26], SCALEFACTOR32_1); + x13 = L_shr_pos(im[s * 26], SCALEFACTOR32_1); + x14 = L_shr_pos(re[s * 30], SCALEFACTOR32_1); + x15 = L_shr_pos(im[s * 30], SCALEFACTOR32_1); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03); + + /* Post-additions */ + y32 = L_add(s00, s02); + y40 = L_sub(s00, s02); + y33 = L_add(s01, s03); + y41 = L_sub(s01, s03); + y36 = L_sub(s04, s06); + y44 = L_add(s04, s06); + y37 = L_sub(s05, s07); + y45 = L_add(s05, s07); + y38 = L_add(s08, s14); + y46 = L_sub(s08, s14); + y39 = L_add(s09, s15); + y47 = L_sub(s09, s15); + y34 = L_add(s10, s12); + y42 = L_sub(s10, s12); + y35 = L_add(s11, s13); + y43 = L_sub(s11, s13); + + /* 4. FFT8 stage */ + x00 = L_shr_pos(re[s * 3], SCALEFACTOR32_1); + x01 = L_shr_pos(im[s * 3], SCALEFACTOR32_1); + x02 = L_shr_pos(re[s * 7], SCALEFACTOR32_1); + x03 = L_shr_pos(im[s * 7], SCALEFACTOR32_1); + x04 = L_shr_pos(re[s * 11], SCALEFACTOR32_1); + x05 = L_shr_pos(im[s * 11], SCALEFACTOR32_1); + x06 = L_shr_pos(re[s * 15], SCALEFACTOR32_1); + x07 = L_shr_pos(im[s * 15], SCALEFACTOR32_1); + x08 = L_shr_pos(re[s * 19], SCALEFACTOR32_1); + x09 = L_shr_pos(im[s * 19], SCALEFACTOR32_1); + x10 = L_shr_pos(re[s * 23], SCALEFACTOR32_1); + x11 = L_shr_pos(im[s * 23], SCALEFACTOR32_1); + x12 = L_shr_pos(re[s * 27], SCALEFACTOR32_1); + x13 = L_shr_pos(im[s * 27], SCALEFACTOR32_1); + x14 = L_shr_pos(re[s * 31], SCALEFACTOR32_1); + x15 = L_shr_pos(im[s * 31], SCALEFACTOR32_1); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03); + + /* Post-additions */ + y48 = L_add(s00, s02); + y56 = L_sub(s00, s02); + y49 = L_add(s01, s03); + y57 = L_sub(s01, s03); + y52 = L_sub(s04, s06); + y60 = L_add(s04, s06); + y53 = L_sub(s05, s07); + y61 = L_add(s05, s07); + y54 = L_add(s08, s14); + y62 = L_sub(s08, s14); + y55 = L_add(s09, s15); + y63 = L_sub(s09, s15); + y50 = L_add(s10, s12); + y58 = L_sub(s10, s12); + y51 = L_add(s11, s13); + y59 = L_sub(s11, s13); + + /* apply twiddle factors */ + y00 = L_shr_pos(y00, SCALEFACTOR32_2); + y01 = L_shr_pos(y01, SCALEFACTOR32_2); + y02 = L_shr_pos(y02, SCALEFACTOR32_2); + y03 = L_shr_pos(y03, SCALEFACTOR32_2); + y04 = L_shr_pos(y04, SCALEFACTOR32_2); + y05 = L_shr_pos(y05, SCALEFACTOR32_2); + y06 = L_shr_pos(y06, SCALEFACTOR32_2); + y07 = L_shr_pos(y07, SCALEFACTOR32_2); + y08 = L_shr_pos(y08, SCALEFACTOR32_2); + y09 = L_shr_pos(y09, SCALEFACTOR32_2); + y10 = L_shr_pos(y10, SCALEFACTOR32_2); + y11 = L_shr_pos(y11, SCALEFACTOR32_2); + y12 = L_shr_pos(y12, SCALEFACTOR32_2); + y13 = L_shr_pos(y13, SCALEFACTOR32_2); + y14 = L_shr_pos(y14, SCALEFACTOR32_2); + y15 = L_shr_pos(y15, SCALEFACTOR32_2); + y16 = L_shr_pos(y16, SCALEFACTOR32_2); + y17 = L_shr_pos(y17, SCALEFACTOR32_2); + y32 = L_shr_pos(y32, SCALEFACTOR32_2); + y33 = L_shr_pos(y33, SCALEFACTOR32_2); + y48 = L_shr_pos(y48, SCALEFACTOR32_2); + y49 = L_shr_pos(y49, SCALEFACTOR32_2); + y40 = L_shr_pos(y40, SCALEFACTOR32_2); + y41 = L_shr_pos(y41, SCALEFACTOR32_2); + + cplxMpy3_0(y18, y19, RotVector_32_32[2 * 0 + 0], RotVector_32_32[2 * 0 + 1]); + cplxMpy3_0(y20, y21, RotVector_32_32[2 * 1 + 0], RotVector_32_32[2 * 1 + 1]); + cplxMpy3_0(y22, y23, RotVector_32_32[2 * 2 + 0], RotVector_32_32[2 * 2 + 1]); + cplxMpy3_0(y24, y25, RotVector_32_32[2 * 3 + 0], RotVector_32_32[2 * 3 + 1]); + cplxMpy3_0(y26, y27, RotVector_32_32[2 * 4 + 0], RotVector_32_32[2 * 4 + 1]); + cplxMpy3_0(y28, y29, RotVector_32_32[2 * 5 + 0], RotVector_32_32[2 * 5 + 1]); + cplxMpy3_0(y30, y31, RotVector_32_32[2 * 6 + 0], RotVector_32_32[2 * 6 + 1]); + cplxMpy3_0(y34, y35, RotVector_32_32[2 * 7 + 0], RotVector_32_32[2 * 7 + 1]); + cplxMpy3_0(y36, y37, RotVector_32_32[2 * 8 + 0], RotVector_32_32[2 * 8 + 1]); + cplxMpy3_0(y38, y39, RotVector_32_32[2 * 9 + 0], RotVector_32_32[2 * 9 + 1]); + cplxMpy3_0(y42, y43, RotVector_32_32[2 * 10 + 0], RotVector_32_32[2 * 10 + 1]); + cplxMpy3_0(y44, y45, RotVector_32_32[2 * 11 + 0], RotVector_32_32[2 * 11 + 1]); + cplxMpy3_0(y46, y47, RotVector_32_32[2 * 12 + 0], RotVector_32_32[2 * 12 + 1]); + cplxMpy3_0(y50, y51, RotVector_32_32[2 * 13 + 0], RotVector_32_32[2 * 13 + 1]); + cplxMpy3_0(y52, y53, RotVector_32_32[2 * 14 + 0], RotVector_32_32[2 * 14 + 1]); + cplxMpy3_0(y54, y55, RotVector_32_32[2 * 15 + 0], RotVector_32_32[2 * 15 + 1]); + cplxMpy3_0(y56, y57, RotVector_32_32[2 * 16 + 0], RotVector_32_32[2 * 16 + 1]); + cplxMpy3_0(y58, y59, RotVector_32_32[2 * 17 + 0], RotVector_32_32[2 * 17 + 1]); + cplxMpy3_0(y60, y61, RotVector_32_32[2 * 18 + 0], RotVector_32_32[2 * 18 + 1]); + cplxMpy3_0(y62, y63, RotVector_32_32[2 * 19 + 0], RotVector_32_32[2 * 19 + 1]); + + /* 1. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y00, y32); + t02 = L_sub(y00, y32); + t01 = L_add(y01, y33); + t03 = L_sub(y01, y33); + t04 = L_add(y16, y48); + t07 = L_sub(y16, y48); + t05 = L_add(y49, y17); + t06 = L_sub(y49, y17); + + /* Post-additions */ + re[s * 0] = L_add(t00, t04); + move32(); + im[s * 0] = L_add(t01, t05); + move32(); + re[s * 8] = L_sub(t02, t06); + move32(); + im[s * 8] = L_sub(t03, t07); + move32(); + re[s * 16] = L_sub(t00, t04); + move32(); + im[s * 16] = L_sub(t01, t05); + move32(); + re[s * 24] = L_add(t02, t06); + move32(); + im[s * 24] = L_add(t03, t07); + move32(); + + /* 2. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y02, y34); + t02 = L_sub(y02, y34); + t01 = L_add(y03, y35); + t03 = L_sub(y03, y35); + t04 = L_add(y18, y50); + t07 = L_sub(y18, y50); + t05 = L_add(y51, y19); + t06 = L_sub(y51, y19); + + /* Post-additions */ + re[s * 1] = L_add(t00, t04); + move32(); + im[s * 1] = L_add(t01, t05); + move32(); + re[s * 9] = L_sub(t02, t06); + move32(); + im[s * 9] = L_sub(t03, t07); + move32(); + re[s * 17] = L_sub(t00, t04); + move32(); + im[s * 17] = L_sub(t01, t05); + move32(); + re[s * 25] = L_add(t02, t06); + move32(); + im[s * 25] = L_add(t03, t07); + move32(); + + /* 3. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y04, y36); + t02 = L_sub(y04, y36); + t01 = L_add(y05, y37); + t03 = L_sub(y05, y37); + t04 = L_add(y20, y52); + t07 = L_sub(y20, y52); + t05 = L_add(y53, y21); + t06 = L_sub(y53, y21); + + /* Post-additions */ + re[s * 2] = L_add(t00, t04); + move32(); + im[s * 2] = L_add(t01, t05); + move32(); + re[s * 10] = L_sub(t02, t06); + move32(); + im[s * 10] = L_sub(t03, t07); + move32(); + re[s * 18] = L_sub(t00, t04); + move32(); + im[s * 18] = L_sub(t01, t05); + move32(); + re[s * 26] = L_add(t02, t06); + move32(); + im[s * 26] = L_add(t03, t07); + move32(); + + /* 4. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y06, y38); + t02 = L_sub(y06, y38); + t01 = L_add(y07, y39); + t03 = L_sub(y07, y39); + t04 = L_add(y22, y54); + t07 = L_sub(y22, y54); + t05 = L_add(y55, y23); + t06 = L_sub(y55, y23); + + /* Post-additions */ + re[s * 3] = L_add(t00, t04); + move32(); + im[s * 3] = L_add(t01, t05); + move32(); + re[s * 11] = L_sub(t02, t06); + move32(); + im[s * 11] = L_sub(t03, t07); + move32(); + re[s * 19] = L_sub(t00, t04); + move32(); + im[s * 19] = L_sub(t01, t05); + move32(); + re[s * 27] = L_add(t02, t06); + move32(); + im[s * 27] = L_add(t03, t07); + move32(); + + /* 5. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y08, y41); + t02 = L_sub(y08, y41); + t01 = L_sub(y09, y40); + t03 = L_add(y09, y40); + t04 = L_add(y24, y56); + t07 = L_sub(y24, y56); + t05 = L_add(y57, y25); + t06 = L_sub(y57, y25); + + /* Post-additions */ + re[s * 4] = L_add(t00, t04); + move32(); + im[s * 4] = L_add(t01, t05); + move32(); + re[s * 12] = L_sub(t02, t06); + move32(); + im[s * 12] = L_sub(t03, t07); + move32(); + re[s * 20] = L_sub(t00, t04); + move32(); + im[s * 20] = L_sub(t01, t05); + move32(); + re[s * 28] = L_add(t02, t06); + move32(); + im[s * 28] = L_add(t03, t07); + move32(); + + /* 6. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y10, y42); + t02 = L_sub(y10, y42); + t01 = L_add(y11, y43); + t03 = L_sub(y11, y43); + t04 = L_add(y26, y58); + t07 = L_sub(y26, y58); + t05 = L_add(y59, y27); + t06 = L_sub(y59, y27); + + /* Post-additions */ + re[s * 5] = L_add(t00, t04); + move32(); + im[s * 5] = L_add(t01, t05); + move32(); + re[s * 13] = L_sub(t02, t06); + move32(); + im[s * 13] = L_sub(t03, t07); + move32(); + re[s * 21] = L_sub(t00, t04); + move32(); + im[s * 21] = L_sub(t01, t05); + move32(); + re[s * 29] = L_add(t02, t06); + move32(); + im[s * 29] = L_add(t03, t07); + move32(); + + /* 7. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y12, y44); + t02 = L_sub(y12, y44); + t01 = L_add(y13, y45); + t03 = L_sub(y13, y45); + t04 = L_add(y28, y60); + t07 = L_sub(y28, y60); + t05 = L_add(y61, y29); + t06 = L_sub(y61, y29); + + /* Post-additions */ + re[s * 6] = L_add(t00, t04); + move32(); + im[s * 6] = L_add(t01, t05); + move32(); + re[s * 14] = L_sub(t02, t06); + move32(); + im[s * 14] = L_sub(t03, t07); + move32(); + re[s * 22] = L_sub(t00, t04); + move32(); + im[s * 22] = L_sub(t01, t05); + move32(); + re[s * 30] = L_add(t02, t06); + move32(); + im[s * 30] = L_add(t03, t07); + move32(); + + /* 8. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y14, y46); + t02 = L_sub(y14, y46); + t01 = L_add(y15, y47); + t03 = L_sub(y15, y47); + t04 = L_add(y30, y62); + t07 = L_sub(y30, y62); + t05 = L_add(y63, y31); + t06 = L_sub(y63, y31); + + /* Post-additions */ + re[s * 7] = L_add(t00, t04); + move32(); + im[s * 7] = L_add(t01, t05); + move32(); + re[s * 15] = L_sub(t02, t06); + move32(); + im[s * 15] = L_sub(t03, t07); + move32(); + re[s * 23] = L_sub(t00, t04); + move32(); + im[s * 23] = L_sub(t01, t05); + move32(); + re[s * 31] = L_add(t02, t06); + move32(); + im[s * 31] = L_add(t03, t07); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 40-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR40 bits. + * + * \param [i/o] re real part + * \param [i/o] im imag part + * \param [i ] sx stride real and imag part + * + * \return void + */ + + + +static void fft40(Word32 *re, Word32 *im, Word16 sx, Word32 *x) +{ + Dyn_Mem_Deluxe_In(const Word32 *W; Word16 dim1, dim2; Counter i, j; + Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15; + Word32 t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15; + Word32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15;); + + dim1 = 5; + move16(); + dim2 = 8; + move16(); + + W = RotVector_40_32; + + FOR (i = 0; i < dim2; i++) + { + FOR (j = 0; j < dim1; j++) + { + x[2 * i * dim1 + 2 * j] = re[sx * i + sx * j * dim2]; + move32(); + x[2 * i * dim1 + 2 * j + 1] = im[sx * i + sx * j * dim2]; + move32(); + } + } + + FOR (i = 0; i < dim2; i++) + { + fft5(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + + FOR (i = 0; i < dim1; i++) + { + cplxMpy4_8_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]); + + IF (i == 0) + { + cplxMpy4_8_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]); + cplxMpy4_8_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]); + cplxMpy4_8_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]); + cplxMpy4_8_1(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1]); + cplxMpy4_8_1(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1]); + cplxMpy4_8_1(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1]); + cplxMpy4_8_1(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1]); + } + ELSE + { + cplxMpy4_8_2(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1], W[2 * (i - 1) + 0 * 2 * 4], + W[2 * (i - 1) + 0 * 2 * 4 + 1]); + cplxMpy4_8_2(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1], W[2 * (i - 1) + 1 * 2 * 4], + W[2 * (i - 1) + 1 * 2 * 4 + 1]); + cplxMpy4_8_2(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1], W[2 * (i - 1) + 2 * 2 * 4], + W[2 * (i - 1) + 2 * 2 * 4 + 1]); + cplxMpy4_8_2(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1], W[2 * (i - 1) + 3 * 2 * 4], + W[2 * (i - 1) + 3 * 2 * 4 + 1]); + cplxMpy4_8_2(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1], W[2 * (i - 1) + 4 * 2 * 4], + W[2 * (i - 1) + 4 * 2 * 4 + 1]); + cplxMpy4_8_2(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1], W[2 * (i - 1) + 5 * 2 * 4], + W[2 * (i - 1) + 5 * 2 * 4 + 1]); + cplxMpy4_8_2(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1], W[2 * (i - 1) + 6 * 2 * 4], + W[2 * (i - 1) + 6 * 2 * 4 + 1]); + } + + t00 = L_shr_pos(L_add(x00, x08), SCALEFACTORN2 - 1); + t02 = L_shr_pos(L_sub(x00, x08), SCALEFACTORN2 - 1); + t01 = L_shr_pos(L_add(x01, x09), SCALEFACTORN2 - 1); + t03 = L_shr_pos(L_sub(x01, x09), SCALEFACTORN2 - 1); + t04 = L_shr_pos(L_add(x02, x10), SCALEFACTORN2 - 1); + t06 = L_sub(x02, x10); + t05 = L_shr_pos(L_add(x03, x11), SCALEFACTORN2 - 1); + t07 = L_sub(x03, x11); + t08 = L_shr_pos(L_add(x04, x12), SCALEFACTORN2 - 1); + t10 = L_shr_pos(L_sub(x04, x12), SCALEFACTORN2 - 1); + t09 = L_shr_pos(L_add(x05, x13), SCALEFACTORN2 - 1); + t11 = L_shr_pos(L_sub(x05, x13), SCALEFACTORN2 - 1); + t12 = L_shr_pos(L_add(x06, x14), SCALEFACTORN2 - 1); + t14 = L_sub(x06, x14); + t13 = L_shr_pos(L_add(x07, x15), SCALEFACTORN2 - 1); + t15 = L_sub(x07, x15); + + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + + t01 = L_shr_pos(L_add(t06, t14), SCALEFACTORN2 - 1); + t02 = L_shr_pos(L_sub(t06, t14), SCALEFACTORN2 - 1); + t00 = L_shr_pos(L_add(t07, t15), SCALEFACTORN2 - 1); + t03 = L_shr_pos(L_sub(t07, t15), SCALEFACTORN2 - 1); + + s12 = Mpy_32_32_lc3plus(L_add(t00, t02), C81_32); + s14 = Mpy_32_32_lc3plus(L_sub(t00, t02), C81_32); + s13 = Mpy_32_32_lc3plus(L_sub(t03, t01), C81_32); + s15 = Mpy_32_32_lc3plus(L_add(t01, t03), C82_32); + + re[sx * i + sx * 0 * dim1] = L_add(s00, s02); + move32(); + im[sx * i + sx * 0 * dim1] = L_add(s01, s03); + move32(); + re[sx * i + sx * 1 * dim1] = L_add(s10, s12); + move32(); + im[sx * i + sx * 1 * dim1] = L_add(s11, s13); + move32(); + re[sx * i + sx * 2 * dim1] = L_sub(s04, s06); + move32(); + im[sx * i + sx * 2 * dim1] = L_sub(s05, s07); + move32(); + re[sx * i + sx * 3 * dim1] = L_add(s08, s14); + move32(); + im[sx * i + sx * 3 * dim1] = L_add(s09, s15); + move32(); + re[sx * i + sx * 4 * dim1] = L_sub(s00, s02); + move32(); + im[sx * i + sx * 4 * dim1] = L_sub(s01, s03); + move32(); + re[sx * i + sx * 5 * dim1] = L_sub(s10, s12); + move32(); + im[sx * i + sx * 5 * dim1] = L_sub(s11, s13); + move32(); + re[sx * i + sx * 6 * dim1] = L_add(s04, s06); + move32(); + im[sx * i + sx * 6 * dim1] = L_add(s05, s07); + move32(); + re[sx * i + sx * 7 * dim1] = L_sub(s08, s14); + move32(); + im[sx * i + sx * 7 * dim1] = L_sub(s09, s15); + move32(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Combined FFT + * + * \param [i/o] re real part + * \param [i/o] im imag part + * \param [i ] W rotation factor + * \param [i ] dim1 length of fft1 + * \param [i ] dim2 length of fft2 + * \param [i ] sx stride real and imag part + * \param [i ] sc stride phase rotation coefficients + * \param [tmp] x 32-bit workbuffer of length=2*len + * \param [i ] Woff offset for addressing the rotation vector table + * + * \return void + */ + + +static void fftN2(Word32 *re, Word32 *im, +#ifdef ENABLE_HR_MODE + const Word32 *W, +#else + const Word16 *W, +#endif + Word16 dim1, Word16 dim2, Word16 sx, Word16 sc, + Word16 Woff + , Word8 *scratchBuffer +#ifdef ENABLE_FFT_RESCALE + , Word16 *scale +#endif + ) +{ + Dyn_Mem_Deluxe_In(Counter i, j;); + + Word32 *x = scratchAlign(scratchBuffer, 0); + + FOR (i = 0; i < dim2; i++) + { + FOR (j = 0; j < dim1; j++) + { + x[2 * i * dim1 + 2 * j] = re[sx * i + sx * j * dim2]; + move32(); + x[2 * i * dim1 + 2 * j + 1] = im[sx * i + sx * j * dim2]; + move32(); + } + } + + SWITCH (dim1) + { + + case 4: + FOR (i = 0; i < dim2; i++) + { + fft4(&x[i * 2 * dim1]); + } + BREAK; + case 8: + FOR (i = 0; i < dim2; i++) + { + fft8(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + + case 10: + FOR (i = 0; i < dim2; i++) + { + fft10(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + case 15: + FOR (i = 0; i < dim2; i++) + { + fft15(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + + BREAK; + case 16: + FOR (i = 0; i < dim2; i++) + { + fft16(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + case 20: + FOR (i = 0; i < dim2; i++) + { + fft20(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + case 30: + FOR (i = 0; i < dim2; i++) + { + fft30(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + case 32: + FOR (i = 0; i < dim2; i++) + { + fft32(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; +#ifdef ENABLE_HR_MODE +#if (defined LC3_FFT15) + case 60: + FOR (i = 0; i < dim2; i++) + { +#ifndef ENABLE_FFT_RESCALE + fftN2(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], RotVector_480, 15, 4, sx, 4, 60, scratch); +#else + fftN2(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], RotVector_480, 15, 4, sx, 4, 60, scratch, NULL); +#endif + } + BREAK; +#endif +#endif + default: ASSERT(0); + } + +#ifdef ENABLE_FFT_RESCALE + IF (scale) + { + *scale = s_max(sub(getScaleFactor32_lc3plus(x, dim1 * dim2 * 2), FFT_RESCALE_HR), 0); move16(); + +#if defined(FUNCTION_scaleValues_32) + scaleValues_32(x, dim1 * dim2, *scale); +#else + FOR (i = 0; i < dim1 * dim2 * 2; i++) + { + x[i] = L_shl_pos(x[i], *scale); move32(); + } + } +#endif +#endif + + SWITCH (dim2) + { + case 4: + { + Word32 x00, x01, x02, x03, x04, x05, x06, x07; + Word32 t00, t01, t02, t03, t04, t05, t06, t07; + + j = add(8, 0); + FOR (i = 0; i < dim1; i++) + { + cplxMpy4_4_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]); + IF (i == 0) + { + cplxMpy4_4_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]); + cplxMpy4_4_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]); + cplxMpy4_4_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]); + } + ELSE + { + cplxMpy4_4_0(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1], + W[sc * i + j * 1 * dim1 - Woff], W[sc * i + j * 1 * dim1 + 1 - Woff]); + cplxMpy4_4_0(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1], + W[sc * i + j * 2 * dim1 - Woff], W[sc * i + j * 2 * dim1 + 1 - Woff]); + cplxMpy4_4_0(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1], + W[sc * i + j * 3 * dim1 - Woff], W[sc * i + j * 3 * dim1 + 1 - Woff]); + } + + t00 = L_add(x00, x04); + t02 = L_sub(x00, x04); + t01 = L_add(x01, x05); + t03 = L_sub(x01, x05); + t04 = L_add(x02, x06); + t07 = L_sub(x02, x06); + t05 = L_add(x07, x03); + t06 = L_sub(x07, x03); + + re[sx * i + sx * 0 * dim1] = L_add(t00, t04); + move32(); + im[sx * i + sx * 0 * dim1] = L_add(t01, t05); + move32(); + re[sx * i + sx * 1 * dim1] = L_sub(t02, t06); + move32(); + im[sx * i + sx * 1 * dim1] = L_sub(t03, t07); + move32(); + re[sx * i + sx * 2 * dim1] = L_sub(t00, t04); + move32(); + im[sx * i + sx * 2 * dim1] = L_sub(t01, t05); + move32(); + re[sx * i + sx * 3 * dim1] = L_add(t02, t06); + move32(); + im[sx * i + sx * 3 * dim1] = L_add(t03, t07); + move32(); + } + + BREAK; + } + +#ifdef CR8_G_ADD_75MS + case 6: + { + Word32 y[2 * 10]; + FOR (j = 0; j < dim2; j++) + { + cplxMpy4_12_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]); + } + fft6(&y[0], &y[1], 2); + FOR (j = 0; j < dim2; j++) + { + re[sx * 0 + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * 0 + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + + FOR (i = 1; i < dim1; i++) + { + cplxMpy4_12_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1], + x[2 * i + 2 * (0 + 0) * dim1 + 1]); + cplxMpy4_12_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1], + x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff], + W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]); + FOR (j = 2; j < dim2; j = j + 2) + { + cplxMpy4_12_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1], + x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff], + W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]); + cplxMpy4_12_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1], + x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff], + W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]); + } + fft6(&y[0], &y[1], 2); + FOR (j = 0; j < dim2; j++) + { + re[sx * i + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * i + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + } + BREAK; + } +#endif + + case 8: + { + Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15; + Word32 t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15; + Word32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15; + + FOR (i = 0; i < dim1; i++) + { + cplxMpy4_8_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]); + IF (i == 0) + { + cplxMpy4_8_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]); + cplxMpy4_8_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]); + cplxMpy4_8_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]); + cplxMpy4_8_1(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1]); + cplxMpy4_8_1(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1]); + cplxMpy4_8_1(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1]); + cplxMpy4_8_1(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1]); + } + ELSE + { + cplxMpy4_8_0(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1], + W[sc * i + sc * 1 * dim1 - Woff], W[sc * i + sc * 1 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1], + W[sc * i + sc * 2 * dim1 - Woff], W[sc * i + sc * 2 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1], + W[sc * i + sc * 3 * dim1 - Woff], W[sc * i + sc * 3 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1], + W[sc * i + sc * 4 * dim1 - Woff], W[sc * i + sc * 4 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1], + W[sc * i + sc * 5 * dim1 - Woff], W[sc * i + sc * 5 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1], + W[sc * i + sc * 6 * dim1 - Woff], W[sc * i + sc * 6 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1], + W[sc * i + sc * 7 * dim1 - Woff], W[sc * i + sc * 7 * dim1 + 1 - Woff]); + } + + t00 = L_shr_pos(L_add(x00, x08), SCALEFACTORN2 - 1); + t02 = L_shr_pos(L_sub(x00, x08), SCALEFACTORN2 - 1); + t01 = L_shr_pos(L_add(x01, x09), SCALEFACTORN2 - 1); + t03 = L_shr_pos(L_sub(x01, x09), SCALEFACTORN2 - 1); + t04 = L_shr_pos(L_add(x02, x10), SCALEFACTORN2 - 1); + t06 = L_sub(x02, x10); + t05 = L_shr_pos(L_add(x03, x11), SCALEFACTORN2 - 1); + t07 = L_sub(x03, x11); + t08 = L_shr_pos(L_add(x04, x12), SCALEFACTORN2 - 1); + t10 = L_shr_pos(L_sub(x04, x12), SCALEFACTORN2 - 1); + t09 = L_shr_pos(L_add(x05, x13), SCALEFACTORN2 - 1); + t11 = L_shr_pos(L_sub(x05, x13), SCALEFACTORN2 - 1); + t12 = L_shr_pos(L_add(x06, x14), SCALEFACTORN2 - 1); + t14 = L_sub(x06, x14); + t13 = L_shr_pos(L_add(x07, x15), SCALEFACTORN2 - 1); + t15 = L_sub(x07, x15); + + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + + t01 = L_shr_pos(L_add(t06, t14), SCALEFACTORN2 - 1); + t02 = L_shr_pos(L_sub(t06, t14), SCALEFACTORN2 - 1); + t00 = L_shr_pos(L_add(t07, t15), SCALEFACTORN2 - 1); + t03 = L_shr_pos(L_sub(t07, t15), SCALEFACTORN2 - 1); + + s12 = Mpy_32_xx(L_add(t00, t02), C81); + s14 = Mpy_32_xx(L_sub(t00, t02), C81); + s13 = Mpy_32_xx(L_sub(t03, t01), C81); + s15 = Mpy_32_xx(L_add(t01, t03), C82); + + re[sx * i + sx * 0 * dim1] = L_add(s00, s02); + move32(); + im[sx * i + sx * 0 * dim1] = L_add(s01, s03); + move32(); + re[sx * i + sx * 1 * dim1] = L_add(s10, s12); + move32(); + im[sx * i + sx * 1 * dim1] = L_add(s11, s13); + move32(); + re[sx * i + sx * 2 * dim1] = L_sub(s04, s06); + move32(); + im[sx * i + sx * 2 * dim1] = L_sub(s05, s07); + move32(); + re[sx * i + sx * 3 * dim1] = L_add(s08, s14); + move32(); + im[sx * i + sx * 3 * dim1] = L_add(s09, s15); + move32(); + re[sx * i + sx * 4 * dim1] = L_sub(s00, s02); + move32(); + im[sx * i + sx * 4 * dim1] = L_sub(s01, s03); + move32(); + re[sx * i + sx * 5 * dim1] = L_sub(s10, s12); + move32(); + im[sx * i + sx * 5 * dim1] = L_sub(s11, s13); + move32(); + re[sx * i + sx * 6 * dim1] = L_add(s04, s06); + move32(); + im[sx * i + sx * 6 * dim1] = L_add(s05, s07); + move32(); + re[sx * i + sx * 7 * dim1] = L_sub(s08, s14); + move32(); + im[sx * i + sx * 7 * dim1] = L_sub(s09, s15); + move32(); + } + BREAK; + } + + case 12: + { + Word32 y[2 * 20]; + FOR (j = 0; j < dim2; j++) + { + cplxMpy4_12_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]); + } + fft12(y); + FOR (j = 0; j < dim2; j++) + { + re[sx * 0 + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * 0 + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + + FOR (i = 1; i < dim1; i++) + { + cplxMpy4_12_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1], + x[2 * i + 2 * (0 + 0) * dim1 + 1]); + cplxMpy4_12_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1], + x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff], + W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]); + FOR (j = 2; j < dim2; j = j + 2) + { + cplxMpy4_12_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1], + x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff], + W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]); + cplxMpy4_12_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1], + x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff], + W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]); + } + fft12(y); + FOR (j = 0; j < dim2; j++) + { + re[sx * i + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * i + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + } + BREAK; + } + +#if defined(ENABLE_HR_MODE) + case 16: + { + Word32 y[2 * 20]; + FOR (j = 0; j < dim2; j++) + { + cplxMpy4_16_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]); + } + + fft16(&y[0], &y[1], 2); + FOR (j = 0; j < dim2; j++) + { + re[sx * 0 + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * 0 + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + + FOR (i = 1; i < dim1; i++) + { + cplxMpy4_16_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1], + x[2 * i + 2 * (0 + 0) * dim1 + 1]); + cplxMpy4_16_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1], + x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff], + W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]); + FOR (j = 2; j < dim2; j = j + 2) + { + cplxMpy4_16_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1], + x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff], + W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]); + cplxMpy4_16_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1], + x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff], + W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]); + } + fft16(&y[0], &y[1], 2); + FOR (j = 0; j < dim2; j++) + { + re[sx * i + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * i + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + } + BREAK; + } +# endif + default: ASSERT(0); + } + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Complex valued FFT + * + * \param [i/o] re real part + * \param [i/o] im imag part + * \param [i ] sizeOfFft length of fft + * \param [i ] s stride real and imag part + * \param [i ] scale scalefactor + * + * \return void + */ + + + +/* x is the scratch buffer */ +void BASOP_cfft_lc3plus(Word32 *re, Word32 *im, Word16 length, Word16 s, Word16 *scale, Word32 *x) +{ +#if (defined ENABLE_FFT_RESCALE) && ((defined LC3_FFT30) || (defined ENABLE_HR_MODE)) + Word16 fftN2scale = 0; +#endif + +#ifdef ENABLE_HR_MODE + Word8 scratch[6128] = {0}; +#else + Word8 scratch[4068] = {0}; +#endif + + SWITCH (length) + { + + case 10: + fft10(re, im, s); + *scale = add(*scale, SCALEFACTOR10); + move16(); + BREAK; + case 16: + fft16(re, im, s); + *scale = add(*scale, SCALEFACTOR16); + move16(); + BREAK; + case 20: + fft20(re, im, s); + *scale = add(*scale, SCALEFACTOR20); + move16(); + BREAK; + case 30: + fft30(re, im, s); + *scale = add(*scale, SCALEFACTOR30); + move16(); + BREAK; + case 32: + fft32(re, im, s); + *scale = add(*scale, SCALEFACTOR32); + move16(); + BREAK; + case 40: + fft40(re, im, s, x); + *scale = add(*scale, SCALEFACTOR40); + move16(); + BREAK; + case 48: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_12, 4, 12, s, 16, 64, scratch); +#else + fftN2(re, im, RotVector_32_12, 4, 12, s, 16, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR48); + move16(); + BREAK; + case 60: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_480, 15, 4, s, 4, 60, scratch); +#else + fftN2(re, im, RotVector_480, 15, 4, s, 4, 60, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR60); + move16(); + BREAK; + case 64: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_8, 8, 8, s, 8, 64, scratch); +#else + fftN2(re, im, RotVector_32_8, 8, 8, s, 8, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR64); + move16(); + BREAK; + case 80: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_320, 10, 8, s, 4, 40, scratch); +#else + fftN2(re, im, RotVector_320, 10, 8, s, 4, 40, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR80); + move16(); + BREAK; + case 90: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_15_6, 15, 6, s, 2, 30, scratch); +#else + fftN2(re, im, RotVector_15_6, 15, 6, s, 2, 30, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR90); + move16(); + BREAK; + + case 120: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_480, 15, 8, s, 4, 60, scratch); +#else + fftN2(re, im, RotVector_480, 15, 8, s, 4, 60, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR120); + move16(); + BREAK; + case 128: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_8, 16, 8, s, 4, 64, scratch); +#else + fftN2(re, im, RotVector_32_8, 16, 8, s, 4, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR128); + move16(); + BREAK; + case 160: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_320, 20, 8, s, 2, 40, scratch); +#else + fftN2(re, im, RotVector_320, 20, 8, s, 2, 40, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR160); + move16(); + BREAK; + case 180: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_360, 15, 12, s, 4, 60, scratch); + *scale = add(*scale, SCALEFACTOR180); +#else + fftN2(re, im, RotVector_360, 15, 12, s, 4, 60, scratch, &fftN2scale); + *scale = add(*scale, SCALEFACTOR180); + *scale = sub(*scale, fftN2scale); move16(); +#endif + + move16(); + BREAK; + case 192: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_12, 16, 12, s, 4, 64, scratch); +#else + fftN2(re, im, RotVector_32_12, 16, 12, s, 4, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR192); + move16(); + BREAK; + case 240: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_480, 30, 8, s, 2, 60, scratch); + *scale = add(*scale, SCALEFACTOR240); +#else + fftN2(re, im, RotVector_480, 30, 8, s, 2, 60, scratch, &fftN2scale); + *scale = add(*scale, SCALEFACTOR240); + *scale = sub(*scale, fftN2scale); move16(); +#endif + move16(); + BREAK; + case 256: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_8, 32, 8, s, 2, 64, scratch); +#else + fftN2(re, im, RotVector_32_8, 32, 8, s, 2, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR256); + move16(); + BREAK; + case 384: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_12, 32, 12, s, 2, 64, scratch); +#else + fftN2(re, im, RotVector_32_12, 32, 12, s, 2, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR384); + move16(); + BREAK; +#ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS + case 360: + fftN2(re, im, RotVector_720, 30, 12, s, 2, 60, scratch, &fftN2scale); + *scale = add(*scale, SCALEFACTOR360); move16(); + *scale = sub(*scale, fftN2scale); move16(); + BREAK; +#endif + case 480: +#ifndef ENABLE_FFT_RESCALE +#ifndef ENABLE_FFT_30X16 + fftN2(re, im, RotVector_960, 60, 8, s, 2, 120, scratch); +#else + fftN2(re, im, RotVector_30_16, 30, 16, s, 2, 60, scratch); +#endif + *scale = add(*scale, SCALEFACTOR480); move16(); +#else +#ifndef ENABLE_FFT_30X16 + fftN2(re, im, RotVector_960, 60, 8, s, 2, 120, scratch, &fftN2scale); +#else + fftN2(re, im, RotVector_30_16, 30, 16, s, 2, 60, scratch, &fftN2scale); +#endif + *scale = add(*scale, SCALEFACTOR480); move16(); + *scale = sub(*scale, fftN2scale); move16(); +#endif + BREAK; +#endif + default: ASSERT(0); + } +} + + +#define RFFT_TWIDDLE1(x, t1, t2, t3, t4, w1, w2, xb0, xb1, xt0, xt1) \ + do \ + { \ + xb0 = L_shr_pos(x[2 * i + 0], 2); \ + xb1 = L_shr_pos(x[2 * i + 1], 2); \ + xt0 = L_shr_pos(x[sizeOfFft - 2 * i + 0], 2); \ + xt1 = L_shr_pos(x[sizeOfFft - 2 * i + 1], 2); \ + t1 = L_sub(xb0, xt0); \ + t2 = L_add(xb1, xt1); \ + t3 = L_sub(Mpy_32_32_lc3plus(t1, w1), Mpy_32_32_lc3plus(t2, w2)); \ + t4 = L_add(Mpy_32_32_lc3plus(t1, w2), Mpy_32_32_lc3plus(t2, w1)); \ + t1 = L_add(xb0, xt0); \ + t2 = L_sub(xb1, xt1); \ + } while (0) + +#define RFFT_TWIDDLE2(x, t1, t2, t3, t4, w1, w2, xb0, xb1, xt0, xt1) \ + do \ + { \ + xb0 = L_shr_pos(x[2 * i + 0], 2); \ + xb1 = L_shr_pos(x[2 * i + 1], 2); \ + xt0 = L_shr_pos(x[sizeOfFft - 2 * i + 0], 2); \ + xt1 = L_shr_pos(x[sizeOfFft - 2 * i + 1], 2); \ + t1 = L_sub(xb0, xt0); \ + t2 = L_add(xb1, xt1); \ + t3 = L_add(Mpy_32_32_lc3plus(t1, w1), Mpy_32_32_lc3plus(t2, w2)); \ + t4 = L_sub(Mpy_32_32_lc3plus(t2, w1), Mpy_32_32_lc3plus(t1, w2)); \ + t1 = L_add(xb0, xt0); \ + t2 = L_sub(xb1, xt1); \ + } while (0) + + + +static const Word32 *rfft_twid(int size) +{ + SWITCH (size) + { + case 32: return RealFFT32_twid; + case 40: return RealFFT40_twid; + case 64: return RealFFT64_twid; + case 80: return RealFFT80_twid; + case 96: return RealFFT96_twid; + case 128: return RealFFT128_twid; + case 192: return RealFFT192_twid; + case 256: return RealFFT256_twid; + case 384: return RealFFT384_twid; + case 512: return RealFFT512_twid; + case 768: return RealFFT768_twid; + default: ASSERT(0); + } + return NULL; +} + + +void BASOP_rfftN(Word32 *x, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer) +{ + Dyn_Mem_Deluxe_In(Counter i; Word16 sizeOfFft2, sizeOfFft4, sizeOfFft8; Word32 t1, t2, t3, t4, xb0, xb1, xt0, xt1; + Word32 * workBuffer; const Word32 *w32;); + + workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * sizeOfFft */ + w32 = rfft_twid(sizeOfFft); + + sizeOfFft2 = shr_pos(sizeOfFft, 1); + sizeOfFft4 = shr_pos(sizeOfFft, 2); + sizeOfFft8 = shr_pos(sizeOfFft, 3); + + BASOP_cfft_lc3plus(&x[0], &x[1], sizeOfFft2, 2, scale, workBuffer); + + xb0 = L_shr_pos(x[0], 1); + xb1 = L_shr_pos(x[1], 1); + x[0] = L_add(xb0, xb1); + move32(); + x[1] = L_sub(xb0, xb1); + move32(); + + FOR (i = 1; i < sizeOfFft8; i++) + { + RFFT_TWIDDLE1(x, t1, t2, t3, t4, w32[2 * i + 1], w32[2 * i], xb0, xb1, xt0, xt1); + x[2 * i] = L_sub(t1, t3); + move32(); + x[2 * i + 1] = L_sub(t2, t4); + move32(); + x[sizeOfFft - 2 * i] = L_add(t1, t3); + move32(); + x[sizeOfFft - 2 * i + 1] = L_negate(L_add(t2, t4)); + move32(); + } + + FOR (i = sizeOfFft8; i < sizeOfFft4; i++) + { + RFFT_TWIDDLE1(x, t1, t2, t3, t4, w32[(2 * sizeOfFft4 - 2 * i)], w32[(2 * sizeOfFft4 - 2 * i + 1)], xb0, xb1, + xt0, xt1); + x[2 * i] = L_sub(t1, t3); + move32(); + x[2 * i + 1] = L_sub(t2, t4); + move32(); + x[sizeOfFft - 2 * i] = L_add(t1, t3); + move32(); + x[sizeOfFft - 2 * i + 1] = L_negate(L_add(t2, t4)); + move32(); + } + + x[sizeOfFft - 2 * i] = L_shr_pos(x[2 * i + 0], 1); + move32(); + x[sizeOfFft - 2 * i + 1] = L_negate(L_shr_pos(x[2 * i + 1], 1)); + move32(); + + *scale = add(*scale, 1); + move16(); + + Dyn_Mem_Deluxe_Out(); +} + + + +void BASOP_irfftN(Word32 *x, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer) +{ + Dyn_Mem_Deluxe_In(Word16 sizeOfFft2, sizeOfFft4, sizeOfFft8; Word32 t1, t2, t3, t4, xb0, xb1, xt0, xt1; + Word32 * workBuffer; const Word32 *w32; Counter i;); + + workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * BASOP_CFFT_MAX_LENGTH */ + + w32 = rfft_twid(sizeOfFft); + + sizeOfFft2 = shr_pos(sizeOfFft, 1); + sizeOfFft4 = shr_pos(sizeOfFft, 2); + sizeOfFft8 = shr_pos(sizeOfFft, 3); + + xb0 = L_shr_pos(x[0], 2); + xb1 = L_shr_pos(x[1], 2); + x[0] = L_add(xb0, xb1); + move32(); + x[1] = L_sub(xb1, xb0); + move32(); + + FOR (i = 1; i < sizeOfFft8; i++) + { + RFFT_TWIDDLE2(x, t1, t2, t3, t4, w32[2 * i + 1], w32[2 * i], xb0, xb1, xt0, xt1); + x[2 * i] = L_sub(t1, t3); + move32(); + x[2 * i + 1] = L_sub(t4, t2); + move32(); + x[sizeOfFft - 2 * i] = L_add(t1, t3); + move32(); + x[sizeOfFft - 2 * i + 1] = L_add(t2, t4); + move32(); + } + + FOR (i = sizeOfFft8; i < sizeOfFft4; i++) + { + RFFT_TWIDDLE2(x, t1, t2, t3, t4, w32[(2 * sizeOfFft4 - 2 * i)], w32[(2 * sizeOfFft4 - 2 * i + 1)], xb0, xb1, + xt0, xt1); + x[2 * i] = L_sub(t1, t3); + move32(); + x[2 * i + 1] = L_sub(t4, t2); + move32(); + x[sizeOfFft - 2 * i] = L_add(t1, t3); + move32(); + x[sizeOfFft - 2 * i + 1] = L_add(t2, t4); + move32(); + } + + x[sizeOfFft - 2 * i] = L_shr_pos(x[2 * i + 0], 1); + move32(); + x[sizeOfFft - 2 * i + 1] = L_shr_pos(x[2 * i + 1], 1); + move32(); + + BASOP_cfft_lc3plus(&x[0], &x[1], sizeOfFft2, 2, scale, workBuffer); + + /* If you want BASOP_irfft to be inverse to BASOP_rfft then the result needs + * to be normalised by sizeOfFft */ + FOR (i = 0; i < sizeOfFft2; i++) + { + x[2 * i + 1] = L_negate(x[2 * i + 1]); + move32(); + } + + *scale = add(*scale, 2); + move16(); + + Dyn_Mem_Deluxe_Out(); +} + + diff --git a/lib_lc3plus/functions.h b/lib_lc3plus/functions.h index 01ad936f0..90571c6cd 100644 --- a/lib_lc3plus/functions.h +++ b/lib_lc3plus/functions.h @@ -1,351 +1,836 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef FUNCTIONS_H #define FUNCTIONS_H -#include "options.h" -#include "wmc_auto.h" -#include "clib.h" #include "defines.h" -#include "float.h" + +#include "stl.h" +#ifdef DYNMEM_COUNT +#include "dynmem.h" +#endif + +#include "basop_util_lc3plus.h" +#include "basop32.h" +#include "constants.h" #include "lc3.h" -#include "setup_dec_lc3.h" -#include "setup_enc_lc3.h" -#include "structs.h" -#include "util.h" - -/* FFT */ -#include "fft/iisfft.h" - -/* fft.c */ -void real_fft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle); -void real_ifft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle); -void real_fft_apply(Fft* fft, const LC3_FLOAT* in, LC3_FLOAT* out); - -void fft_init(Fft* fft, LC3_INT length); -void fft_free(Fft* fft); -void real_fft_free(Fft* fft); -void fft_apply(Fft* fft, const Complex* input, Complex* output); - -/* dct.c */ -void dct2_init(Dct2* dct, LC3_INT length); -void dct2_free(Dct2* dct); -void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output); - -void dct3_init(Dct3* dct, LC3_INT length); -void dct3_free(Dct3* dct); -void dct3_apply(Dct3* dct, const LC3_FLOAT* input, LC3_FLOAT* output); - -void dct4_init(Dct4* dct, LC3_INT length); -void dct4_free(Dct4* dct); -void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output); - -/* mdct.c */ -void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC3_INT hrmode); -void mdct_free(Mdct* mdct); -void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct); +#include "setup_dec_lc3.h" /* for decoder state handle ptr */ +#include "setup_enc_lc3.h" /* for encoder state handle ptr */ +#include "basop_mpy_lc3plus.h" + +#include +#include +#include +#include +#include + +#define PRINTF printf /* C console debug, */ +#define ASSERT(test) assert(test) + +typedef struct +{ + Word16 lead_sign_ind; /* this MPVQ index is the first part of the total PVQ index */ + UWord32 index, size; /* this MPVQ index is the second part of the total PVQ index */ + Word16 dim, k_val; + Word16 vec[PVQ_MAX_VEC_SIZE]; /* integer vector */ +} PvqEntry_fx; + +typedef enum { + LC3_CON_TEC_NS_STD, /* 0 */ + LC3_CON_TEC_PHASE_ECU, /* 2 */ + LC3_CON_TEC_TDPLC, /* 3 */ + LC3_CON_TEC_NS_ADV, /* 4 */ + LC3_CON_TEC_FREQ_MUTING, /* 5 */ +} LC3_ConcealTechnique; + +void WarnMsg(char *msg); +void ExitMsg(char *msg); +void AssertMsg(int true_flag, char *msg); + +void processTnsDecoder_fx(Word16 rc_idx[], Word32 x[], Word16 xLen, Word16 order[], Word16 *x_e, Word16 BW_stopband_idx, + Word16 frame_dms, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); -#ifdef ENABLE_PADDING -LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT bw_cutoff_bits, LC3_INT ep_enabled, LC3_INT* total_padding, LC3_INT *np_zero); -#endif - -void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits, - LC3_INT bw_cutoff_idx, LC3_INT lastnz, LC3_INT N, LC3_INT lsbMode, LC3_INT gg_idx, LC3_INT num_tns_filters, - LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx - , LC3_INT bfi_ext, LC3_INT fs_idx - ); -void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT N, LC3_INT fs_idx, - LC3_INT bw_cutoff_bits, LC3_INT* bfi, LC3_INT* gg_idx, LC3_INT* scf_idx, LC3_INT* fac_ns_idx, - LC3_INT* tns_numfilters, LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* bw_cutoff_idx, LC3_INT* lastnz, - LC3_INT* lsbMode, LC3_INT frame_dms - ); -void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT nt, LC3_INT totalBits, LC3_INT* nbits, LC3_INT* nbits2, LC3_INT fs, - LC3_INT* lastnzout, LC3_INT* codingdata, LC3_INT* lsbMode, LC3_INT mode, LC3_INT target, LC3_INT hrmode); - -void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC3_FLOAT* gain, LC3_INT* quantizedGain, - LC3_INT* quantizedGainMin, LC3_INT quantizedGainOff, LC3_FLOAT* targetBitsOff, - LC3_INT* old_targetBits, LC3_INT old_specBits, LC3_INT bq_mode - , LC3_INT regBits, LC3_FLOAT frame_ms +void processTnsCoder_fx(Word16 *bits, Word16 indexes[], Word32 x[], Word16 BW_cutoff_idx, Word16 order[], + Word16 *numfilters, Word16 enable_lpc_weighting, Word16 nSubdivisions, Word16 frame_dms, + Word16 max_len, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + , Word16 near_nyquist_flag ); -void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting, - LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx, - LC3_INT gg_idx, uint8_t* resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes, - LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms, - LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx, - LC3_INT hrmode - ); +void TnsUpdate_fx(Word16 *tns_numfilters, Word16 *long_startfreq, const Word16 **subdiv_startfreq, + const Word16 **subdiv_stopfreq, Word16 frame_length, Word16 tab_idx); + +void processResidualDecoding_fx(Word32 spectrum[], Word16 spectrum_e, Word16 L_spec, UWord8 prm[], Word16 resQBits +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); -void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT gains[], const LC3_INT bands_offset[], LC3_INT fdns_npts); +void processPreemph_fx(Word16 *x, Word16 len, Word16 mem[], Word16 memLen, Word16 out[], Word16 *outLen, Word16 mu); -void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t * resBits, - LC3_INT* numResBits - , LC3_INT hrmode +void processNoiseFilling_fx(Word32 xq[], Word16 nfseed, Word16 xq_e, Word16 fac_ns_idx, Word16 BW_cutoff_idx, + Word16 frame_dms, Word16 fac_ns_pc, Word16 spec_inv_idx, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif ); -void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits - , LC3_INT hrmode +void processNoiseFactor_fx(Word16 *fac_ns_idx, Word16 x_e, Word32 x[], +#ifdef ENABLE_HR_MODE + Word32 xq[], +#else + Word16 xq[], +#endif + Word16 gg, Word16 gg_e, Word16 BW_cutoff_idx, Word16 frame_dms, Word16 target_bytes, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif ); -void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, - LC3_INT* gainChange, LC3_INT fs_idx - , LC3_INT16 hrmode, LC3_INT16 frame_dms - ); +void processMdctShaping_fx(Word32 x[], +#ifdef ENABLE_HR_MODE + Word32 scf[], +#else + Word16 scf[], +#endif + Word16 scf_exp[], const Word16 bands_offset[], Word16 fdns_npts); -void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off); +void processScfScaling(Word16 scf_exp[], Word16 fdns_npts, Word16 *x_e); -void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms, - LC3_INT target_bytes - ); +void processMdct_fx( +#ifdef ENABLE_HR_MODE + Word32 x[], +#else + Word16 x[], +#endif + Word16 x_exp, Word16 N, +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION +# ifdef ENABLE_HR_MODE + Word16 hrmode, /* i: indicate high precision */ +# endif +#endif +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#endif + Word16 wLen, +#ifdef ENABLE_HR_MODE + Word32 mem[], /* i/o: last block of input samples */ +#else + Word16 mem[], /* i/o: last block of input samples */ +#endif + Word16 memLen, + Word32 y[], Word16 *y_e, Word8 *scratchBuffer); -void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx); +void processLevinson_fx(Word32 *lpc, Word32 *ac, Word16 N, Word16 *rc, Word32 *pred_err, Word8 *scratchBuffer); -void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, -#ifdef CR9_F_PITCH_WIN_LEN_FIX - LC3_INT* pitch_flag, +void lpc2rc(Word32 *lpc, Word16 *rc, Word16 N); + +void ProcessingIMDCT(Word32 y[], Word16 *y_e, +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + Word32 mem[], /* i/o: overlap add memory */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + Word16 mem[], /* i/o: overlap add memory */ +#endif + Word16 *mem_e, +#ifdef ENABLE_HR_MODE + Word32 x[], /* o: time signal out */ +#else + Word16 x[], /* o: time signal out */ +#endif + Word16 wLen, + Word16 N, Word16 memLen, Word16 frame_dms, + Word16 concealMethod, Word16 bfi, Word16 prev_bfi, Word16 nbLostFramesInRow, AplcSetup *plcAd, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +#ifdef ENABLE_HR_MODE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION +void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word16 hrmode, Word32 *workBuffer); +# else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ +void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word32 *workBuffer); +# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ +#else +void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word32 *workBuffer); #endif - LC3_INT* T0_out,LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms); -void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits, - LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out - , LC3_INT16 near_nyquist_flag - ); -void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLOAT* error, LC3_INT len); +#ifdef ENABLE_HR_MODE +Word16 find_last_nz_pair(const Word32 x[], Word16 length); +#else +Word16 find_last_nz_pair(const Word16 x[], Word16 length); +#endif -void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs); +PvqEntry_fx mpvq_index_fx(const Word16 *vec_in, Word16 dim_in, Word16 k_val_local); +void mpvq_deindex_fx(const PvqEntry_fx *entry, UWord32 *h_mem, Word16 *vec_out); + +void pvq_enc_search_fx(const Word16 *x, /* i: target vector to quantize Qin */ + Word16 * rt_far, /* o: outl_far o, raw pulses (non-scaled short) Q0 */ + Word16 * rt_near, /* o: outl_near o, raw pulses (non-scaled short) Q0 */ + Word16 * rtA, /* o: A section raw pulses (non-scaled short) Q0 */ + Word16 * rtB, /* o: B section raw pulses (non-scaled short) Q0 */ + Word32 *L_corr, /* o: 4 un-normalized correlation sums for outl_far, near, outl, A, AB */ + Word32 *L_search_en, /* o: 4 energy sums for out_far, outl_near, A, AB */ + Word16 *pulses_fin, /* i: number of allocated pulses to outl A, AB section */ + Word16 *pulses_proj, /* i: number of proj pulses pulses to outl, A , AB section */ + + const Word16 dim, /* i: Length of vector */ + const Word16 dimA /* i: Length of vector A section */ +); -void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx); +PvqEntry_fx get_size_mpvq_calc_offset_fx(Word16 dim_in, Word16 k_val_in, UWord32 *h_mem); -void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_LC3_INT); +Word16 pvq_dec_deidx_fx( /* out BER detected 1 , ok==0 */ + Word16 * y, /* o: decoded vector (non-scaled int) */ + const Word16 k_val, /* i: number of allocated pulses */ + const Word16 dim, /* i: Length of vector */ + const Word16 LS_ind, /* i; lS index 1 bit */ + const UWord32 UL_MPVQ_ind /* i; MPVQ index */ +); -void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx); -void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, - const LC3_INT bands_number, const LC3_FLOAT* ener -#ifdef CR8_E_TONE_DETECTOR - , const LC3_INT16 frame_dms, const LC3_INT16 hrmode ); +void pvq_dec_en1_norm_fx( /* */ +#ifdef ENABLE_HR_MODE + Word32 * xq, /* o: en1 normalized decoded vector (Q14) */ #else - ); -#endif -void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d); - -void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_INT winLen, LC3_INT last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x, - Dct4* dct); + Word16 * xq, /* o: en1 normalized decoded vector (Q14) */ +#endif + const Word16 *y, /* i: decoded vector (non-scaled int) */ + const Word16 kval_max, /* i: max possible K in Q0 kO or kA */ + const Word16 dim, /* i: Length of vector */ + const Word16 neg_glob_gain /* i: a Global Gain (negated to fit 1.0 in Q15 as -1.0) */ +); -void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT* win, LC3_INT32 winLen, LC3_INT32 last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x); +#ifdef ENABLE_HR_MODE +#ifdef WIN32 +#define mexPrintf(x, y) printf(x, y) +#endif +#endif -void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms, - LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch, - LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits -#ifdef CR9_K_REDUCE_NORM_CORR_TH - ,LC3_INT16 hrmode +void pvq_dec_en1_normQ14_fx( /* Have to be used by both encoder and decoder */ +#ifdef ENABLE_HR_MODE + Word32 * xq, /* o: en1 normalized decoded vector (Q14) */ +#else + Word16 * xq, /* o: en1 normalized decoded vector (Q14) */ #endif + const Word16 *y, /* i: decoded vector (non-scaled int) */ + const Word16 k_val_max, /* i: max possible K in Q0 kO or kA */ + const Word16 dim /* i: Length of vector */ ); -void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, - LC3_INT* mem_pitch_LC3_INT, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi, - LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, LC3_FLOAT damping - , LC3_INT *mem_ltpf_active -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3_INT frame_dms + +#ifdef ENABLE_HR_MODE +void pvq_dec_scale_vec_fx(const Word32 *inQ29, Word16 adjGainQ13, Word32 *outQ); +#else +void pvq_dec_scale_vec_fx(const Word16 *inQ14, Word16 adjGainQ13, Word16 *outQ14); +#endif + +Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side, Word16 mask_side, Word16 nbbits, +#ifdef ENABLE_HR_MODE + Word32 xq[], +#else + Word16 xq[], +#endif + Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz, + Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode, + Word16 enable_lpc_weighting, Word8 *scratchBuffer); + +void processAriDecoder_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec, + Word16 fs_idx, Word16 enable_lpc_weighting, Word16 tns_numfilters, Word16 lsbMode, + Word16 lastnz, Word16 *bfi, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, + Word16 frame_dms, + Word16 n_pc, Word16 be_bp_left, Word16 be_bp_right, Word16 mode, Word16 *spec_inv_idx, + Word16 *b_left, + Word16 *resBits, +#ifdef ENABLE_HR_MODE + Word32 *x, +#else + Word16 *x, +#endif + Word16 *nf_seed, UWord8 *resQdata, Word16 *tns_idx, Word16 *zero_frame, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode #endif ); -void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], - LC3_INT mem_out_len, LC3_FLOAT y[], LC3_INT* y_len, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT fs); +void processAriDecoderScaling_fx( +#ifdef ENABLE_HR_MODE + Word32 *datain, +#else + Word16 *data16, +#endif + Word16 dataLen, Word32 *data32, Word16 *data_e); + +void processApplyGlobalGain_fx(Word32 x[], Word16 *x_e, Word16 xLen, Word16 global_gain_idx, Word16 global_gain_off); -void write_bit_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT bit); -void write_uint_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT val, LC3_INT numbits); +void processPerBandEnergy_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word32 *d_fx, Word16 d_fx_exp, + const Word16 *band_offsets, Word16 fs_idx, Word16 n_bands, Word16 linear, Word16 frame_dms, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); -void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT* x, LC3_INT* tns_order, LC3_INT tns_numfilters, - LC3_INT* tns_idx, LC3_INT lastnz, - LC3_INT* codingdata, uint8_t* res_bits, LC3_INT resBitsLen, LC3_INT lsbMode, - LC3_INT nbbits, LC3_INT enable_lpc_weighting); +void processNearNyquistdetector_fx(Word16 *near_nyquist_flag, const Word16 fs_idx, const Word16 near_nyquist_index, + const Word16 bands_number, const Word32 *ener_fx, const Word16 ener_fx_exp +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + , Word16 frame_dms , Word16 hrmode); +#else + ); +#endif +#else + ); +#endif +void processDetectCutoffWarped_fx(Word16 *bw_idx, Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 frame_dms); -void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* lastAttackPosition, LC3_FLOAT* accNrg, LC3_INT* attackFlag, - LC3_FLOAT* attdec_filter_mem, LC3_INT attackHandlingOn, LC3_INT attdec_nblocks, LC3_INT attdec_hangover_threshold); +void process_resamp12k8_fx(Word16 x[], Word16 x_len, Word16 mem_in[], Word16 mem_in_len, Word32 mem_50[], + Word16 mem_out[], Word16 mem_out_len, Word16 y[], Word16 *y_len, Word16 fs_idx, + Word16 frame_dms, Word8 *scratchBuffer + , Word16 bps + ); -void process_snsQuantizesScf_Enc(LC3_FLOAT* env, LC3_INT* index, LC3_FLOAT* envq, Dct2 dct2structSNS); +void process_olpa_fx(Word16 *mem_s6k4_exp, Word16 mem_s12k8[], Word16 mem_s6k4[], Word16 *pitch, Word16 *s12k8, + Word16 len, Word16 *normcorr, Word16 *mem_pitch, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + Word16 *pitch_flag, +#endif + Word16 s12k8_exp, Word16 frame_dms, Word8 *scratchBuffer); + +void process_ltpf_coder_fx(Word16 *bits, Word16 ol_pitch, Word16 ltpf_enable, Word16 *old_wsp_exp, Word16 *old_wsp, + Word16 old_wsplen, Word16 *param, Word16 *wsp, Word16 len, Word16 *mem_normcorr, + Word16 *mem_mem_normcorr, Word16 ol_normcorr, Word16 *mem_ltpf_on, Word16 *mem_ltpf_pitch, + Word16 wsp_exp, Word16 frame_dms, Word8 *scratchBuffer +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,Word16 hrmode +#endif +); -void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q); +void process_ltpf_decoder_fx(Word16 *x_e, Word16 L_frame, Word16 old_x_len, Word16 fs_idx, Word16 old_y_len, + Word16 *old_e, Word16 *x, Word16 *old_x, Word16 *y, Word16 *old_y, Word16 ltpf, + Word16 ltpf_active, Word16 pitch_index, Word16 *old_pitch_int, Word16 *old_pitch_fr, + Word16 *old_gain, Word16 *mem_ltpf_active, Word16 scale_fac_idx, Word16 bfi, + Word16 concealMethod, + Word16 damping, Word16 *old_scale_fac_idx, +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 *rel_pitch_change, Word16 hrmode, Word16 frame_dms, +#endif + Word8 *scratchBuffer); -void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct); +void attack_detector_fx(LC3PLUS_Enc *enc, EncSetup *setup, Word16 *input, Word16 input_scaling, void *scratch); -int alloc_encoder(LC3PLUS_Enc* encoder, int channels); -void set_enc_frame_params(LC3PLUS_Enc* encoder); -LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate); +void processSnsComputeScf_fx(Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 *scf, + Word16 scf_smoothing_enabled, Word16 attdec_damping_factor, Word8 *scratchBuffer, Word16 sns_damping + ); -LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]); +void processSnsQuantizeScfEncoder_fx(Word16 scf[], /* i: input scf M */ + Word32 *L_prm_idx, /* o: indeces . negative == unused */ +#ifdef ENABLE_HR_MODE + Word32 *scf_q, /* o: quantized scf M */ +#else + Word16 *scf_q, /* o: quantized scf M */ +#endif + Word8 * scratchBuffer); + +Word16 processSnsQuantizeScfDecoder_fx( /* o: BER flag */ + Word32 *L_prm_idx, /* i: indeces */ +#ifdef ENABLE_HR_MODE + Word32 scf_q[], +#else + Word16 scf_q[], +#endif + Word8 *scratchBuffer); /* o: M */ -/* Setup Functions */ -int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels); -void set_dec_frame_params(LC3PLUS_Dec* decoder); -LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes); +void processSnsInterpolateScf_fx( +#ifdef ENABLE_HR_MODE + Word32 *scf_q, Word32 mdct_scf[], +#else + Word16 *scf_q, Word16 mdct_scf[], +#endif + Word16 mdct_scf_exp[], Word16 inv_scf, + Word16 n_bands, Word8 *scratchBuffer); -LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode, int hrmode); +void downshift_w32_arr(Word32 *w32_arr, Word16 *w16_arr, Word16 shft_val, Word32 len); +void round_w32tow16_arr(Word32 *w32_arr, Word16 *w16_arr, Word32 len); -int Enc_LC3PLUS_fl(LC3PLUS_Enc* encoder, void** input, LC3_UINT8* output, int bps -, LC3_INT32 bfi_ext -); -LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, LC3_UINT8* input, int input_bytes, void** output, int bps, int bfi_ext); +void processPLCmain_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, Word16 prev_bfi, + Word16 frame_length, Word16 la_zeroes, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 x_fx[], Word16 ola_mem[], + Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, const Word16 *band_offsets, Word16 bands_number, Word16 *damping, + Word16 old_pitch_int, Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, + AplcSetup *plcAd, Word16 frame_dms, Word8 *scratchBuffer, Word16 *pc_nbLostFramesInRow +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , Word32 rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , Word16 *alpha_type_2_table +#endif + ); + +void processPLCupdate_fx(AplcSetup *plcAd, Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 frame_length, + Word16 fs_idx, Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, + Word16 scf_q[], Word16 *ns_cum_alpha +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + ); -void* balloc(void* base, size_t* base_size, size_t size); +void processPLCupdateSpec_fx(Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], Word16 *q_fx_exp, Word16 yLen); -void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi, - PlcAdvSetup *PlcAdvSetup, PlcSetup *PlcSetup, LC3_INT plcMeth, LC3_INT ltpf_pitch_int, LC3_INT ltpf_pitch_fr, - LC3_INT tilt, const LC3_INT *bands_offset, LC3_INT bands_number, const LC3_INT *bands_offsetPLC, - LC3_INT n_bandsPLC, LC3_INT16 hrmode, pcState *statePC); -void processPlcUpdate_fl(PlcAdvSetup *PlcAdvSetup, LC3_INT32 frame_length, LC3_FLOAT *syntM, LC3_FLOAT *scf_q, - LC3_INT32 *nbLostCmpt, LC3_FLOAT *cum_alpha, LC3_INT32 bfi, LC3_INT32 *prevBfi, LC3_INT32 *prevprevBfi); +void processPLCspec2shape_fx(Word16 prev_bfi, Word16 bfi, Word16 q_old_d_fx[], Word16 yLen, + Word16 *PhECU_oold_grp_shape_fx, Word16 *PhECU_old_grp_shape_fx); -void processPlcUpdateSpec_fl(LC3_FLOAT *q_d_prev, LC3_FLOAT *q_d_fl_c, LC3_INT yLen); +Word32 winEnCalc(const Word16 *, const Word16, const Word16 *, const Word16, const Word16, Word16 *); -void processNoiseSubstitution_fl(LC3_FLOAT* spec, LC3_FLOAT* spec_prev, LC3_INT32 yLen); +void processPLCUpdateAfterIMDCT_fx(Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 xLen, Word16 fs_idx, + Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, + Word16 scf_q[], Word16 *ns_cum_alpha, AplcSetup *plcAd); -void process_cutoff_bandwidth(LC3_FLOAT* d_fl, LC3_INT len, LC3_INT bw_bin); -void update_enc_bandwidth(LC3PLUS_Enc* encoder, LC3_INT bandwidth); +void processPLCclassify_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, + Word16 ltpf_mem_pitch_int, Word16 frame_length, Word16 frame_dms, Word16 fs_idx, Word16 yLen, + Word16 q_old_d_fx[], const Word16 *band_offsets, Word16 bands_number, AplcSetup *plcAd, Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + , Word16 hrmode +# endif + ); -/* al_fec.c */ -LC3_INT16 fec_get_n_pccw(LC3_INT16 slot_bytes, LC3_INT16 fec_mode, LC3_INT16 ccc_flag); -LC3_INT16 fec_get_data_size(LC3_INT16 fec_mode, LC3_INT16 ccc_flag, LC3_INT16 slot_bytes); -LC3_INT16 fec_get_n_pc(LC3_INT16 fec_mode, LC3_INT16 n_pccw, LC3_INT16 slot_bytes); -void processReorderBitstream_fl(LC3_UINT8* bytes, LC3_INT32 n_pccw, LC3_INT32 n_pc, LC3_INT32 b_left, LC3_INT32 len); -void fec_encoder(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_INT16 data_bytes, LC3_INT16 slot_bytes, LC3_INT16 n_pccw); -LC3_INT32 fec_decoder(LC3_UINT8 *iobuf, LC3_INT16 slot_bytes, LC3_INT32 *data_bytes, LC3PLUS_EpModeRequest *epmr, LC3_INT16 ccc_flag, LC3_INT16 *n_pccw, LC3_INT32 *bfi, - LC3_INT16 *be_bp_left, LC3_INT16 *be_bp_right, LC3_INT16 *n_pc, LC3_INT16 *m_fec); - -LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len); - -void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi); -void processPcMain_fl(LC3_INT32 *bfi, LC3PLUS_Dec* decoder, LC3_FLOAT *sqQdec, DecSetup* h_DecSetup, LC3_INT32 pitch_present, LC3_FLOAT stab_fac, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 fac_ns_idx, pcState *statePC, LC3_INT32 spec_inv_idx, LC3_INT32 yLen); -void processPcUpdate_fl(LC3_INT32 bfi, LC3_FLOAT *q_res, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 rframe, LC3_INT32 *BW_cutoff_idx_nf, LC3_INT32 *prev_BW_cutoff_idx_nf, LC3_INT32 fac_ns_idx, LC3_FLOAT *prev_fac_ns, LC3_FLOAT *fac, LC3_FLOAT *q_old_res, LC3_FLOAT *prev_gg, LC3_INT32 spec_inv_idx, LC3_INT32 yLen); -void processPcApply_fl(LC3_FLOAT *q_res, LC3_FLOAT *q_old_res, LC3_FLOAT *q_d_prev, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_FLOAT *prev_gg, LC3_FLOAT *fac, LC3_INT32 *pc_nbLostCmpt); - -void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *nbLostCmpt, LC3_INT32 bfi, - LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 pitch_int, - LC3_INT32 fs, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 tilt, PlcAdvSetup *plcAd - , LC3_INT32 hrmode -); -void processPlcComputeStabFacMain_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_FLOAT *old_old_scf_q, LC3_INT32 bfi, LC3_INT32 prev_bfi, LC3_INT32 prev_prev_bfi, LC3_FLOAT *stab_fac); - -void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, - LC3_INT32 *pc_seed, LC3_INT32 ns_nbLostCmpt_pc, - LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, - LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi, - LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2, - LC3_FLOAT *cum_fflcAtten +void processPLCapply_fx( +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 *concealMethod, +#else + Word16 concealMethod, +#endif + Word16 nbLostFramesInRow, Word16 bfi, Word16 prev_bfi, + Word16 frame_length, Word16 la_zeroes, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 x_fx[], Word16 ola_mem[], + Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, Word16 *damping, Word16 old_pitch_int, + Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, Word16 frame_dms, AplcSetup *plcAd, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , Word32 rel_pitch_change + +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , Word16 *alpha_type_2_table +#endif + ); + +void processPLCNoiseSubstitution_fx(Word32 spec[], Word16 spec_prev[], Word16 L_spec); +void processPLCDampingScrambling_main_fx(Word16 bfi, Word16 concealMethod, Word16 ns_nbLostFramesInRow, Word16 *cum_fflcAtten, + Word16 pc_nbLostFramesInRow, Word16 *ns_seed, Word16 *pc_seed, Word16 pitch_present_bfi1, + Word16 pitch_present_bfi2, Word32 spec[], Word16 *q_fx_exp, Word16 *q_old_d_fx, + Word16 *q_old_fx_exp, Word16 L_spec, Word16 stabFac, Word16 frame_dms, + Word16 *cum_fading_slow, Word16 *cum_fading_fast, Word16 spec_inv_idx #ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type + , UWord8 plc_fadeout_type #endif - ); + ); -void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb, - LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow, - LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx +void processPLCDampingScrambling_fx(Word32 spec[], Word16 L_spec, Word16 nbLostFramesInRow, Word16 stabFac, Word16 processDampScramb, + Word16 *cum_fflcAtten, Word16 pitch_present, Word16 frame_dms, Word16 *cum_fading_slow, + Word16 *cum_fading_fast, Word16 *seed, Word16 spec_inv_idx #ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type + , UWord8 plc_fadeout_type #endif ); -void plc_phEcu_F0_refine_first(LC3_INT32 *plocs, LC3_INT32 n_plocs, LC3_FLOAT *f0est, const LC3_INT32 Xabs_len, - LC3_FLOAT *f0binPtr, LC3_FLOAT *f0gainPtr, const LC3_INT32 nSubm); -void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3_INT32 frame_dms); - -LC3_FLOAT plc_phEcuSetF0Hz(LC3_INT32 fs, LC3_FLOAT *old_pitchPtr); - -void plc_phEcu_processPLCspec2shape(LC3_INT16 prev_bfi, LC3_INT16 bfi, LC3_FLOAT q_d[], LC3_INT32 yLen, LC3_FLOAT *stPhECU_oold_grp_shape, LC3_FLOAT *stPhECU_old_grp_shape); -void plc_phEcu_LF_peak_analysis(LC3_INT32 *plocs, LC3_INT32 *n_plocs, LC3_FLOAT *f0est, const LC3_FLOAT *Xabs, - LC3_FLOAT *f0binPtr, LC3_FLOAT *f0gainPtr, const LC3_INT32 nSubm); - -void plc_phEcu_F0_refine_first(LC3_INT32 *plocs, LC3_INT32 n_plocs, LC3_FLOAT *f0est, const LC3_INT32 Xabs_len, - LC3_FLOAT *f0binPtr, LC3_FLOAT *f0gainPtr, const LC3_INT32 nSubm); - -LC3_FLOAT plc_phEcu_imax2_jacobsen_mag(const Complex *y, LC3_FLOAT *c_jacobPtr); -LC3_FLOAT plc_phEcu_interp_max(const LC3_FLOAT *y, LC3_INT32 y_len); -void plc_phEcu_fft_spec2_sqrt_approx(const Complex* x, LC3_INT32 x_len, LC3_FLOAT* x_abs); -LC3_INT32 plc_phEcu_pitch_in_plocs(LC3_INT32* plocs, LC3_INT32 n_plocs); -void plc_phEcu_spec_ana(LC3_FLOAT* xfp, LC3_INT32 xfp_len, const LC3_FLOAT* whr, - LC3_FLOAT* pfind_sensPtr, LC3_INT32* plocs, - LC3_INT32* n_plocs, LC3_FLOAT* f0est, Complex* x, LC3_INT32* x_len, - LC3_FLOAT* f0hzLtpBinPtr, LC3_FLOAT* f0gainLtpPtr, LC3_INT32 bw_idx, Fft* PhEcu_Fft); -void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_INT32 time_offs, Complex* X, LC3_INT32 X_len, - LC3_FLOAT* mag_chg_gr, LC3_INT32 *seed, LC3_FLOAT* alpha, LC3_FLOAT* beta, LC3_FLOAT* Xavg, - LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, +void processLagwin_fx(Word32 r[], const Word32 w[], Word16 m); + +void processInverseODFT_fx(Word32 *r_fx, Word16 *r_fx_exp, Word32 *d2_fx, Word16 d2_fx_exp, Word16 n_bands, + Word16 lpc_order, Word8 *scratchBuffer); + +void processPreEmphasis_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 frame_dms, + Word8 *scratchBuffer); + +void processPLCLpcScaling_fx(Word32 tdc_A_32[], Word16 tdc_A_16[], Word16 m); + +void processPLCcomputeStabFac_main(Word16 scf_q[], Word16 old_scf_q[], Word16 old_old_scf_q[], Word16 bfi, + Word16 prev_bfi, Word16 prev_prev_bfi, Word16 *stab_fac); + +void processPLCUpdateXFP_w_E_hist_fx(Word16 prev_bfi, Word16 bfi, + Word16 *xfp_fx, Word16 xfp_exp_fx,Word16 margin_xfp, + Word16 fs_idx, + Word32 *L_oold_xfp_w_E_fx, Word16 *oold_xfp_w_E_exp_fx, + Word32 *L_old_xfp_w_E_fx, Word16 *old_xfp_w_E_exp_fx, + Word16 *oold_Ltot_exp_fx, Word16 *old_Ltot_exp_fx); + +void processTimeDomainConcealment_Apply_fx(const Word16 pitch_int, const Word16 preemphFac_fx, const Word16 *A_fx, + const Word16 lpc_order, const Word16 *pcmbufHist_fx, + const Word16 frame_length, const Word16 frame_dms, const Word16 fs_idx, + const Word16 nbLostFramesInRow, const Word16 overlap, + const Word16 stabFac_fx, Word16 *fract, Word16 *seed_fx, + Word32 *gain_c_fx, Word16 *synth_fx, Word16 *Q_syn, + Word16 *alpha, Word16 max_len_pcm_plc, + Word16 harmonicBuf_fx[MAX_PITCH], Word16 synthHist_fx[M], Word16 *const harmonicBuf_Q, + Word8 *scratchBuffer +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + ,UWord8 plc_fadeout_type +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + ,Word16 *alpha_type_2_table +#endif +); + +void processTdac_fx(Word16 *ola_mem, Word16 *ola_mem_exp, const Word16 *synth, const Word16 synth_exp, +#ifdef ENABLE_HR_MODE + const Word32 *win, +#else + const Word16 *win, +#endif + const Word16 la_zeroes, const Word16 frame_len, Word8 *scratchBuffer); + +void plc_phEcu_F0_refine_first_fx(Word16 *plocs, const Word16 n_plocs_in, Word32 *L_f0est, + const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15, + const Word16 nSubm); +void plc_phEcu_LF_peak_analysis_fx(Word16 *plocs, Word16 *n_plocs, Word32 *L_f0estQ16, const Word16 *mag, + const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15, + const Word16 nSubm, Word16 maxPlocs, Word8 *scratchBuffer); + +Word16 plc_phEcuSetF0Hz_fx(Word16 fs_idx, Word16 old_pitch_int, Word16 old_pitch_fr); + +void create_sin2_taper_fx(Word16 *, Word16, Word16); + +void plc_phEcu_initWord16(Word16 * vec, /*i/o : vector pointer */ + const Word16 value, /*i : short initialization value */ + const Word16 len); /*i : number of elements */ + +Word16 plc_phEcu_ratio_fx(const Word32, const Word32, Word16 *); + +void plc_phEcu_minval_fx(const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + Word16 * minvalPtr); /* o : min value Ptr */ + +void plc_phEcu_maxval_fx(const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + Word16 * maxvalPtr); /* o : *maxvalPtr */ + +void Scale_sig_sat(Word16 x[], /* i/o: signal to scale, possibly saturated Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0); /* i : exponent: x = round(x << exp) Qx ?exp */ + +void Processing_ITDA_WIN_OLA(Word32 L_x_tda[], Word16 *y_e, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 mem[], Word16 *mem_e, Word16 x[], + Word16 wLen, Word16 N, Word16 memLen); + +void trans_burst_ana_fx(const Word16 *xfp, /* i : Input signal Qspec */ + Word16 * mag_chg, /* o : Magnitude modification Q15 */ + Word16 *ph_dith, /* o : Phase dither, 2*PI is not included (Q15, i.e., between 0.0 and 1.0) */ + Word16 *mag_chg_1st, /* i/o: per band magnitude modifier for transients Q15 */ + const Word16 output_frame, /* i : Frame length */ + const Word16 time_offs, /* i : Time offset (integral multiple of output_frame) */ + const Word16 est_stab_content, /* i : 0.0=dynamic ... 1.0=stable (==st->env_stab ) */ + Word16 * alpha, /* o : Magnitude modification factors for fade to average */ + Word16 * beta, /* : Magnitude modification factors for fade to average */ + Word16 * beta_mute, /* i/o : Factor for long-term mute */ + Word16 * Xavg, /* o : Frequency group average gain to fade to */ + Word16 Q_spec, Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, Word16 oold_Ltot_exp_fx, + Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx, + Word16 old_Ltot_exp_fx, Word16 *old_grp_shape_fx, #ifdef CR8_A_PLC_FADEOUT_TUNING - LC3_INT16 fadeout, /* needed for DC muting */ - LC3_INT16* nonpure_tone_flag_ptr, /* i/o: flag */ -#endif - LC3_FLOAT *corr_phase_dbg, - LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg); -void plc_phEcu_rec_frame(Complex *X_in, LC3_INT32 xfp_len, LC3_INT32 Lecu, const LC3_FLOAT *whr, const LC3_FLOAT *winMDCT, LC3_INT32 Lprot, - LC3_FLOAT *xfp, LC3_INT32 time_offs, LC3_FLOAT *x_out, - Complex *full_spec_dbg, LC3_FLOAT* ifft_out_dbg, LC3_FLOAT* xsubst_dbg, - LC3_INT32 LA_ZEROS, LC3_INT32 LA, Fft* PhEcu_Ifft - - ); -void plc_phEcu_tba_spect_Xavg(LC3_INT32 fs_idx, LC3_INT32 n_grp, LC3_FLOAT *oold_spec_shape, - LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spec_shape, LC3_FLOAT *old_EwPtr, - LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *Xavg); -void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change); -void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *grp_pow_change, - LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, - LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec, - LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames, - LC3_FLOAT *thresh_dbg + Word16 fadeout, + Word32 *L_Xavg, /* full scale average band amplitudes */ +#endif + Word8 *scratchBuffer); + +void spec_ana_fx(Word16 *xfp, Word16 *, Word32 *, Word16 *, Word16 *, const Word16, const Word16, + const Word16 *, const Word16, const Word16, Word16 maxLprot, Word16 maxPlocs, Word8 *scratchBuffer); + +void subst_spec_fx(const Word16 *, const Word32 *, Word16 *, const Word16, Word16 *, const Word16 *, const Word16, + const Word16 *, const Word16, Word16 *, const Word16 *, const Word16 *, const Word16 *, const Word16 #ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type + ,const Word16, + Word16*, + const Word32 * #endif - ); -void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, - LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, - LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, - LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, - LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg +); + +void rec_frame_fx(Word16 * X, /* i : FFT spectrum */ + Word32 * L_ecu_rec, /* o : Reconstructed frame in tda domain */ + const Word16 output_frame, /* i : Frame length */ + const Word16 Q, const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + + Word16 maxLprot, const Word16 *prevsynth, const Word16 Q_prevsynth, + Word8 * scratchBuffer); + +Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F); + +void hq_phase_ecu_fx(const Word16 *prevsynth, /* i : buffer of previously synthesized signal */ + Word32 *L_ecu_rec, /* o : reconstructed frame in tda domain , also tmp w32_fft buffer */ + Word16 *time_offs, /* i/o: Sample offset for consecutive frame losses*/ + Word16 *X_sav, /* i/o: Stored spectrum of prototype frame */ + Word16 *Q_spec, /* o: Q value of stored spectrum */ + Word16 *num_p, /* i/o: Number of identified peaks */ + Word16 *plocs, /* i/o: Peak locations */ + Word32 *L_plocsi, /* i/o: Interpolated peak locations Q16 */ + const Word16 env_stab, /* i : Envelope stability parameter */ + const Word16 f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */ + const Word16 norm_corrQ15_fx, /*i : correlation for lag at f0hzLtpBinQ7 */ + const Word16 prev_bfi, /* i : indicating burst frame error */ + Word16 old_is_transient[2], /* i/o : flags indicating noise generation */ + Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients */ + Word16 * mag_chg_gr, /* o: per band magnitude modifier incl burst attenuation */ + Word16 * Xavg, /* i/o: Frequency group average gain to fade to */ + Word16 * beta_mute, /* o : Factor for long-term mute */ + const Word16 bwidth_fx, /* i : Encoded bandwidth */ + const Word16 output_frame, /* i : frame length */ + Word16 * seed_out_fxPtr, /* o: seed synch analysis */ + Word16 * X_out, /* o: utput evolved spectrum */ + const Word16 t_adv, /* i : time adjustment including time_offs */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + const Word16 * sp_ana_win, /* i : whr hamming window */ + Word16 q_fx_old_exp, Word16 maxLprot, Word16 maxPlocs, + Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, /* exp of time signal */ + Word16 oold_Ltot_exp_fx, /*true exp of energy */ + Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx, + Word16 old_xfp_w_E_exp_fx, /* exp of time signal */ + Word16 old_Ltot_exp_fx, /*true exp of energy */ + Word16 *old_grp_shape_fx, + Word16 margin_prev_synth, /* i: margin in prev_synth(16ms for first bfi , 3.75 ms for other bfi + frames ) , from plcAd.PhECU_margin_xfp */ #ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type + const Word16 fadeout, /*i: fadeout length indicator */ + Word16 *nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */ #endif - ); -void plc_phEcu_hq_ecu( - LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, - LC3_FLOAT *xfp, LC3_INT16 prev_bfi, LC3_INT32 *short_flag_prev, - LC3_INT32 fs, LC3_INT32 * time_offs, - Complex *X_sav_m, LC3_INT32 *n_plocs, LC3_INT32 *plocs, LC3_FLOAT *f0est, const LC3_FLOAT *mdctWin, - LC3_FLOAT *env_stabPtr, LC3_INT32 delta_corr, - LC3_FLOAT *pfind_sensPtr, - LC3_INT32 PhECU_LA, LC3_INT32 t_adv, const LC3_FLOAT *winWhr, LC3_FLOAT *oold_grp_shape, - LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_grp_shape, - LC3_FLOAT *old_EwPtr, - LC3_FLOAT *st_beta_mute, LC3_FLOAT *st_mag_chg_1st, LC3_FLOAT *st_Xavg, LC3_INT32 LA_ZEROS, LC3_FLOAT *x_tda, LC3_FLOAT *xsubst_dbg, Complex *X_out_m_dbg, - LC3_INT32 *seed_dbg, LC3_FLOAT *mag_chg_dbg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg, LC3_FLOAT *corr_phase_dbg - ,Fft* PhEcu_Fft,Fft* PhEcu_Ifft -#ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type, - LC3_INT16 *nonpure_tone_flag_ptr + Word8 *scratchBuffer /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */ +); + +Word16 +plc_xcorr_lc_fx(/* o: quantized output xcorr in Q15 [ 0 ..32767 ] = [0. 1.0[ */ + Word16 * + pcmbuf_fx, /* NB should be an already dynamically upscaled buffer with about 0...1 bits margin */ + Word16 max_len_pcm_plc, /* Q0 size of pcmbuf_fx */ + Word16 pitch_int, /* Q0 in Fs, lag value to evaluate, corresponding to the current f0 fr pcm_buf */ + Word16 fs_idx); + +void plc_phEcu_peak_locator_fx(const Word16 *, const Word16, Word16 *, Word16 *, const Word16, const Word16, + const Word16, Word16, Word8 *); + +Word16 plc_phEcu_find_ind_fx(const Word16 *, const Word16, const Word16); + + +Word16 initQV(Word16 SR_idx, Word32 BR); + +void processEstimateGlobalGain_fx(Word32 x[], Word16 x_e, Word16 lg, Word16 sqTargetBits, +#ifdef ENABLE_HR_MODE + Word32 *gain, +#else + Word16 *gain, +#endif + Word16 *gain_e, + Word16 *quantizedGain, Word16 *quantizedGainMin, Word16 quantizedGainOff, + Word32 *targetBitsOff, Word16 *old_targetBits, Word16 old_specBits, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode, Word16 regBits, Word16 frame_dms #endif ); -void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands); +void processAdjustGlobalGain_fx(Word16 *gg_idx, Word16 gg_idx_min, Word16 gg_idx_off, +#ifdef ENABLE_HR_MODE + Word32 *gain, +#else + Word16 *gain, +#endif + Word16 *gain_e, + Word16 target, Word16 nBits, Word16 *gainChange, Word16 fs_idx +#ifdef ENABLE_HR_MODE + , Word16 hrmode, Word16 frame_dms +#endif + ); -void processTdcTdac_fl(const LC3_FLOAT *synth_inp, const LC3_FLOAT *win, LC3_INT32 frame_length, LC3_INT32 la_zeroes, LC3_FLOAT *ola_mem); -void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, LC3_INT32 lpc_order); +void processScalarQuant_fx(Word32 x[], Word16 x_e, Word16 xq[], Word16 L_frame, Word16 gain, Word16 gain_e); -void processTdcApply_fl(const LC3_INT32 pitch_LC3_INT, const LC3_FLOAT *preemphFac, const LC3_FLOAT* A, const LC3_INT32 lpc_order, const LC3_FLOAT* pcmbufHist, const LC3_INT32 max_len_pcm_plc, const LC3_INT32 N, const LC3_INT32 frame_dms, - const LC3_INT32 SampRate, const LC3_INT32 nbLostCmpt, const LC3_INT32 overlap, const LC3_FLOAT *stabFac, LC3_FLOAT harmonicBuf[MAX_PITCH], LC3_FLOAT synthHist[M], - LC3_INT32* fract, LC3_INT16* seed, LC3_FLOAT* gain_c, LC3_FLOAT* alpha, LC3_FLOAT* synth -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - ,LC3_UINT8 plc_fadeout_type +#ifdef ENABLE_HR_MODE +void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word32 gain, Word16 gain_e, Word32 xq[], Word16 nt, Word16 target, + Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnz, + Word16 *codingdata, Word16 *lsbMode, Word16 mode, Word16 hrmode); +#else +void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word16 gain, Word16 gain_e, Word16 xq[], Word16 nt, + Word16 target, + Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnz, + Word16 *codingdata, Word16 *lsbMode, Word16 mode); + +#endif /* ENABLE_HR_MODE */ + +void processResidualCoding_fx(Word16 x_e, Word32 x[], +#ifdef ENABLE_HR_MODE + Word32 xq[], Word32 gain, +#else + Word16 xq[], Word16 gain, +#endif + Word16 gain_e, Word16 L_spec, Word16 targetBits, Word16 nBits, + UWord8 *resBits, Word16 *numResBits +#ifdef ENABLE_HR_MODE + , Word16 hrmode #endif ); -void* balloc(void* base, size_t* base_size, size_t size); +void scale_signal24_fx(Word32 x[], /* i: time input signal */ +#ifdef ENABLE_HR_MODE + Word32 x_scaled[], +#else + Word16 x_scaled[], +#endif + Word16 *x_exp, +#ifdef ENABLE_HR_MODE + Word32 mdct_mem[], +#else + Word16 mdct_mem[], +#endif + Word16 mdct_mem_len, + Word16 resample_mem_in[], Word16 resample_mem_in_len, Word32 resample_mem_in50[], + Word16 resample_mem_out[], Word16 resample_mem_out_len, Word32 mdct_mem32[], Word16 N, + Word32 resamp_mem32[], Word16 mem_s12k8[], Word16 *resamp_scale); + +void processReorderBitstream_fx(UWord8 *bytes, Word16 n_pccw, Word16 n_pc, Word16 b_left, Word8 *scratchBuffer); + +/* al_fec.c */ +Word16 fec_get_n_pccw(Word16 slot_bytes, Word16 fec_mode, Word16 ccc_flag); +Word16 fec_get_data_size(Word16 fec_mode, Word16 ccc_flag, Word16 slot_bytes); +Word16 fec_get_n_pc(Word16 fec_mode, Word16 n_pccw, Word16 slot_bytes); + +void fec_encoder(Word16 mode, Word16 epmr, UWord8 *iobuf, Word16 data_bytes, Word16 slot_bytes, Word16 n_pccw, + void *scratch); + +int fec_decoder(UWord8 *iobuf, Word16 slot_bytes, int *data_bytes, Word16 *epmr, Word16 ccc_flag, Word16 *n_pccw, + int *bfi, Word16 *be_bp_left, Word16 *be_bp_right, Word16 *n_pc, Word16 *m_fec, void *scratch); + +void processPCmain_fx(Word16 rframe, Word16 *bfi, Word16 yLen, Word16 frame_dms, Word16 q_old_res_fx[], + Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 q_old_d_fx[], Word16 spec_inv_idx, + Word16 pitch_present, Word16 stab_fac, Word32 q_d_fx[], Word16 *q_fx_exp, + Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e, Word16 *BW_cutoff_idx_nf, + Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 *pc_nbLostFramesInRow); +void processPCclassify_fx(Word16 pitch_present, Word16 frame_dms, Word16 q_old_d_fx[], Word16 q_old_res_fx[], + Word16 yLen, Word16 spec_inv_idx, Word16 stab_fac, Word16 *bfi); +void processPCapply_fx(Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 q_old_d_fx[], Word16 spec_inv_idx, Word16 *fac, Word16 *fac_e, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 gg_idx, Word16 gg_idx_off, Word16 prev_gg, Word16 prev_gg_e, + Word16 *pc_nbLostFramesInRow); +void processPCupdate_fx(Word16 bfi, Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 spec_inv_idx, Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e, + Word16 rframe, Word16 *BW_cutoff_idx_nf, Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, + Word16 *prev_fac_ns_fx, Word16 fac, Word16 fac_e); +void processPcApplyDamping_fx(Word32 x[], Word16 xLen, Word16 fac, Word16 spec_inv_idx); + +void process_cutoff_bandwidth(Word32 d_fx[], Word16 len, Word16 bw_bin); + +void idct16_fx(const Word16 *in, Word16 *out); + +void dct32_fx(const Word32 *in, Word32 *out); +void idct32_fx(const Word32 *in, Word32 *out); +void idct32_32_fx(const Word32 *in, Word32 *out); + +/* Functions used in arithmetic coder */ + +void write_bit_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 bit); +void write_indice_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 indice, Word16 numbits); + +void processEncoderEntropy(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 targetBytes, + Word16 L_spec, Word16 BW_cutoff_bits, Word16 tns_numfilters, Word16 lsbMode, Word16 lastnz, + Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, Word16 BW_cutoff_idx, Word16 *ltpf_idx, + Word32 *L_scf_idx, Word16 bfi_ext, Word16 fs_idx); + +void processDecoderEntropy_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec, + Word16 fs_idx, Word16 BW_cutoff_bits, Word16 *tns_numfilters, Word16 *lsbMode, + Word16 *lastnz, Word16 *bfi, Word16 *tns_order, Word16 *fac_ns_idx, Word16 *gg_idx, + Word16 *BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, Word16 frame_dms); + +#ifdef ENABLE_PADDING +int paddingDec_fx(UWord8 *bytes, Word16 nbbits, Word16 L_spec, Word16 BW_cutoff_bits, Word16 ep_enabled, + Word16 *total_padding, Word16 *np_zero); +#endif + +Word16 read_bit(UWord8 *ptr, Word16 *bp, Word16 *mask); + +/* setup_enc_lc3.c */ +int alloc_encoder(LC3PLUS_Enc *encoder, int samplerate, int channels); +void set_enc_frame_params(LC3PLUS_Enc *encoder); +LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc *encoder, int bitrate); +LC3PLUS_Error FillEncSetup(LC3PLUS_Enc *encoder, int samplerate, int channels +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + , int32_t lfe_channel_array[] + ); +/* setup_dec_lc3.c */ +int alloc_decoder(LC3PLUS_Dec *decoder, int samplerate, int channels); +void set_dec_frame_params(LC3PLUS_Dec *decoder); +LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec *decoder, int ch, Word16 nBytes); +LC3PLUS_Error FillDecSetup(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + ); + +int Enc_LC3PLUS(LC3PLUS_Enc *encoder, void **input, int bits_per_sample, UWord8 *output, void *scratch, Word16 bfi_ext); +LC3PLUS_Error Dec_LC3PLUS(LC3PLUS_Dec *decoder, UWord8 *input, int input_bytes, void **output, int bits_per_sample, void *scratch, + int bfi_ext); + +void *balloc(void *base, size_t *base_size, size_t size); + +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +Word16 type_2_fadeout_fx(Word16 nbLostFramesInRow, Word16 frame_dms); +#endif #endif diff --git a/lib_lc3plus/imdct.c b/lib_lc3plus/imdct.c deleted file mode 100644 index b2ef8ee92..000000000 --- a/lib_lc3plus/imdct.c +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -/* Function expects already flipped window */ -void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_INT winLen, LC3_INT last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x, Dct4* dct) -{ - LC3_FLOAT x_tda[MAX_LEN], x_ov[2 * MAX_LEN]; - LC3_INT i, j; - - /* Flip imdct window up to down */ - i = winLen - 1; - j = 0; - - dct4_apply(dct, y, x_tda); - - move_float(x_ov, &x_tda[yLen / 2], yLen / 2); - - j = yLen / 2; - for (i = 0; i < yLen / 2; i++) { - x_ov[j] = -x_tda[yLen - 1 - i]; - j++; - } - - j = yLen; - for (i = 0; i < yLen / 2; i++) { - x_ov[j] = -x_tda[yLen / 2 - 1 - i]; - j++; - } - - j = yLen + yLen / 2; - for (i = 0; i < yLen / 2; i++) { - x_ov[j] = -x_tda[i]; - j++; - } - - for (i = 0; i < winLen; i++) { - x_ov[i] = x_ov[i] * win[winLen - 1 - i]; - } - - /* Buffer update */ - j = 0; - for (i = last_zeros; i < yLen; i++) { - x_ov[i] = x_ov[i] + mem[j]; - j++; - } - - move_float(&x[0], &x_ov[last_zeros], yLen); - - move_float(&mem[0], &x_ov[yLen + last_zeros], (winLen - (yLen + last_zeros))); -} - -void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT* win, LC3_INT32 winLen, LC3_INT32 last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x) -{ - LC3_FLOAT x_ov[2 * MAX_LEN]; - LC3_INT32 i, j; - - move_float(x_ov, &x_tda[yLen / 2], yLen / 2); - - j = yLen / 2; - for (i = 0; i < yLen / 2; i++) { - x_ov[j] = -x_tda[yLen - 1 - i]; - j++; - } - - j = yLen; - for (i = 0; i < yLen / 2; i++) { - x_ov[j] = -x_tda[yLen / 2 - 1 - i]; - j++; - } - - j = yLen + yLen / 2; - for (i = 0; i < yLen / 2; i++) { - x_ov[j] = -x_tda[i]; - j++; - } - - for (i = 0; i < winLen; i++) { - x_ov[i] = x_ov[i] * win[winLen - 1 - i]; - } - - /* Buffer update */ - j = 0; - - for (i = last_zeros; i < yLen; i++) { - x[j] = x_ov[i] + mem[j]; - j++; - } - - move_float(&x[j], &x_ov[last_zeros+j], yLen-j); - - move_float(&mem[0], &x_ov[yLen + last_zeros], (winLen - (yLen + last_zeros))); -} diff --git a/lib_lc3plus/imdct_fx.c b/lib_lc3plus/imdct_fx.c new file mode 100644 index 000000000..50ad2b257 --- /dev/null +++ b/lib_lc3plus/imdct_fx.c @@ -0,0 +1,387 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void ProcessingIMDCT( + Word32 y[], /* i: spectra data */ + Word16 * y_e, /* i: spectral data exponent */ +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + Word32 mem[], /* i/o: overlap add memory */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + Word16 mem[], /* i/o: overlap add memory */ +#endif + Word16 * mem_e, /* i/o: overlap add exponent */ +#ifdef ENABLE_HR_MODE + Word32 x[], /* o: time signal out */ +#else + Word16 x[], /* o: time signal out */ +#endif + Word16 wLen, /* i: window length */ + Word16 N, /* i: block size */ + Word16 memLen, /* i: overlap add buffer size */ + Word16 frame_dms, /* i: frame size in ms */ + Word16 concealMethod, /* i: concealment method */ + Word16 bfi, /* i: bad frame indicator */ + Word16 prev_bfi, /* i: previous bad frame indicator */ + Word16 nbLostFramesInRow, /* i: number of consecutive lost frames */ + AplcSetup *plcAd, /* i: advanced plc struct */ + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + Counter i; + Word16 o, z, m, s; + Word16 y_s, mem_s, max_bw; + Word32 L_tmp; + Word32 *workBuffer; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Word16 o, z, m, s; + Word16 y_s, mem_s, max_bw; + Word32 L_tmp; + Counter i; + Word32 *workBuffer; + Word16 mem_i_win; + Word16 w_taper_win; + }; + Dyn_Mem_In("ProcessingIMDCT", sizeof(struct _dynmem)); +#endif + + + test(); test(); test(); + IF (sub(bfi, 1) != 0 || sub(concealMethod, LC3_CON_TEC_NS_STD) == 0 || sub(concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(concealMethod, LC3_CON_TEC_FREQ_MUTING) == 0) + { + workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */ + + /* Init (constant per sample rate) */ + z = 2 * N - wLen; /* number of leading zeros in window */ + m = N >> 1; /* half block size */ + o = m - z; + max_bw = 0; + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + max_bw = N; + } + else +#endif + { + SWITCH (frame_dms) + { + case 25: + max_bw = MAX_BW >> 2; move16(); + BREAK; + case 50: + max_bw = MAX_BW >> 1; move16(); + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + max_bw = (MAX_BW >> 2) * 3; move16(); + BREAK; +#endif + case 100: + max_bw = MAX_BW; move16(); + BREAK; + } + } + + if (N > max_bw) + basop_memset(&y[max_bw], 0, (N - max_bw) * sizeof(*y)); + + /* Start Processing */ + y_s = getScaleFactor32_0(y, N); + IF (sub(y_s, 32) < 0) + { + FOR (i = 0; i < N; i++) + { + y[i] = L_shl(y[i], y_s); + } + *y_e = sub(*y_e, y_s); +#ifdef ENABLE_HR_MODE + dct_IV(y, y_e, N, +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + hrmode, +# endif + workBuffer); +#else + dct_IV(y, y_e, N, workBuffer); +#endif + y_s = getScaleFactor32_lc3plus(y, N); + y_s = sub(y_s, 1); + *y_e = sub(*y_e, y_s + 3); /* mdct window is scaled by pow(2,x) */ + /* N<=20 only happens for 2.5ms frames in NB */ + if (sub(N, 20) <= 0) + { + *y_e = add(*y_e, 2); + } + else if (sub(N, 120) <= 0) + { + *y_e = add(*y_e, 1); + } + } + ELSE + { + *y_e = 0; move16(); + } + +#ifdef ENABLE_HR_MODE + mem_s = getScaleFactor32_0(mem, memLen); +#else + mem_s = getScaleFactor16_0(mem, memLen); +#endif + +#ifdef ENABLE_HR_MODE + IF (sub(mem_s, 32) < 0) +#else + IF (sub(mem_s, 16) < 0) +#endif + { + mem_s = sub(mem_s, 1); + *mem_e = sub(*mem_e, mem_s); + } + ELSE + { + *mem_e = *y_e; move16(); + } + + s = sub(*mem_e, *y_e); + + IF (s > 0) + { + y_s = sub(y_s, s); + *y_e = add(*y_e, s); + } + ELSE + { + mem_s = add(mem_s, s); + *mem_e = sub(*mem_e, s); + } + + mem_s = s_max(mem_s, -31); + y_s = s_max(y_s, -31); + + if (sub(y_s, 32) >= 0) + { + y_s = 0; move16(); + } +#ifdef ENABLE_HR_MODE + if (sub(mem_s, 32) >= 0) + { + mem_s = 0; move16(); + } +#else + if (sub(mem_s, 16) >= 0) + { + mem_s = 0; move16(); + } +#endif + + UNUSED(prev_bfi); + UNUSED(nbLostFramesInRow); + UNUSED(plcAd); + + { /* regular operation */ + FOR (i = 0; i < o; i++) + { +#ifdef ENABLE_HR_MODE + L_tmp = L_sub(L_shl(mem[i], mem_s), Mpy_32_32_lc3plus(L_shl(y[m + i + z], y_s), w[4 * m - 1 - i - z])); + x[i] = L_tmp; + move32(); +#else + L_tmp = L_sub(L_shl(L_deposit_h(mem[i]), mem_s), Mpy_32_16_lc3plus(L_shl(y[m + i + z], y_s), w[4 * m - 1 - i - z])); + x[i] = round_fx(L_tmp); + move16(); +#endif + } + FOR (i = 0; i < m; i++) + { +#ifdef ENABLE_HR_MODE + L_tmp = L_add(L_shl(mem[i + o], mem_s), Mpy_32_32_lc3plus(L_shl(y[2 * m - 1 - i], y_s), w[3 * m - 1 - i])); + x[i + o] = L_tmp; + move32(); +#else + L_tmp = L_add(L_shl(L_deposit_h(mem[i + o]), mem_s), Mpy_32_16_lc3plus(L_shl(y[2 * m - 1 - i], y_s), w[3 * m - 1 - i])); + x[i + o] = round_fx(L_tmp); + move16(); +#endif + } + } + + FOR (i = 0; i < m; i++) + { +#ifdef ENABLE_HR_MODE + L_tmp = L_negate(Mpy_32_32_lc3plus(L_shl(y[i], y_s), w[m - 1 - i])); + x[3 * m - z + i] = L_tmp; + move32(); +#else + L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(y[i], y_s), w[m - 1 - i])); + x[3 * m - z + i] = round_fx(L_tmp); + move16(); +#endif + } + + FOR (i = 0; i < m; i++) + { +#ifdef ENABLE_HR_MODE + L_tmp = L_negate(Mpy_32_32_lc3plus(L_shl(y[i], y_s), w[m + i])); + x[3 * m - z - 1 - i] = L_tmp; + move32(); +#else + L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(y[i], y_s), w[m + i])); + x[3 * m - z - 1 - i] = round_fx(L_tmp); + move16(); +#endif + } + +#ifdef ENABLE_HR_MODE + basop_memmove(mem, &x[N], memLen * sizeof(Word32)); +#else + basop_memmove(mem, &x[N], memLen * sizeof(Word16)); +#endif + + *mem_e = *y_e; move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} +/* End Processing */ + +void Processing_ITDA_WIN_OLA( + Word32 L_x_tda[], /* i: X_TDA buffer data = "y" DCT-IV output */ + Word16 * y_e, /* i/o: x_tda input exponent "y_e" , x output exponent */ +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#endif + Word16 mem[], /* i/o: overlap add memory */ + Word16 * mem_e, /* i/o: overlap add exponent */ + Word16 x[], /* o: time signal out */ + Word16 wLen, /* i: window length */ + Word16 N, /* i: block size */ + Word16 memLen /* i: overlap add buffer size */ + ) +{ + /* Declarations */ + Word16 i, o, z, m, s; + Word16 y_s, mem_s; + Word32 L_tmp; + Word32 *L_y; + Word16 fs_idx, tmp_w, w_factor; + Word16 factorITDA[5]= { 25905 , 18318 , 22435 , 25905 , 31727}; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("Processing_ITDA_WIN_OLA", sizeof(struct { + Word16 i, o, z, m, s; + Word16 y_s, mem_s; + Word32 L_tmp; + Word32 *L_y; + })); +#endif + + + /* Init (constants per sample rate) */ + z = 2 * N - wLen; /* number of leading zeros in window */ + m = N >> 1; /* half block size */ + o = m - z; + + + L_y = L_x_tda; /* use same variables naming as in IMDCT for DCT-IV output signal y */ + + y_s = getScaleFactor32_lc3plus(L_y, N); + + y_s = sub(y_s, 1); /* add 1 bit margin , y_s is now initial tda upscaling factor */ + + + *y_e = sub(add(*y_e,1),y_s); /* handle W scale down by 2^(3) , as mdct synthesis window was upscaled by pow(2,x) x=2 for NB otherwise 3 */ + + + + mem_s = getScaleFactor16_0(mem, memLen); + + IF (sub(mem_s, 16) < 0) + { + mem_s = sub(mem_s, 1); /* one bit margin */ + *mem_e = sub(*mem_e, mem_s); /*adjusted mem exponent due to new scale */ + } + ELSE + { + *mem_e = 0; move16(); + } + + s = sub(*mem_e, *y_e); /* */ + + IF (s > 0) + { + y_s = sub(y_s, s); /* new , reduced upshift of TDA in window application loop */ + *y_e = add(*y_e, s); /* resulting new exp y_e for output signal */ + } + ELSE + { + mem_s = add(mem_s, s); /* s negative or zero, new , decreased upshift of OLAmem in loop */ + *mem_e = sub(*mem_e, s); /* resulting new exp mem_e for OLA_mem output signal */ + } + + fs_idx = mult(N,(Word16)(32768.0/99.0)); /* truncation needed , i.e no rounding can be applied here */ + w_factor = factorITDA[fs_idx]; move16(); + y_s = s_max(s_min(y_s, 31), -31); + + FOR (i = 0; i < o; i++) + { + tmp_w = mult_r(extractW16(w[4 * m - 1 - i - z]), w_factor); + L_tmp = L_sub(L_shl_sat(L_deposit_h(mem[i]), mem_s), Mpy_32_16_lc3plus(L_shl(L_y[m + i + z], y_s), tmp_w)); + x[i] = round_fx_sat(L_tmp); + move16(); + } + + FOR (i = 0; i < m; i++) + { + tmp_w = mult_r(extractW16(w[3 * m - 1 - i]), w_factor); + L_tmp = L_add(L_shl_sat(L_deposit_h(mem[i + o]), mem_s), Mpy_32_16_lc3plus(L_shl(L_y[2 * m - 1 - i], y_s), tmp_w)); + x[i + o] = round_fx_sat(L_tmp); + move16(); + } + + FOR (i = 0; i < m; i++) + { + tmp_w = mult_r(extractW16(w[m - 1 - i]), w_factor); + L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(L_y[i], y_s), tmp_w)); + x[3 * m - z + i] = round_fx(L_tmp); move16(); + } + + FOR (i = 0; i < m; i++) + { + tmp_w = mult_r(extractW16(w[m + i]), w_factor); + L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(L_y[i], y_s), tmp_w )); + x[3 * m - z - 1 - i] = round_fx(L_tmp); move16(); + } + + FOR (i = 0; i < memLen; i++) + { + mem[i] = x[N + i]; move16(); + } + *mem_e = *y_e; move16(); /* set OLA mem exp to x_Fx exponent*/ + + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/lc3.c b/lib_lc3plus/lc3.c index e3f4491d2..120dd0929 100644 --- a/lib_lc3plus/lc3.c +++ b/lib_lc3plus/lc3.c @@ -1,31 +1,51 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "lc3.h" + #include "defines.h" #include "functions.h" -#include - +#include "lc3.h" #include "setup_dec_lc3.h" #include "setup_enc_lc3.h" -#define RETURN_IF(cond, error) \ - if (cond) \ +#define RETURN_IF(cond, error) \ + if (cond) \ return (error) +#ifdef SUBSET_NB +#pragma message("- SUBSET_NB") +#endif +#ifdef SUBSET_WB +#pragma message("- SUBSET_WB") +#endif +#ifdef SUBSET_SSWB +#pragma message("- SUBSET_SSWB") +#endif +#ifdef SUBSET_SWB +#pragma message("- SUBSET_SWB") +#endif +#ifdef SUBSET_FB +#pragma message("- SUBSET_FB") +#endif +#ifdef SUBSET_UB +#pragma message("- SUBSET_UB") +#endif + /* ensure api header constants are up to date */ STATIC_ASSERT(LC3PLUS_MAX_SAMPLES >= MAX_LEN); STATIC_ASSERT(LC3PLUS_MAX_CHANNELS >= MAX_CHANNELS); STATIC_ASSERT(LC3PLUS_MAX_BYTES >= BYTESBUFSIZE); +STATIC_ASSERT(LC3PLUS_ENC_MAX_SIZE >= ENC_MAX_SIZE); +STATIC_ASSERT(LC3PLUS_DEC_MAX_SIZE >= DEC_MAX_SIZE); +STATIC_ASSERT(LC3PLUS_ENC_MAX_SCRATCH_SIZE >= SCRATCH_BUF_LEN_ENC_TOT); +STATIC_ASSERT(LC3PLUS_DEC_MAX_SCRATCH_SIZE >= SCRATCH_BUF_LEN_DEC_TOT); +STATIC_ASSERT(PLC_FADEOUT_IN_MS >= 20); + /* misc functions ************************************************************/ @@ -43,16 +63,27 @@ int lc3plus_samplerate_supported(int samplerate) { switch (samplerate) { +#ifdef SUBSET_NB case 8000: return 1; +#endif +#ifdef SUBSET_WB case 16000: return 1; +#endif +#ifdef SUBSET_SSWB case 24000: return 1; +#endif +#ifdef SUBSET_SWB case 32000: return 1; +#endif +#ifdef SUBSET_FB case 44100: return 1; case 48000: return 1; +#endif +#ifdef ENABLE_HR_MODE case 96000: return 1; - default: break; +#endif + default: return 0; } - return 0; } static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode) @@ -61,24 +92,23 @@ static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode) { case LC3PLUS_PLC_ADVANCED: /* fallthru */ return 1; - default: break; + default: return 0; } - return 0; } -static int lc3plus_frame_size_supported(float frame_ms) +static int lc3plus_frame_size_supported(int frame_dms) { - switch ((int)(ceil(frame_ms * 10))) + switch (frame_dms) { case 25: /* fallthru */ case 50: /* fallthru */ #ifdef CR8_G_ADD_75MS case 75: /* fallthru */ #endif - case 100: return 1; - default: break; + case 100: + return 1; + default: return 0; } - return 0; } static int null_in_list(void **list, int n) @@ -103,35 +133,59 @@ int32_t lc3_enc_supported_lfe(void) } /* encoder functions *********************************************************/ -LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]) + +LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + , int32_t lfe_channel_array[] + ) { int ch = 0; + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); RETURN_IF((uintptr_t)encoder % 4 != 0, LC3PLUS_ALIGN_ERROR); RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); +#ifdef ENABLE_HR_MODE RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); +#endif for (ch = 0; ch < channels; ch++) { RETURN_IF(!lc3_enc_supported_lfe() && lfe_channel_array[ch], LC3PLUS_LFE_MODE_NOT_SUPPORTED); } - return FillEncSetup(encoder, samplerate, channels, hrmode, lfe_channel_array); /* real bitrate check happens here */ +#ifdef ENABLE_HR_MODE + return FillEncSetup(encoder, samplerate, channels, hrmode + , lfe_channel_array + ); /* real bitrate check happens here */ +#else + return FillEncSetup(encoder, samplerate, channels + , lfe_channel_array + ); /* real bitrate check happens here */ +#endif } int lc3plus_enc_get_size(int samplerate, int channels) { RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0); RETURN_IF(!lc3plus_channels_supported(channels), 0); - return alloc_encoder(NULL, channels); + return alloc_encoder(NULL, samplerate, channels); } -/* Dummy function for API alignment */ int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder) { - UNUSED(encoder); - return 0; + int size = 0; + RETURN_IF(encoder == NULL, 0); + +#ifdef ENABLE_HR_MODE + size = 47 * MAX(encoder->frame_length, 160) + 64; +#else + size = 14 * MAX(encoder->frame_length, 160) + 64; +#endif + assert(size <= LC3PLUS_ENC_MAX_SCRATCH_SIZE); + return size; } int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder) @@ -143,14 +197,12 @@ int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder) int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder) { RETURN_IF(encoder == NULL, 0); - - return encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); + return (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); } int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder) { int ch = 0, totalBytes = 0; - int bitrate; RETURN_IF(encoder == NULL, 0); RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR); @@ -159,7 +211,7 @@ int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder) totalBytes += encoder->channel_setup[ch]->targetBytes; } - bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; + int bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; if (encoder->fs_in == 44100) { @@ -170,14 +222,10 @@ int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder) return bitrate; } - LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc *encoder, int bitrate) { RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); RETURN_IF(bitrate <= 0, LC3PLUS_BITRATE_ERROR); -#ifndef STRIP_HR_MODE_API - RETURN_IF(encoder->fs_idx == 5 && encoder->hrmode == 0, LC3PLUS_HRMODE_ERROR); -#endif return update_enc_bitrate(encoder, bitrate); } @@ -187,25 +235,37 @@ int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder) return encoder->frame_length - 2 * encoder->la_zeroes; } +LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((unsigned)epmode > LC3PLUS_EP_HIGH, LC3PLUS_EPMODE_ERROR); + encoder->epmode = epmode; + return encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((unsigned)epmr > LC3PLUS_EPMR_HIGH, LC3PLUS_EPMR_ERROR); + encoder->epmr = epmr; + return LC3PLUS_OK; +} + LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_dms) { RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); - RETURN_IF(!lc3plus_frame_size_supported(frame_dms / 10.0), LC3PLUS_FRAMEMS_ERROR); + RETURN_IF(!lc3plus_frame_size_supported(frame_dms), LC3PLUS_FRAMEMS_ERROR); RETURN_IF(encoder->lc3_br_set, LC3PLUS_BITRATE_SET_ERROR); encoder->frame_dms = frame_dms; - encoder->frame_ms = frame_dms / 10.0; set_enc_frame_params(encoder); return LC3PLUS_OK; } + LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth) { - LC3_INT effective_fs; RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); -#ifdef ENABLE_HR_MODE_FL_FLAG - RETURN_IF(encoder->hrmode == 1, LC3PLUS_HRMODE_BW_ERROR); -#endif - effective_fs = encoder->fs_in; + Word32 effective_fs = encoder->fs_in; if (encoder->bandwidth != bandwidth) { if (encoder->fs_in > 40000) { effective_fs = 40000; @@ -216,7 +276,7 @@ LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth) else { encoder->bandwidth = bandwidth; encoder->bandwidth_preset = bandwidth; - encoder->bw_ctrl_active = 1; + encoder->bw_ctrl_active = 1; update_enc_bitrate(encoder, encoder->bitrate); } } @@ -224,209 +284,143 @@ LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth) } -LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc* encoder, int16_t** input_samples, void* output_bytes, int* num_bytes -, void *scratch -) +static LC3PLUS_Error lc3plus_enc(LC3PLUS_Enc *encoder, void **input_samples, int bitdepth, void *output_bytes, int *num_bytes, + void *scratch) { - UNUSED(scratch); - return lc3plus_enc_fl(encoder, (void**)input_samples, 16, output_bytes, num_bytes); + RETURN_IF(!encoder || !input_samples || !output_bytes || !num_bytes || !scratch, LC3PLUS_NULL_ERROR); + RETURN_IF(null_in_list(input_samples, encoder->channels), LC3PLUS_NULL_ERROR); + RETURN_IF(bitdepth != 16 && bitdepth != 24, LC3PLUS_ERROR); + RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR); + *num_bytes = Enc_LC3PLUS(encoder, input_samples, bitdepth, output_bytes, scratch, *num_bytes == -1); + + assert(*num_bytes == lc3plus_enc_get_num_bytes(encoder)); + return LC3PLUS_OK; } -LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc* encoder, int32_t** input_samples, void* output_bytes, int* num_bytes -, void *scratch -) +LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc *encoder, int16_t **input_samples, void *output_bytes, int *num_bytes, void *scratch) { - UNUSED(scratch); - return lc3plus_enc_fl(encoder, (void**)input_samples, 24, output_bytes, num_bytes); + return lc3plus_enc(encoder, (void **)input_samples, 16, output_bytes, num_bytes, scratch); } - -LC3PLUS_Error lc3plus_enc_fl(LC3PLUS_Enc* encoder, void** input_samples, int bitdepth, void* output_bytes, int* num_bytes) +LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc *encoder, int32_t **input_samples, void *output_bytes, int *num_bytes, void *scratch) { - RETURN_IF(!encoder || !input_samples || !output_bytes || !num_bytes, LC3PLUS_NULL_ERROR); - RETURN_IF(null_in_list(input_samples, encoder->channels), LC3PLUS_NULL_ERROR); - RETURN_IF(bitdepth != 16 && bitdepth != 24, LC3PLUS_ERROR); - *num_bytes = Enc_LC3PLUS_fl(encoder, input_samples, output_bytes, bitdepth - , *num_bytes == -1 - ); - assert(*num_bytes == lc3plus_enc_get_num_bytes(encoder)); - return LC3PLUS_OK; + return lc3plus_enc(encoder, (void **)input_samples, 24, output_bytes, num_bytes, scratch); } /* decoder functions *********************************************************/ -LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode, int hrmode) +LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode +#ifdef ENABLE_HR_MODE + , int hrmode +#endif +) { RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); RETURN_IF(!lc3plus_plc_mode_supported(plc_mode), LC3PLUS_PLCMODE_ERROR); +#ifdef ENABLE_HR_MODE RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); - return FillDecSetup(decoder, samplerate, channels, plc_mode, hrmode); -} +#endif -int lc3plus_dec_get_size(int samplerate, int channels) + return FillDecSetup(decoder, samplerate, channels, plc_mode +#ifdef ENABLE_HR_MODE + , hrmode +#endif + ); +} + +int lc3plus_dec_get_size(int samplerate, int channels, LC3PLUS_PlcMode plc_mode) { RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0); RETURN_IF(!lc3plus_channels_supported(channels), 0); + RETURN_IF(!lc3plus_plc_mode_supported(plc_mode), 0); return alloc_decoder(NULL, samplerate, channels); } -/* Dummy function for API alignment */ int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder) { - UNUSED(decoder); - return 0; + int size = 0; + RETURN_IF(decoder == NULL, 0); + +#ifdef ENABLE_HR_MODE + size = 30 * DYN_MAX_LEN(decoder->fs) + 2866; + size += 4 * MAX_LGW + 8 * DYN_MAX_LPROT(decoder->fs) + 16 * DYN_MAX_LEN(decoder->fs); +#else + size = 12 * DYN_MAX_LEN(decoder->fs) + 752; + size += 2 * MAX_LGW + 8 * DYN_MAX_LPROT(decoder->fs) + 8 * DYN_MAX_LEN(decoder->fs); + size += 3720; +#endif + + assert(size <= LC3PLUS_DEC_MAX_SCRATCH_SIZE); + return size; } -LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_dms) +LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int ep_enabled) { RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); - RETURN_IF(!lc3plus_frame_size_supported(frame_dms / 10.0), LC3PLUS_FRAMEMS_ERROR); - RETURN_IF(decoder->plcMeth == 2 && frame_dms != 100, LC3PLUS_FRAMEMS_ERROR); - - decoder->frame_dms = frame_dms; - decoder->frame_ms = frame_dms / 10.0; - set_dec_frame_params(decoder); + decoder->ep_enabled = ep_enabled != 0; + decoder->epmr = LC3PLUS_EPMR_ZERO; return LC3PLUS_OK; } -int lc3plus_dec_get_output_samples(const LC3PLUS_Dec* decoder) +int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder) { RETURN_IF(decoder == NULL, 0); - return decoder->frame_length; + return decoder->error_report == 2047 ? -1 : decoder->error_report & 0x07FF; } -int lc3plus_dec_get_delay(const LC3PLUS_Dec* decoder) +int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder) { RETURN_IF(decoder == NULL, 0); - return decoder->frame_length - 2 * decoder->la_zeroes; -} - -LC3PLUS_Error lc3plus_dec_fl(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, void** output_samples, int bps, int bfi_ext) -{ - RETURN_IF(!decoder || !input_bytes || !output_samples, LC3PLUS_NULL_ERROR); - RETURN_IF(null_in_list((void**)output_samples, decoder->channels), LC3PLUS_NULL_ERROR); - return Dec_LC3PLUS_fl(decoder, input_bytes, num_bytes, output_samples, bps, bfi_ext); -} - -LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, int16_t** output_samples, - void* scratch, - int bfi_ext) -{ - UNUSED(scratch); - return lc3plus_dec_fl(decoder, input_bytes, num_bytes, (void**)output_samples, 16, bfi_ext); -} - -LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, int32_t** output_samples, - void* scratch, - int bfi_ext) -{ - UNUSED(scratch); - return lc3plus_dec_fl(decoder, input_bytes, num_bytes, (void**)output_samples, 24, bfi_ext); -} - -/* memory functions *********************************************************/ - -LC3PLUS_Error lc3plus_enc_free_memory(LC3PLUS_Enc* encoder) -{ - RETURN_IF(!encoder, LC3PLUS_NULL_ERROR); - - lc3plus_free_encoder_structs(encoder); - - return LC3PLUS_OK; -} - -LC3PLUS_Error lc3plus_dec_free_memory(LC3PLUS_Dec* decoder) -{ - RETURN_IF(!decoder, LC3PLUS_NULL_ERROR); - - lc3plus_free_decoder_structs(decoder); - - return LC3PLUS_OK; + return decoder->error_report >> 11; } -LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder) +LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder) { - int ch = 0; - RETURN_IF(!encoder, LC3PLUS_NULL_ERROR); - - for (ch = 0; ch < encoder->channels; ch++) { - mdct_free(&encoder->channel_setup[ch]->mdctStruct); - dct2_free(&encoder->channel_setup[ch]->dct2StructSNS); - } - - return LC3PLUS_OK; + RETURN_IF(decoder == NULL, LC3PLUS_EPMR_ZERO); + return (LC3PLUS_EpModeRequest)decoder->epmr; } -LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder) +LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_dms) { - int ch = 0; - RETURN_IF(!decoder, LC3PLUS_NULL_ERROR); - - for (ch = 0; ch < decoder->channels; ch++) { - dct4_free(&decoder->channel_setup[ch]->dct4structImdct); - real_fft_free(&decoder->channel_setup[ch]->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft); - real_fft_free(&decoder->channel_setup[ch]->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft); - } + RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(!lc3plus_frame_size_supported(frame_dms), LC3PLUS_FRAMEMS_ERROR); + RETURN_IF(decoder->plcMeth == 2 && frame_dms != 100, LC3PLUS_FRAMEMS_ERROR); + decoder->frame_dms = frame_dms; + set_dec_frame_params(decoder); return LC3PLUS_OK; } -LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder) -{ - RETURN_IF(decoder == NULL, LC3PLUS_EPMR_ZERO); - return (LC3PLUS_EpModeRequest)decoder->epmr; -} - -int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder) +int lc3plus_dec_get_output_samples(const LC3PLUS_Dec *decoder) { RETURN_IF(decoder == NULL, 0); - return decoder->error_report == 2047 ? -1 : decoder->error_report & 0x07FF; + return decoder->frame_length; } -LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode) +int lc3plus_dec_get_delay(const LC3PLUS_Dec *decoder) { - LC3PLUS_EpMode oldEpmode; - LC3PLUS_Error error; - RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); - RETURN_IF((unsigned)epmode > LC3PLUS_EP_HIGH, LC3PLUS_EPMODE_ERROR); - oldEpmode = encoder->epmode; - encoder->epmode = epmode; - error = encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK; - if (error != LC3PLUS_OK) - { - encoder->epmode = oldEpmode; // preserve old epmode in case of failure - } - return error; + RETURN_IF(decoder == NULL, 0); + return decoder->frame_length - 2 * decoder->la_zeroes; } -LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr) +static LC3PLUS_Error lc3plus_dec(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, void **output_samples, int bitdepth, + void *scratch, int bfi_ext) { - RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); - RETURN_IF((unsigned)epmr > LC3PLUS_EPMR_HIGH, LC3PLUS_EPMODE_ERROR); - encoder->epmr = epmr; - return LC3PLUS_OK; + RETURN_IF(!decoder || !input_bytes || !output_samples || !scratch, LC3PLUS_NULL_ERROR); + RETURN_IF(null_in_list(output_samples, decoder->channels), LC3PLUS_NULL_ERROR); + RETURN_IF(bitdepth != 16 && bitdepth != 24, LC3PLUS_ERROR); + return Dec_LC3PLUS(decoder, input_bytes, num_bytes, output_samples, bitdepth, scratch, bfi_ext); } -LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int32_t ep_enabled) +LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int16_t **output_samples, void *scratch, int bfi_ext) { - RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); - decoder->ep_enabled = ep_enabled != 0; - decoder->epmr = LC3PLUS_EPMR_ZERO; - return LC3PLUS_OK; + return lc3plus_dec(decoder, input_bytes, num_bytes, (void **)output_samples, 16, scratch, bfi_ext); } -int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder) +LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int32_t **output_samples, void *scratch, int bfi_ext) { - RETURN_IF(decoder == NULL, 0); - return decoder->error_report >> 11; + return lc3plus_dec(decoder, input_bytes, num_bytes, (void **)output_samples, 24, scratch, bfi_ext); } - -#ifndef STRIP_ERROR_PROTECTION_API_FL -#endif /* STRIP_ERROR_PROTECTION_API_FL */ - -#ifndef STRIP_ERROR_PROTECTION_API_FL -#endif /* STRIP_ERROR_PROTECTION_API_FL */ - diff --git a/lib_lc3plus/lc3.h b/lib_lc3plus/lc3.h index fab259e96..64d8cc590 100644 --- a/lib_lc3plus/lc3.h +++ b/lib_lc3plus/lc3.h @@ -1,63 +1,91 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /*! \file lc3.h * This header provides the API for LC3plus. * * This library is targeting devices with extreme memory limitations, so memory management - * must be handeled by the user. This includes allocating memory for the structs. The structs are persistent - * between function calls. + * must be handeled by the user. This includes allocating memory for the structs and scratch + * memory. The structs are persistent between function calls. The scratch memory is working + * memory that does not persist between function calls. * * The amount of memory needed for various configurations can be obtained from the lc3plus_*_get_size - * function. The LC3PLUS_*_MAX_SIZE macro can be used for all configurations. + * and lc3plus_*_get_scratch_size functions. If memory usage is not a concern the LC3PLUS_*_MAX_SIZE + * LC3PLUS_*_MAX_SCRATCH_SIZE macros can be used for all configurations. * * Depending on the build configuration some functions might not be available. */ #ifndef LC3PLUS_H -#define LC3PLUS_H +#define LC3PLUS_H + +#define ENABLE_HR_MODE #ifndef _MSC_VER -#include "options.h" -#include "wmc_auto.h" #include #else -typedef unsigned char uint8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; +typedef __int16 int16_t; +typedef __int32 int32_t; #endif /*! Construct version number from major/minor/micro values. */ #define LC3PLUS_VERSION_INT(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro)) /*! Version number to ensure header and binary are matching. */ -#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 2) +#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 3) /*! Maximum number of supported channels. The actual binary might support * less, use lc3plus_channels_supported() to check. */ #define LC3PLUS_MAX_CHANNELS 2 -/*! Maximum number of samples per channel that can be stored in one LC3plus frame. - */ +/*! Maximum number of samples per channel that can be stored in one LC3plus frame. */ +#ifdef ENABLE_HR_MODE #define LC3PLUS_MAX_SAMPLES 960 +#else +#define LC3PLUS_MAX_SAMPLES 480 +#endif /*! Maximum number of bytes of one LC3plus frame. */ -#define LC3PLUS_MAX_BYTES 1250 +#ifdef ENABLE_HR_MODE +#define LC3PLUS_MAX_BYTES (625 * LC3PLUS_MAX_CHANNELS) +#else +#define LC3PLUS_MAX_BYTES 870 +#endif /*! Maximum size needed to store encoder state. */ -#define LC3PLUS_ENC_MAX_SIZE 20392 +#ifdef ENABLE_HR_MODE +#define LC3PLUS_ENC_MAX_SIZE 12628 +#else +#define LC3PLUS_ENC_MAX_SIZE 7226 +#endif /*! Maximum size needed to store decoder state. */ -#define LC3PLUS_DEC_MAX_SIZE 87528 +#ifdef ENABLE_HR_MODE +#define LC3PLUS_DEC_MAX_SIZE 42488 +#else +#define LC3PLUS_DEC_MAX_SIZE 28446 +#endif -/*! Error codes returned by functions. */ +/*! Maximum scratch size needed by lc3plus_enc16() or lc3plus_enc24().*/ +#ifdef ENABLE_HR_MODE +# define LC3PLUS_ENC_MAX_SCRATCH_SIZE 45624 +#else +# define LC3PLUS_ENC_MAX_SCRATCH_SIZE 6784 +#endif + +/*! Maximum scratch size needed by lc3plus_dec16() or lc3plus_dec24(). */ +#ifdef ENABLE_HR_MODE +#define LC3PLUS_DEC_MAX_SCRATCH_SIZE 59768 +#else +#define LC3PLUS_DEC_MAX_SCRATCH_SIZE 27474 +#endif +/*! Decoder packet loss concealment mode */ typedef enum { LC3PLUS_PLC_ADVANCED = 1 /*!< Enhanced concealment method */ @@ -173,14 +201,18 @@ int lc3plus_samplerate_supported(int samplerate); * \param[in] hrmode High resolution mode. * \return LC3PLUS_OK on success or appropriate error code. */ -LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc* encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]); +LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + , int32_t lfe_channel_array[] + ); /*! * Encode LC3plus frame with 16 bit input. * * Each call consumes a fixed number of samples. The number of input samples * can be obtained from lc3plus_enc_get_input_samples(). - * Scratch parameter only works as dummy parameter to align fixed-point and floating-point APIs * * \param[in] encoder Encoder handle initialized by lc3plus_enc_init(). * \param[in] input_samples Input samples. The left channel is stored in input_samples[0], @@ -189,31 +221,23 @@ LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc* encoder, int samplerate, int channel * \param[out] output_bytes Output buffer. It must have a at least lc3plus_enc_get_num_bytes() * or at most LC3PLUS_MAX_BYTES. * \param[out] num_bytes Number of bytes written to output_bytes. - * \param scratch See comment above. + * \param scratch A pointer to an allocated work buffer of at least + * lc3plus_enc_get_scratch_size() or at most LC3PLUS_ENC_SCRATCH_SIZE bytes. + * The buffer does not have to persist, so it can be used for other + * purposes in between calls. * \return LC3PLUS_OK on success or appropriate error code. */ -LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc* encoder, int16_t** input_samples, void* output_bytes, int* num_bytes -, void *scratch -); +LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc *encoder, int16_t **input_samples, void *output_bytes, int *num_bytes, void *scratch); /*! Encode LC3plus frame with 24 bit input. * * The input samples are expected to be 24-bit values, sign-extended to 32-bit. * See lc3plus_enc16() for parameter documentation. */ -LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc* encoder, int32_t** input_samples, void* output_bytes, int* num_bytes -, void *scratch -); - -/*! - * Internal function. Use lc3plus_enc16() or lc3plus_enc24() for encoding. - */ - -LC3PLUS_Error lc3plus_enc_fl(LC3PLUS_Enc* encoder, void** input_samples, int bitdepth, void* output_bytes, int* num_bytes); +LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc *encoder, int32_t **input_samples, void *output_bytes, int *num_bytes, void *scratch); -/*! Get the size of the LC3plus encoder struct for a samplerate / channel - * configuration. If memory is not restricted LC3PLUS_ENC_MAX_SIZE can be used for - * all configurations. +/*! Get the size of the LC3plus encoder struct for a samplerate / channel configuration. + * If memory is not restricted LC3PLUS_ENC_MAX_SIZE can be used for all configurations. * * \param[in] samplerate Sampling rate. * \param[in] channels Number of channels. @@ -221,7 +245,9 @@ LC3PLUS_Error lc3plus_enc_fl(LC3PLUS_Enc* encoder, void** input_samples, int bit */ int lc3plus_enc_get_size(int samplerate, int channels); -/*! Dummy function as no scratch management available in floating-point code. Returns always zero. Used to align fixed-point and floating-point APIs. +/*! Get the size of the scratch buffer required by lc3plus_enc16() or lc3plus_enc24() for the current + * encoder configuration. If memory is not restricted, LC3PLUS_ENC_MAX_SCRATCH_SIZE can be used for + * all configurations. * * \param[in] encoder Encoder handle. * \return Size in bytes or 0 on error. @@ -233,18 +259,18 @@ int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder); * \param[in] encoder Encoder handle. * \return Number of samples or 0 on error. */ -int lc3plus_enc_get_input_samples(const LC3PLUS_Enc* encoder); +int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder); -/*! Get real internal bitrate of the encoder. It might differ from the requested - * bitrate due to 44.1 kHz input. +/*! Get real internal bitrate of the encoder. It might differ from the requested bitrate due + * to error protection or 44.1 kHz input. * * \param[in] encoder Encoder handle. * \return Bitrate in bits per second or 0 on error. */ -int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc* encoder); +int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder); /*! Get the maximum number of bytes produced by lc3plus_enc16() or lc3plus_enc24() for the current - * bitrate. It should be equal to the num_bytes output of lc3plus_enc16/24(). + * bitrate. It should be equal to the num_bytes output of lc3plus_enc16(). * * \param[in] encoder Encoder handle. * \return Size in bytes or 0 on error. @@ -253,7 +279,7 @@ int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder); /*! Set encoder bitrate for all channels. * This function must be called at least once before encoding the first frame, but - * after other configuration functions such as lc3plus_enc_set_frame_ms(). + * after other configuration functions such as lc3plus_enc_set_frame_dms(). * * Recommended bitrates for input sampling rates with 10 ms framing: * kHz | kbps @@ -263,33 +289,14 @@ int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder); * 24 | 48 * 32 | 64 * 44.1/48 | 80(voice) 128(music) - * 96 | 128 * * \param[in] encoder Encoder handle. * \param[in] bitrate Bitrate in bits per second. * \return LC3PLUS_OK on success or appropriate error code. */ -LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc* encoder, int bitrate); +LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc *encoder, int bitrate); -/*! Get the encoder delay in number of samples. - * - * \param[in] encoder Encoder handle. - * \return Encoder in samples or 0 on error. - */ -int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder); - -/*! Set the frame length for LC3plus decoder in deci milliseconds. - * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned. - * This only works correcly if the encoder was configured with the same vale. - * - * \param[in] decoder Decoder handle. - * \param[in] frame_ms Frame length in ms. - * \return LC3PLUS_OK on success or appropriate error code. - */ -LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_ms); - - -/*! Set encoder Low-frequency effect moded. deactivates LTPF, TNS, NF +/*! Set encoder Low-frequency effect moded. deactivates LTPF, TNS, NF. * * \param[in] encoder Encoder handle. * \param[in] lfe LFE mode flag @@ -297,28 +304,34 @@ LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_ms); */ LC3PLUS_Error lc3plus_enc_set_lfe(LC3PLUS_Enc* encoder, int lfe); -/*! Free memory allocated within LC3plus encoder struct. +/*! Get the encoder delay in number of samples. * * \param[in] encoder Encoder handle. - * \return LC3PLUS_OK on success or appropriate error code. + * \return Encoder in samples or 0 on error. */ -LC3PLUS_Error lc3plus_enc_free_memory(LC3PLUS_Enc* encoder); +int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder); -/*! Set encoder bandwidth to a different value. All frequency bins above the cutoff - * frequency are cut off. Allowed frequencies are: 4 kHz, 8 kHz, 12 kHz, 16 kHz and 24 kHz. +/*! Set the frame length for LC3plus encoder in deci milliseconds. + * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned. + * This function must be called before lc3plus_enc_set_bitrate(). The decoder must be + * configured with lc3plus_dec_set_frame_dms() with the same value. * * \param[in] encoder Encoder handle. - * \param[in] bandwidth Cutoff Frequency in Hz + * \param[in] frame_ms Frame length in ms. * \return LC3PLUS_OK on success or appropriate error code. */ -LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth); +LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_ms); -/*! Internal function called by lc3plus_enc_free_memory. +/*! Set error protection mode. The default is LC3PLUS_EP_OFF. It is possible to switch between + * different modees during encoding. Dynamic switching is only allowed between LC3PLUS_EP_ZERO, + * LC3PLUS_EP_LOW, LC3_EP_MEDIUM, and LC3PLUS_EP_HIGH. The the decoder must be notified with + * lc3plus_dec_set_ep_enabled() to expect protected data if epmode is other than LC3PLUS_EP_OFF. * * \param[in] encoder Encoder handle. + * \param[in] epmode Error protection mode. * \return LC3PLUS_OK on success or appropriate error code. */ -LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder); +LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode); /*! Sets error protection mode request transmitted in each channel encoded frame. * The channel coder includes an error protection mode request (EPMR) in every frame. @@ -332,41 +345,44 @@ LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder); */ LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr); -/*! Set error protection mode. The default is LC3PLUS_EP_OFF. It is possible to switch between - * different modees during encoding. Dynamic switching is only allowed between LC3PLUS_EP_ZERO, - * LC3PLUS_EP_LOW, LC3_EP_MEDIUM, and LC3PLUS_EP_HIGH. The the decoder must be notified with - * lc3plus_dec_set_ep_enabled() to expect protected data if epmode is other than LC3PLUS_EP_OFF. +/*! Set encoder bandwidth to a different value. All frequency bins above the cutoff + * frequency are cut off. Allowed frequencies are: 4 kHz, 8 kHz, 12 kHz, 16 kHz and 24 kHz. * * \param[in] encoder Encoder handle. - * \param[in] epmode Error protection mode. + * \param[in] bandwidth Cutoff Frequency in Hz * \return LC3PLUS_OK on success or appropriate error code. */ -LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode); +LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth); /*! \} * \addtogroup Decoder * \{ */ + /*! * Initialize LC3plus decoder. * - * This function is used to fill a user-allocated decoder struct. This is - * typically called once for a samplerate / channel configuration. + * This function is used to fill a user-allocated decoder struct. This is typically + * called once for a samplerate / channel / plc_mode configuration. * - * The samplerate and channel arguments must have the same values that were - * used for encoding. LC3plus does not provide a signalling scheme, transporting - * these values is the responsibility of the application. + * The samplerate and channel arguments must have the same values that were used for encoding. + * LC3plus does not provide a signalling scheme, transporting these values is the responsibility + * of the application. * - * \param[out] decoder Pointer to decoder memory. It must have as size - * of least lc3plus_dec_get_size() or at most LC3PLUS_DEC_MAX_SIZE. - * \param[in] samplerate Bitstream sampling rate. \param[in] channels Bitstream - * number of channels. + * \param[out] decoder Pointer to decoder memory. It must have as size of least + * lc3plus_dec_get_size() or at most LC3PLUS_DEC_MAX_SIZE. + * \param[in] samplerate Bitstream sampling rate. + * \param[in] channels Bitstream number of channels. + * \param[in] plc_mode Packet loss concealment mode. + * \param[in] hrmode High resolution mode mode. * * \return LC3PLUS_OK on success or appropriate error code. */ -LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode, int hrmode); - - +LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + ); /*! * Decode compressed LC3plus frame to 16 bit PCM output. @@ -387,83 +403,68 @@ LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec* decoder, int samplerate, int channel * should provide enough space to hold at most LC3PLUS_MAX_SAMPLES. The * left channel is stored in output_samples[0], the right channel in * output_samples[1]. - * \param scratch Scratch parameter only works as dummy parameter to align fixed-point and floating-point APIs + * \param scratch A pointer to an allocated work buffer of at least + * lc3plus_dec_get_scratch_size() or at most LC3PLUS_DEC_MAX_SCRATCH_SIZE + * bytes. The scratch buffer does not have to persist, so it can be + * used for other purposes in between calls. * \return Returns LC3PLUS_OK on success or appropriate error code. Note there is * a special case for LC3PLUS_DECODE_ERROR where the output is still valid. */ -LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, int16_t** output_samples, - void* scratch, - int bfi_ext); +LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int16_t **output_samples, void *scratch, + int bfi_ext); /*! Decode compressed LC3plus frame to 24 bit PCM output. * * The output samples are 24-bit values, sign-extended to 32-bit. * See lc3plus_dec16() for parameter documentation. */ -LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, int32_t** output_samples, - void* scratch, - int bfi_ext); +LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int32_t **output_samples, void *scratch, + int bfi_ext); -/* Internal function */ - LC3PLUS_Error lc3plus_dec_fl(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, void** output_samples, int bps, int bfi_ext); - -/*! Get the size of the LC3plus decoder struct for a samplerate / channel - * configuration. If memory is not restricted LC3PLUS_DEC_MAX_SIZE can be used for - * all configurations. +/*! Get the size of the LC3plus decoder struct for a samplerate / channel / plc_mode configuration. + * If memory is not restricted LC3PLUS_DEC_MAX_SIZE can be used for all configurations. * * \param[in] channels Number of channels. * \param[in] samplerate Sampling rate. + * \param[in] plc_mode Packet loss concealment mode. * \return Size in bytes or 0 on error. */ -int lc3plus_dec_get_size(int samplerate, int channels); +int lc3plus_dec_get_size(int samplerate, int channels, LC3PLUS_PlcMode plc_mode); -/*! Dummy function as no scratch management available in floating-point code. Returns always zero. Used to align fixed-point and floating-point APIs. +/*! Get the size of the scratch buffer required by lc3plus_dec16() or lc3plus_dec24() for the current + * decoder configuration. If memory is not restricted LC3PLUS_DEC_MAX_SCRATCH_SIZE can be used for + * all configurations. * * \param[in] decoder Decoder handle. * \return Size in bytes or 0 on error. */ int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder); -/*! Get the number of samples per channel produced by lc3plus_dec16() or lc3plus_dec24. +/*! Get the number of samples per channel produced by lc3plus_dec16() or lc3plus_dec24(). * * \param[in] decoder Decoder handle. * \return Number of samples or 0 on error. */ -int lc3plus_dec_get_output_samples(const LC3PLUS_Dec* decoder); + +int lc3plus_dec_get_output_samples(const LC3PLUS_Dec *decoder); /*! Get the decoder delay in number of samples. * * \param[in] decoder Decoder handle. * \return Delay in samples or 0 on error. */ -int lc3plus_dec_get_delay(const LC3PLUS_Dec* decoder); +int lc3plus_dec_get_delay(const LC3PLUS_Dec *decoder); -/*! Set the frame length for LC3plus encoder in deci milliseconds. +/*! Set the frame length for LC3plus decoder in deci milliseconds. * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned. - * This function must be called before lc3plus_enc_set_bitrate(). The decoder must be - * configured with lc3plus_dec_set_frame_dms() with the same value. + * This only works correcly if the encoder was configured with the same vale. * - * \param[in] encoder Encoder handle. + * \param[in] decoder Decoder handle. * \param[in] frame_ms Frame length in ms. * \return LC3PLUS_OK on success or appropriate error code. */ LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_ms); - -/*! Free memory allocated within LC3plus decoder struct. - * - * \param[in] decoder Decoder handle. - * \return LC3PLUS_OK on success or appropriate error code. - */ -LC3PLUS_Error lc3plus_dec_free_memory(LC3PLUS_Dec* decoder); - -/*! Internal function called by lc3plus_dec_free_memory. - * - * \param[in] decoder Decoder handle. - * \return LC3PLUS_OK on success or appropriate error code. - */ -LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder); - /*! Enable or disable error protection. Default value is 0 (disabled). If error protection is * enabled, the decoder expects that the frames were encoded with error protection mode * LC3PLUS_EP_ZERO or higher. diff --git a/lib_lc3plus/lc3plus_fft.c b/lib_lc3plus/lc3plus_fft.c deleted file mode 100644 index c7911b92d..000000000 --- a/lib_lc3plus/lc3plus_fft.c +++ /dev/null @@ -1,101 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" -#include "fft/iis_fft.c" -#include "fft/iisfft.c" -#include "fft/cfft.c" - -void fft_init(Fft* fft, int length) -{ - HANDLE_IIS_FFT handle = NULL; - IIS_FFT_ERROR error = 0; - assert(length % 2 == 0); - - fft->length = length; - - error = LC3_IIS_CFFT_Create(&handle, length, IIS_FFT_FWD); - - assert(error == IIS_FFT_NO_ERROR); - fft->handle = handle; -} - -void fft_free(Fft* fft) -{ - IIS_FFT_ERROR error = 0; - - if (fft) { - error = LC3_IIS_CFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); - - assert(error == IIS_FFT_NO_ERROR); - memset(fft, 0, sizeof(*fft)); - } -} - -void real_fft_free(Fft* fft) -{ - IIS_FFT_ERROR error = 0; - - if (fft) { - error = LC3_IIS_RFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); - - assert(error == IIS_FFT_NO_ERROR); - memset(fft, 0, sizeof(*fft)); - } -} - -void real_fft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle) -{ - IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; - assert(length % 4 == 0); /* due to current limitation of core complex FFTs*/ - - fft->length = length; - - error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_FWD); - assert(error == IIS_FFT_NO_ERROR); - fft->handle = *handle; -} - - -void real_ifft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle) -{ - IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; - assert(length % 4 == 0); /* due to current limitation of core complex FFTs*/ - - fft->length = length; - - error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_BWD); - - assert(error == IIS_FFT_NO_ERROR); - fft->handle = *handle; -} - -void fft_apply(Fft* fft, const Complex* input, Complex* output) -{ - IIS_FFT_ERROR error = 0; - error = LC3_IIS_FFT_Apply_CFFT(fft->handle, input, output); - - assert(error == IIS_FFT_NO_ERROR); -} - - -void real_fft_apply(Fft* fft, const LC3_FLOAT* input, LC3_FLOAT* output) -{ - IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; - - UNUSED(error); - - error = LC3_IIS_FFT_Apply_RFFT(fft->handle, input, output); - - assert(error == IIS_FFT_NO_ERROR); -} - diff --git a/lib_lc3plus/levinson_fx.c b/lib_lc3plus/levinson_fx.c new file mode 100644 index 000000000..9003173d0 --- /dev/null +++ b/lib_lc3plus/levinson_fx.c @@ -0,0 +1,160 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void processLevinson_fx(Word32 *lpc, Word32 *ac, Word16 N, Word16 *rc, Word32 *pred_err, Word8 *scratchBuffer) +{ + + Word32 *lpc_tmp; + Word32 rc32, err, sum; + Word16 shift, s, inv; + Counter n, m; + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processLevinson_fx", sizeof(struct { + Word32 *lpc_tmp; + Word32 rc32, err, sum; + Word16 shift, s, inv; + Counter n, m; + Word32 params[2]; + })); +#endif + + lpc_tmp = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * (M_LTPF + 1) = 100 bytes */ + + /* Init Prediction Error */ + err = ac[0]; move32(); + shift = 0; move16(); + + /* LPC Coefficient 0 */ + lpc[0] = 0x8000000; move32(); + + /* Reflection Coefficient 0 */ + IF (ac[0] != 0) + { + inv = div_s(16383, extract_h(ac[0])); + rc32 = L_shl_pos(Mpy_32_32_lc3plus(L_abs(ac[1]), Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(ac[0], inv)), inv)), 2); + } + ELSE + { + rc32 = 0; move32(); + } + if (ac[1] > 0) + { + rc32 = L_negate(rc32); + } + if (rc != NULL) + { + rc[0] = round_fx(rc32); move16(); + } + + /* LPC Coefficient 1 */ + lpc[1] = L_shr_pos(rc32, 4); move32(); + + FOR (n = 2; n <= N; n++) + { + /* Update Prediction Error */ + err = Mpy_32_32_lc3plus(err, L_sub(MAX_32, Mpy_32_32_lc3plus(rc32, rc32))); + s = norm_l(err); + err = L_shl_pos(err, s); + shift = add(shift, s); + + /* Reflection Coefficient n-1 */ + sum = Mpy_32_32_lc3plus(ac[1], lpc[n - 1]); + FOR (m = 2; m < n; m++) + { + sum = L_add(sum, Mpy_32_32_lc3plus(ac[m], lpc[n - m])); + } + + sum = L_add(L_shl_pos(sum, 4), ac[n]); + IF (err != 0) + { + inv = div_s(16383, extract_h(err)); + rc32 = L_shl_pos(Mpy_32_32_lc3plus(L_abs(sum), Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(err, inv)), inv)), 2); + } + ELSE + { + rc32 = 0; + } + if (sum > 0) + { + rc32 = L_negate(rc32); + } + rc32 = L_shl(rc32, shift); + if (rc != NULL) + { + rc[n - 1] = round_fx(rc32); move16(); + } + +/* Recompute LPC Coefficients up to n-1 */ + FOR (m = 1; m < n; m++) + { + lpc_tmp[m] = L_add(lpc[m], Mpy_32_32_lc3plus(rc32, lpc[n - m])); move32(); + } + + basop_memmove(&lpc[1], &lpc_tmp[1], (n - 1) * sizeof(Word32)); + + /* LPC Coefficient n */ + lpc[n] = L_shr_pos(rc32, 4); move32(); + } + + /* Final Prediction Error */ + IF (pred_err != NULL) + { + err = Mpy_32_32_lc3plus(err, L_sub(MAX_32, Mpy_32_32_lc3plus(rc32, rc32))); + *pred_err = L_shr(err, shift); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + +void lpc2rc(Word32 *lpc, Word16 *rc, Word16 N) +{ + Word32 lpc_tmp[MAXLAG + 1]; + Word32 rc32, tmp0, tmp1; + Word16 inv; + Counter n, m; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("lpc2rc", sizeof(struct { + Word32 lpc_tmp[MAXLAG + 1]; + Word32 rc32, tmp0, tmp1; + Word16 inv; + Counter n, m; + })); +#endif + + FOR (n = N; n >= 2; n--) + { + rc32 = L_shl_pos(lpc[n], 4); + rc[n - 1] = round_fx(rc32); move16(); + + tmp0 = L_sub(MAX_32, L_abs(Mpy_32_32_lc3plus(rc32, rc32))); + FOR (m = 1; m < n; m++) + { + tmp1 = L_sub(lpc[m], Mpy_32_32_lc3plus(lpc[n - m], rc32)); + inv = div_s(16383, extract_h(tmp0)); + lpc_tmp[m] = L_shl_pos(Mpy_32_32_lc3plus(tmp1, Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(tmp0, inv)), inv)), 2); move32(); + } + + basop_memmove(&lpc[1], &lpc_tmp[1], (n - 1) * sizeof(Word32)); + } + + rc[0] = round_fx(L_shl_pos(lpc[1], 4)); move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/license.h b/lib_lc3plus/license.h index 077df126e..22f25e9ff 100644 --- a/lib_lc3plus/license.h +++ b/lib_lc3plus/license.h @@ -1,22 +1,19 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" #include "defines.h" static const char *const LICENSE = "*******************************************************************************\n" - "* ETSI TS 103 634 V1.4.3 *\n" + "* ETSI TS 103 634 V1.4.5 *\n" "* Low Complexity Communication Codec Plus (LC3plus) *\n" - "* Floating Point Software V%i.%i.%iETSI, " __DATE__ " *\n" + "* Fixed Point Software V%i.%i.%iETSI, " __DATE__ " *\n" "* Copyright licence is solely granted through ETSI Intellectual Property *\n" "* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *\n" "* estoppel or otherwise. *\n" diff --git a/lib_lc3plus/ltpf_coder.c b/lib_lc3plus/ltpf_coder.c deleted file mode 100644 index 81a491ab9..000000000 --- a/lib_lc3plus/ltpf_coder.c +++ /dev/null @@ -1,268 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); - -LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) -{ - LC3_INT max_i = 0, i; - LC3_FLOAT max = 0; - - if (len <= 0) { - return -128; - } - - for (i = 0; i < len; i++) { - if (in[i] > max) { - max = in[i]; - max_i = i; - } - } - - return max_i; -} - -void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms, - LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch, - LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits -#ifdef CR9_K_REDUCE_NORM_CORR_TH - , LC3_INT16 hrmode -#endif -) -{ - LC3_FLOAT buffer[LTPF_MEMIN_LEN + LEN_12K8 + 1 + (LEN_12K8 >> 2)], sum = 0, cor_up[(MAX_PITCH_12K8 - MIN_PITCH_12K8) / 2] = {0}, *x; - LC3_INT i, j, n, step, N, ltpf_active, pitch_search_delta, - pitch_search_upsamp = 0, pitch_search_L_interpol1 = 0, - t0_min = 0, t0_max = 0, t_min = 0, t_max = 0, temp2 = 0, t1 = 0, pitch_int = 0, pitch_fr = 0, midpoint = 0, - delta_up = 0, delta_down = 0, pitch_index = 0, gain = 0, acflen = 0; - LC3_FLOAT cor_tmp, cor_int_tmp, norm_corr = 0, cor[MAX_LEN_NR], cor_int[MAX_LEN_NR], sum1 = 0, sum2 = 0, sum3 = 0; - LC3_FLOAT pitch = 0; - -#ifdef CR9_K_REDUCE_NORM_CORR_TH - LC3_FLOAT normCorrTh = 0.0f; - if (hrmode) { - normCorrTh = 0.4; - } else { - normCorrTh = 0.6; - } -#endif - - /* Signal Buffer */ - N = xLen - 1; - x = &buffer[memLen]; - - move_float(buffer, mem_old_x, memLen); - move_float(x, xin, xLen); - move_float(mem_old_x, &buffer[N], xLen + memLen - N); - - ltpf_active = 0; - norm_corr = 0; - - pitch_search_delta = 4; - pitch_search_upsamp = 4; - pitch_search_L_interpol1 = 4; - -#ifdef CR9_K_REDUCE_NORM_CORR_TH - if (pitch_ol_norm_corr > normCorrTh) -#else - if (pitch_ol_norm_corr > 0.6) -#endif - { - /* Search Bounds */ - t0_min = pitch_ol - pitch_search_delta; - t0_max = pitch_ol + pitch_search_delta; - t0_min = MAX(t0_min, MIN_PITCH_12K8); - t0_max = MIN(t0_max, MAX_PITCH_12K8); - acflen = N; - - if (frame_dms == 25) - { - acflen = 2 * N; - x = x - N; - } - - /* Cross-Correlation Bounds */ - t_min = t0_min - pitch_search_L_interpol1; - t_max = t0_max + pitch_search_L_interpol1; - - /* Compute norm */ - sum1 = sum2 = 0; - for (j = 0; j < acflen; j++) { - sum1 += x[j] * x[j]; - sum2 += x[j - t_min] * x[j - t_min]; - } - - /* Do first iteration outside of loop */ - sum = mac_loop(x, &x[-t_min], acflen); - - sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05; - norm_corr = sum / sum3; - - norm_corr = MAX(0, norm_corr); - cor[0] = norm_corr; - - /* Compute Cross-Correlation */ - for (i = t_min + 1; i <= t_max; i++) { - sum = mac_loop(x, &x[-i], acflen); - - sum2 = sum2 + x[-i]*x[-i] - - x[acflen - 1 - ( i - 1 )]*x[acflen - 1 - ( i - 1 )]; - - sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05; - norm_corr = sum / sum3; - - norm_corr = MAX(0, norm_corr); - cor[i - t_min] = norm_corr; - - } - - /* Find Integer Pitch-Lag */ - temp2 = searchMaxIndice(&cor[pitch_search_L_interpol1], t_max - t_min - pitch_search_L_interpol1 - pitch_search_L_interpol1 + 1); - - t1 = temp2 + t0_min; - assert(t1 >= t0_min && t1 <= t0_max); - - /* Find Fractional Pitch-Lag */ - if (t1 >= RES2_PITCH_12K8) { - pitch_int = t1; - pitch_fr = 0; - } else { - j = 0; - - for (i = 0; i < pitch_search_upsamp * (t_max - t_min) + 1; i = i + pitch_search_upsamp) { - cor_up[i] = cor[j]; - j++; - } - - for (i = 0; i < pitch_search_upsamp * (t0_max - t0_min + 1); i++) { - sum = mac_loop(&cor_up[i], (const LC3_FLOAT *)inter4_1, 32); - - cor_int[i] = sum; - } - - if (t1 >= RES4_PITCH_12K8) { - step = 2; - } else { - step = 1; - } - - midpoint = pitch_search_upsamp * (t1 - t0_min) + 1; - delta_up = pitch_search_upsamp - step; - - if (t1 == t0_min) { - delta_down = 0; - } else { - delta_down = pitch_search_upsamp - step; - } - - j = 0; - for (i = midpoint - delta_down - 1; i <= midpoint + delta_up; i = i + step) { - cor[j] = cor_int[i]; - j++; - } - - - temp2 = searchMaxIndice(cor, ((midpoint + delta_up) - (midpoint - delta_down)) / step + 1); - pitch_fr = temp2 * step - delta_down; - - if (pitch_fr >= 0) { - pitch_int = t1; - } else { - pitch_int = t1 - 1; - pitch_fr = pitch_search_upsamp + pitch_fr; - } - } - - assert((pitch_int <= MAX_PITCH_12K8 && pitch_int >= RES2_PITCH_12K8 && pitch_fr == 0) || - (pitch_int < RES2_PITCH_12K8 && pitch_int >= RES4_PITCH_12K8 && (pitch_fr == 0 || pitch_fr == 2)) || - (pitch_int < RES4_PITCH_12K8 && pitch_int >= MIN_PITCH_12K8 && - (pitch_fr == 0 || pitch_fr == 1 || pitch_fr == 2 || pitch_fr == 3))); - - if (pitch_int < RES4_PITCH_12K8) { - pitch_index = pitch_int * 4 + pitch_fr - (MIN_PITCH_12K8 * 4); - } else if (pitch_int < RES2_PITCH_12K8) { - pitch_index = pitch_int * 2 + floor(pitch_fr / 2) - (RES4_PITCH_12K8 * 2) + ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4); - } else { - pitch_index = pitch_int - RES2_PITCH_12K8 + ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) + ((RES2_PITCH_12K8 - RES4_PITCH_12K8) * 2); - } - - assert(pitch_index >= 0 && pitch_index < 512); - pitch = (LC3_FLOAT) pitch_int + (LC3_FLOAT) pitch_fr / 4.0; - - - /* Normalized Correlation */ - sum1 = sum2 = sum3 = 0; - for (n = 0; n < acflen; n++) - { - cor_tmp = x[n + 1] * enc_inter_filter[0][0] + - x[n] * enc_inter_filter[0][1] + - x[n - 1] * enc_inter_filter[0][2]; - - cor_int_tmp = x[n - pitch_int + 1] * enc_inter_filter[pitch_fr][0] + - x[n - pitch_int] * enc_inter_filter[pitch_fr][1] + - x[n - pitch_int - 1] * enc_inter_filter[pitch_fr][2] + - x[n - pitch_int - 2] * enc_inter_filter[pitch_fr][3]; - - sum1 += cor_tmp * cor_int_tmp; - sum2 += cor_tmp * cor_tmp; - sum3 += cor_int_tmp * cor_int_tmp; - } - - sum2 = LC3_SQRT(sum2 * sum3) + 1.00e-05; - norm_corr = sum1 / sum2; - - assert(norm_corr >= -1.00001 && norm_corr <= 1.00001); - norm_corr = MIN(1, MAX(-1, norm_corr)); - if (norm_corr < 0) { - norm_corr = 0; - } - - if (ltpf_enable == 1) { - /* Decision if ltpf active */ - if ((*mem_on == 0 && (frame_dms == 100 || *mem_norm_corr_past_past > 0.94) && *mem_norm_corr_past > 0.94 && - norm_corr > 0.94) || - (*mem_on == 1 && norm_corr > 0.9) || - (*mem_on == 1 && LC3_FABS(pitch - *mem_pitch) < 2 && (norm_corr - *mem_norm_corr_past) > -0.1 && - norm_corr > 0.84)) { - ltpf_active = 1; - } - } - - gain = 4; - - } else { - gain = 0; - norm_corr = pitch_ol_norm_corr; - pitch = 0; - } - - if (gain > 0) { - param[0] = 1; - param[1] = ltpf_active; - param[2] = pitch_index; - *bits = 11; - } else { - zero_int(param, 3); - - *bits = 1; - } - - if (frame_dms < 100) { - *mem_norm_corr_past_past = *mem_norm_corr_past; - } - - *mem_norm_corr_past = norm_corr; - *mem_on = ltpf_active; - *mem_pitch = pitch; -} diff --git a/lib_lc3plus/ltpf_coder_fx.c b/lib_lc3plus/ltpf_coder_fx.c new file mode 100644 index 000000000..212788d73 --- /dev/null +++ b/lib_lc3plus/ltpf_coder_fx.c @@ -0,0 +1,323 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +/*************************************************************************/ + + +void process_ltpf_coder_fx(Word16 *bits, Word16 ol_pitch, Word16 ltpf_enable, Word16 *mem_in_exp, Word16 mem_in[], + Word16 mem_in_len, Word16 param[], Word16 *xin, Word16 len, Word16 *mem_normcorr, + Word16 *mem_mem_normcorr, Word16 ol_normcorr, Word16 *mem_ltpf_on, Word16 *mem_ltpf_pitch, + Word16 xin_exp, Word16 frame_dms, Word8 *scratchBuffer +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,Word16 hrmode +#endif +) +{ + Word16 pitch_index, scale0, scale1, scale2, *x, x_exp, shift, prod_exp, ltpf_pitch; + Word32 L_tmp, cor_max32, sum0, sum1, sum2, prod, inv; + Word32 *ac32; + Word16 *ac, *currFrame, *predFrame; + Word16 min_pitch, max_pitch, ac_min_pitch, ac_max_pitch, ac_max; + Word16 pitch, pitch_res, min_pitch_fr, pitch_int, pitch_fr, norm_corr, ltpf_active; + Counter n, m, fr; + Word16 tmp, acflen; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("process_ltpf_coder_fx", sizeof(struct { + Word16 pitch_index, scale0, scale1, scale2, *x, x_exp, shift, prod_exp, ltpf_pitch; + Word32 L_tmp, cor_max32, sum0, sum1, sum2, prod, inv; + Word32 *ac32; + Word16 *ac, *currFrame, *predFrame; + Word16 min_pitch, max_pitch, ac_min_pitch, ac_max_pitch, ac_max; + Word16 pitch, pitch_res, min_pitch_fr, pitch_int, pitch_fr, norm_corr, ltpf_active; + Counter n, m, fr; + Word16 tmp, acflen; + })); +#endif + + + + ac32 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 17 = 68 bytes; */ + ac = (Word16 *)scratchAlign(ac32, sizeof(*ac32) * 17); /* Size = 2 * 17 = 34 bytes */ + currFrame = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * 128 = 256 bytes */ + predFrame = (Word16 *)scratchAlign(currFrame, sizeof(*currFrame) * LEN_12K8); /* Size = 2 * 128 = 256 bytes */ + /* Buffers 'overlap' since they are not used at the same time */ /* Total size used = 512 bytes */ + + ltpf_active = 0; move16(); + norm_corr = 0; move16(); + + /* Input buffer */ + x = mem_in + mem_in_len; + + basop_memmove(x, xin, (len + 1) * sizeof(Word16)); + + ASSERT(mem_in_len + len + 1 <= LTPF_MEMIN_LEN + LEN_12K8 + 1); + + /* Scaling */ + scale0 = sub(getScaleFactor16_0(mem_in, mem_in_len), 3); + *mem_in_exp = sub(*mem_in_exp, scale0); move16(); + scale1 = sub(getScaleFactor16_0(x, len + 1), 3); + x_exp = sub(xin_exp, scale1); + scale2 = sub(*mem_in_exp, x_exp); + IF (scale2 > 0) + { + Scale_sig(x, len + 1, sub(scale1, scale2)); + Scale_sig(mem_in, mem_in_len, scale0); + x_exp = *mem_in_exp; move16(); + } + ELSE + { + Scale_sig(x, len + 1, scale1); + Scale_sig(mem_in, mem_in_len, add(scale0, scale2)); + *mem_in_exp = x_exp; move16(); + } + +#ifdef CR9_K_REDUCE_NORM_CORR_TH + Word32 normCorrTh = 0; + if (hrmode) { + normCorrTh = 13107; + } else { + normCorrTh = 19660; + } +#endif + +#ifdef CR9_K_REDUCE_NORM_CORR_TH + IF (sub(ol_normcorr, normCorrTh) > 0) +#else + IF (sub(ol_normcorr, 19660) > 0) +#endif + { + /* Autocorrelation Bounds */ + min_pitch = sub(ol_pitch, 4); + max_pitch = add(ol_pitch, 4); + min_pitch = s_max(min_pitch, MIN_PITCH_12K8); + max_pitch = s_min(max_pitch, MAX_PITCH_12K8); + ac_min_pitch = sub(min_pitch, 4); + ac_max_pitch = add(max_pitch, 4); + acflen = len; move16(); + if (sub(frame_dms, 25) == 0) + { + acflen = shl(len, 1); + x = x - len; + } + + /* Compute norm */ + sum1 = L_mac0(1, x[0], x[0]); + sum2 = L_mac0(1, x[-ac_min_pitch], x[-ac_min_pitch]); + FOR (m = 1; m < acflen; m++) + { + sum1 = L_mac0(sum1, x[m], x[m]); + sum2 = L_mac0(sum2, x[m - ac_min_pitch], x[m - ac_min_pitch]); + } + scale1 = norm_l(sum1); + sum1 = L_shl_pos(sum1, scale1); + + /* Compute Autocorrelation */ + FOR (n = ac_min_pitch; n <= ac_max_pitch; n++) + { + sum0 = L_mac0(0L, x[0], x[0 - n]); + FOR (m = 1; m < acflen; m++) + { + sum0 = L_mac0(sum0, x[m], x[m - n]); + } + if (n > ac_min_pitch) + { + sum2 = L_msu0(sum2, x[acflen - 1 - (n - 1)], x[acflen - 1 - (n - 1)]); + sum2 = L_mac0_sat(sum2, x[-n], x[-n]); + } + scale2 = norm_l(sum2); + L_tmp = L_shl_pos(sum2, scale2); + prod = Mpy_32_32_lc3plus(sum1, L_tmp); + shift = norm_l(prod); + prod = L_shl_pos(prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + inv = Isqrt(prod, &prod_exp); + scale0 = norm_l(sum0); + sum0 = L_shl_pos(sum0, scale0); + prod = Mpy_32_32_lc3plus(sum0, inv); + prod_exp = add(sub(31, scale0), prod_exp); + test(); + IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0) + { + ac[n - ac_min_pitch] = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16(); + } + ELSE + { + ac[n - ac_min_pitch] = 32767; move16(); + } + } + + /* Find maximum */ + ac_max = ac[min_pitch - ac_min_pitch]; move16(); + pitch = min_pitch; move16(); + FOR (n = min_pitch + 1; n <= max_pitch; n++) + { + tmp = sub_sat(ac[n - ac_min_pitch], ac_max); + if (tmp > 0) + { + pitch = n; move16(); + } + ac_max = s_max(ac_max, ac[n - ac_min_pitch]); + } + pitch_int = pitch; move16(); + pitch_fr = 0; move16(); + pitch_index = add(pitch_int, 283); + + /* If the pitch is low -> estimate a fractional part */ + IF (sub(pitch, RES2_PITCH_12K8) < 0) + { + IF (sub(pitch, RES4_PITCH_12K8) < 0) + { + pitch_res = 1; move16(); + min_pitch_fr = -3; move16(); + } + ELSE + { + pitch_res = 2; move16(); + min_pitch_fr = -2; move16(); + } + if (sub(pitch, min_pitch) == 0) + { + min_pitch_fr = 0; + } + cor_max32 = MIN_32; + FOR (fr = min_pitch_fr; fr < 4; fr += pitch_res) + { + sum0 = L_mult0(ac[pitch_int - ac_min_pitch - 4], ltpf_ac_interp_filt[fr + 3][0]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 3], ltpf_ac_interp_filt[fr + 3][1]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 2], ltpf_ac_interp_filt[fr + 3][2]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 1], ltpf_ac_interp_filt[fr + 3][3]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 0], ltpf_ac_interp_filt[fr + 3][4]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 1], ltpf_ac_interp_filt[fr + 3][5]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 2], ltpf_ac_interp_filt[fr + 3][6]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 3], ltpf_ac_interp_filt[fr + 3][7]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 4], ltpf_ac_interp_filt[fr + 3][8]); + + L_tmp = L_sub_sat(sum0, cor_max32); + if (L_tmp > 0) + { + pitch_fr = fr; move16(); + } + cor_max32 = L_max(cor_max32, sum0); + } + IF (pitch_fr < 0) + { + pitch_int = sub(pitch_int, 1); + pitch_fr = add(pitch_fr, 4); + } + IF (sub(pitch_int, 127) >= 0) + { + pitch_index = add(add(shl_pos(pitch_int, 1), shr_pos(pitch_fr, 1)), 126); + } + ELSE + { + pitch_index = sub(add(shl_pos(pitch_int, 2), pitch_fr), 128); + } + } + ltpf_pitch = add(shl_pos(pitch_int, 2), pitch_fr); + + /* Filter current and predicted frame */ + + FOR (n = 0; n < acflen; n++) + { + sum0 = L_mult(x[n + 1], inter_filter[0][0][0]); + sum0 = L_mac(sum0, x[n], inter_filter[0][0][1]); + currFrame[n] = mac_r(sum0, x[n - 1], inter_filter[0][0][2]); + + sum0 = L_mult(x[n - pitch_int + 1], inter_filter[0][pitch_fr][0]); + sum0 = L_mac(sum0, x[n - pitch_int], inter_filter[0][pitch_fr][1]); + sum0 = L_mac(sum0, x[n - pitch_int - 1], inter_filter[0][pitch_fr][2]); + predFrame[n] = mac_r(sum0, x[n - pitch_int - 2], inter_filter[0][pitch_fr][3]); + } + + /* Normalized Correlation */ + sum0 = L_mult0(currFrame[0], predFrame[0]); + sum1 = L_mac0(1, predFrame[0], predFrame[0]); + sum2 = L_mac0(1, currFrame[0], currFrame[0]); + for (m = 1; m < acflen; m++) + { + sum0 = L_mac0(sum0, currFrame[m], predFrame[m]); + sum1 = L_mac0(sum1, predFrame[m], predFrame[m]); + sum2 = L_mac0(sum2, currFrame[m], currFrame[m]); + } + + scale1 = norm_l(sum1); + scale2 = norm_l(sum2); + sum1 = L_shl_pos(sum1, scale1); + sum2 = L_shl_pos(sum2, scale2); + prod = Mpy_32_32_lc3plus(sum1, sum2); + shift = norm_l(prod); + prod = L_shl_pos(prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + inv = Isqrt(prod, &prod_exp); + scale0 = norm_l(sum0); + sum0 = L_shl_pos(sum0, scale0); + prod = Mpy_32_32_lc3plus(sum0, inv); + prod_exp = add(sub(31, scale0), prod_exp); + test(); + IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0) + { + norm_corr = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16(); + } + ELSE + { + norm_corr = 32767; move16(); + } + if (norm_corr < 0) + { + norm_corr = 0; + } + + IF (sub(ltpf_enable, 1) == 0) + { + test(); test(); test(); test(); + /* Decision if lptf active */ + IF ((*mem_ltpf_on == 0 && sub(*mem_normcorr, 30802) > 0 && sub(norm_corr, 30802) > 0 && + (sub(frame_dms, 100) == 0 || sub(*mem_mem_normcorr, 30802) > 0)) || + (sub(*mem_ltpf_on, 1) == 0 && sub(norm_corr, 29491) > 0) || + (sub(*mem_ltpf_on, 1) == 0 && sub(abs_s(sub(ltpf_pitch, *mem_ltpf_pitch)), 8) < 0 && + add(sub(norm_corr, *mem_normcorr), 3277) > 0 && sub(norm_corr, 27525) > 0)) + { + ltpf_active = 1; move16(); + } + } + + param[0] = 1; move16(); + param[1] = ltpf_active; move16(); + param[2] = pitch_index; move16(); + *bits = 11; move16(); + } + ELSE + { + norm_corr = ol_normcorr; move16(); + param[0] = 0; move16(); + param[1] = 0; move16(); + param[2] = 0; move16(); + *bits = 1; move16(); + ltpf_pitch = 0; move16(); + } + +/* Update memory */ + FOR (n = 0; n < mem_in_len; n++) + { + mem_in[n] = mem_in[n + len]; move16(); + } + + *mem_mem_normcorr = *mem_normcorr; move16(); + *mem_normcorr = norm_corr; move16(); + *mem_ltpf_on = ltpf_active; move16(); + *mem_ltpf_pitch = ltpf_pitch; move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/ltpf_decoder.c b/lib_lc3plus/ltpf_decoder.c deleted file mode 100644 index d51c7ffe3..000000000 --- a/lib_lc3plus/ltpf_decoder.c +++ /dev/null @@ -1,498 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, - LC3_INT* mem_pitch_int, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi, - LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, - LC3_FLOAT damping - , LC3_INT *mem_ltpf_active -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3_INT frame_dms -#endif -) -{ - LC3_INT i, j, n, N, L_past_x, N4, N34, - pitch_int, pitch_fr, p1, p2, L_past_y, inter_len, tilt_len = 0, - tilt_len_r, inter_len_r, old_x_len, old_y_len; - - LC3_FLOAT conf_alpha, gain, a1[12], a2[12], b1[11], b2[11], - buf_x[4 * MAX_LEN], buf_y[4 * MAX_LEN], buf_z[4 * MAX_LEN], pitch, sum1, sum2; -#ifdef CR9_LTPF_REWRITE - LC3_FLOAT *p_x, *p_y, *p_y2, *p_x_init, *p_y_init, *p_a1, *p_b1, *p_a2, *p_b2, fade_fac, current_fade_fac_up, current_fade_fac_down; -#endif -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - LC3_FLOAT pitch_fl_c_old, pitch_delta; -#endif - const LC3_FLOAT *inter_filter[4], *tilt_filter[4]; - -#ifdef WMOPS - push_wmops("process_ltpf_decoder_fl"); -#endif -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - pitch_fl_c_old = (LC3_FLOAT) *mem_pitch_int + (LC3_FLOAT)*mem_pitch_fr / 4.0; -#endif - conf_alpha = 0.85; - - if (bfi != 1) { - /* Decode pitch */ - if (param[0] == 1) { - if (param[2] < (RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) { - pitch_int = MIN_PITCH_12K8 + floor(param[2] / 4); - pitch_fr = param[2] - ((pitch_int - MIN_PITCH_12K8) * 4); - } else if (param[2] < ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) + ((RES2_PITCH_12K8 - RES4_PITCH_12K8) * 2)) { - param[2] = param[2] - ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4); - pitch_int = RES4_PITCH_12K8 + floor(param[2] / 2); - pitch_fr = param[2] - ((pitch_int - RES4_PITCH_12K8) * 2); - pitch_fr = pitch_fr * 2; - } else { - pitch_int = - param[2] + (RES2_PITCH_12K8 - ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) - ((RES2_PITCH_12K8 - RES4_PITCH_12K8) * 2)); - pitch_fr = 0; - } - - pitch = ((LC3_FLOAT)pitch_int + (LC3_FLOAT)pitch_fr / 4.0) * (LC3_FLOAT)fs / 12800.0; - pitch = round(pitch * 4.0) / 4.0; - pitch_int = floor(pitch); - pitch_fr = (LC3_INT)((pitch - (LC3_FLOAT)pitch_int) * 4.0); - } else { - pitch_int = 0; - pitch_fr = 0; - } - - /* Decode gain */ - if (conf_beta_idx < 0) { - param[1] = 0; - } - - if (param[1] == 1) { - gain = conf_beta; - } else { - gain = 0; - } - } - else if (concealMethod > 0) { - if (conf_beta_idx < 0) { - if (mem_param[1] && *mem_beta_idx >= 0) - { - conf_beta_idx = *mem_beta_idx; - } - } - - memmove(param, mem_param, sizeof(LC3_INT32) * 3); - if (concealMethod == 2) - { - /* cause the ltpf to "fade_out" and only filter during initial 2.5 ms and then its buffer during 7.5 ms */ - assert(bfi == 1); - param[1] = 0; /* ltpf_active = 0 */ - } - - pitch_int = *mem_pitch_int; - pitch_fr = *mem_pitch_fr; - gain = (LC3_FLOAT) *mem_gain * damping; - } - - if ((conf_beta <= 0) && (*mem_ltpf_active == 0)) - { - if (fs == 8000 || fs == 16000) { - tilt_len = 4 - 2; - } - else if (fs == 24000) { - tilt_len = 6 - 2; - } - else if (fs == 32000) { - tilt_len = 8 - 2; - } - else if (fs == 44100 || fs == 48000) { - tilt_len = 12 - 2; - } - - N = xLen; - old_x_len = tilt_len; - inter_len = MAX(fs, 16000) / 8000; - old_y_len = ceilf((LC3_FLOAT)228.0 * fs / 12800.0) + inter_len; /* 228.0 needed to make use of ceil */ - - move_float(mem_old_y, &mem_old_y[N], (old_y_len - N)); - move_float(&mem_old_y[old_y_len - N], x, N); - move_float(mem_old_x, &x[N - old_x_len], old_x_len); - - *mem_ltpf_active = 0; - } - else - { - inter_len_r = 0; tilt_len_r = 0; - if (fs == 8000 || fs == 16000) { - inter_filter[0] = conf_inter_filter_16[0]; - inter_filter[1] = conf_inter_filter_16[1]; - inter_filter[2] = conf_inter_filter_16[2]; - inter_filter[3] = conf_inter_filter_16[3]; - inter_len_r = 4; - - tilt_filter[0] = conf_tilt_filter_16[0]; - tilt_filter[1] = conf_tilt_filter_16[1]; - tilt_filter[2] = conf_tilt_filter_16[2]; - tilt_filter[3] = conf_tilt_filter_16[3]; - tilt_len = 4 - 2; - tilt_len_r = 3; - } else if (fs == 24000) { - inter_filter[0] = conf_inter_filter_24[0]; - inter_filter[1] = conf_inter_filter_24[1]; - inter_filter[2] = conf_inter_filter_24[2]; - inter_filter[3] = conf_inter_filter_24[3]; - inter_len_r = 6; - - tilt_filter[0] = conf_tilt_filter_24[0]; - tilt_filter[1] = conf_tilt_filter_24[1]; - tilt_filter[2] = conf_tilt_filter_24[2]; - tilt_filter[3] = conf_tilt_filter_24[3]; - tilt_len = 6 - 2; - tilt_len_r = 5; - } else if (fs == 32000) { - inter_filter[0] = conf_inter_filter_32[0]; - inter_filter[1] = conf_inter_filter_32[1]; - inter_filter[2] = conf_inter_filter_32[2]; - inter_filter[3] = conf_inter_filter_32[3]; - inter_len_r = 8; - - tilt_filter[0] = conf_tilt_filter_32[0]; - tilt_filter[1] = conf_tilt_filter_32[1]; - tilt_filter[2] = conf_tilt_filter_32[2]; - tilt_filter[3] = conf_tilt_filter_32[3]; - tilt_len = 8 - 2; - tilt_len_r = 7; - } else if (fs == 44100 || fs == 48000) { - inter_filter[0] = conf_inter_filter_48[0]; - inter_filter[1] = conf_inter_filter_48[1]; - inter_filter[2] = conf_inter_filter_48[2]; - inter_filter[3] = conf_inter_filter_48[3]; - inter_len_r = 12; - - tilt_filter[0] = conf_tilt_filter_48[0]; - tilt_filter[1] = conf_tilt_filter_48[1]; - tilt_filter[2] = conf_tilt_filter_48[2]; - tilt_filter[3] = conf_tilt_filter_48[3]; - tilt_len = 12 - 2; - tilt_len_r = 11; - } - - inter_len = MAX(fs, 16000) / 8000; - - /* Init buffers */ - N = xLen; - old_x_len = tilt_len; - old_y_len = ceilf(228.0 * fs / 12800.0) + inter_len; - L_past_x = old_x_len; - move_float(buf_x, mem_old_x, old_x_len); - move_float(&buf_x[old_x_len], x, xLen); - L_past_y = old_y_len; - move_float(buf_y, mem_old_y, old_y_len); - zero_float(&buf_y[old_y_len], xLen); - - N4 = fs * 0.0025; - N34 = N - N4; - - /* Init filter parameters */ - if (mem_param[1] == 1) { - for (i = 0; i < inter_len_r; i++) { - a1[i] = *mem_gain * inter_filter[*mem_pitch_fr][i]; - } - - for (i = 0; i < tilt_len_r; i++) { - b1[i] = conf_alpha * (*mem_gain) * tilt_filter[*mem_beta_idx][i]; - } - - p1 = *mem_pitch_int; - } - - if (param[1] == 1) { - for (i = 0; i < tilt_len_r; i++) { - b2[i] = conf_alpha * gain * tilt_filter[conf_beta_idx][i]; - } - - for (i = 0; i < inter_len_r; i++) { - a2[i] = gain * inter_filter[pitch_fr][i]; - } - - p2 = pitch_int; - } - - /* First quarter of the current frame: cross-fading */ -#ifdef CR9_LTPF_REWRITE - fade_fac = 1. / (LC3_FLOAT) N4; - current_fade_fac_up = 0.f; - current_fade_fac_down = 1.f; - (void) p_x; (void) p_y; (void) p_a1; (void) p_b1; -#endif - - if (mem_param[1] == 0 && param[1] == 0) { - memmove(&buf_y[L_past_y], &buf_x[L_past_x], sizeof(LC3_FLOAT) * N4); - - } else if (mem_param[1] == 1 && param[1] == 0) { - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { - sum1 += b1[j] * buf_x[i]; - j++; - } - - j = 0; - for (i = L_past_y + n - p1 + inter_len - 1; i >= L_past_y + n - p1 - inter_len; i--) { - sum2 += a1[j] * buf_y[i]; - j++; - } - -#ifdef CR9_LTPF_REWRITE - buf_y[L_past_y + n] = buf_x[L_past_x + n] - current_fade_fac_down * sum1 + - current_fade_fac_down * sum2; - current_fade_fac_down -= fade_fac; -#else - buf_y[L_past_y + n] = buf_x[L_past_x + n] - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum1 + - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; -#endif - } - - } else if (mem_param[1] == 0 && param[1] == 1) { - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { - sum1 += b2[j] * buf_x[i]; - j++; - } - - j = 0; - for (i = L_past_y + n - p2 + inter_len - 1; i >= L_past_y + n - p2 - inter_len; i--) { - sum2 += a2[j] * buf_y[i]; - j++; - } - -#ifdef CR9_LTPF_REWRITE - buf_y[L_past_y + n] = buf_x[L_past_x + n] - current_fade_fac_up * sum1 + current_fade_fac_up * sum2; - current_fade_fac_up += fade_fac; -#else - buf_y[L_past_y + n] = buf_x[L_past_x + n] - ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum1 + ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum2; -#endif - } - } else if (*mem_pitch_int == pitch_int && *mem_pitch_fr == pitch_fr) { - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { - sum1 += b2[j] * buf_x[i]; - j++; - } - - j = 0; - for (i = L_past_y + n - p2 + inter_len - 1; i >= L_past_y + n - p2 - inter_len; i--) { - sum2 += a2[j] * buf_y[i]; - j++; - } - - buf_y[L_past_y + n] = buf_x[L_past_x + n] - sum1 + sum2; - } - } else { -#ifdef CR9_LTPF_REWRITE - p_x_init = &buf_x[L_past_x]; - p_y_init = &buf_y[L_past_y - p1 + inter_len - 1]; - p_y2 = &buf_y[L_past_y]; - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - p_b1 = b1; - p_x = p_x_init; - for (i = tilt_len; i >= 0; i--) { - sum1 += *p_b1 * *p_x; - p_b1++; - p_x--; - } - - p_y = p_y_init; - p_a1 = a1; - for (i = 2*inter_len - 1; i >= 0; i--) { - sum2 += *p_a1 * *p_y; - p_a1++; - p_y--; - } - - *p_y2 = *p_x_init - current_fade_fac_down * sum1 + - current_fade_fac_down * sum2; - current_fade_fac_down -= fade_fac; - p_x_init++; - p_y_init++; - p_y2++; - } - - move_float(buf_z, buf_y, (old_y_len + xLen)); - p_x_init = &buf_z[L_past_y]; /* buf z in this case */ - p_y_init = &buf_y[L_past_y - p2 + inter_len - 1]; - p_y2 = &buf_y[L_past_y]; - - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - p_x = p_x_init; - p_b2 = b2; - for (i = tilt_len; i >= 0; i--) { - sum1 += *p_b2 * *p_x; - p_b2++; - p_x--; - } - - p_y = p_y_init; - p_a2 = a2; - for (i = 2*inter_len - 1; i >= 0; i--) { - sum2 += *p_a2 * *p_y; - p_a2++; - p_y--; - } - - *p_y2 = *p_x_init - current_fade_fac_up * sum1 + current_fade_fac_up * sum2; - current_fade_fac_up += fade_fac; - p_x_init++; - p_y_init++; - p_y2++; - } -#else - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { - sum1 += b1[j] * buf_x[i]; - j++; - } - - j = 0; - for (i = L_past_y + n - p1 + inter_len - 1; i >= L_past_y + n - p1 - inter_len; i--) { - sum2 += a1[j] * buf_y[i]; - j++; - } - - buf_y[L_past_y + n] = buf_x[L_past_x + n] - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum1 + - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; - } - - memmove(buf_z, buf_y, sizeof(LC3_FLOAT) * (old_y_len + xLen)); - - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_y + n; i >= L_past_y + n - tilt_len; i--) { - sum1 += b2[j] * buf_z[i]; - j++; - } - - j = 0; - for (i = L_past_y + n - p2 + inter_len - 1; i >= L_past_y + n - p2 - inter_len; i--) { - sum2 += a2[j] * buf_y[i]; - j++; - } - - buf_y[L_past_y + n] = buf_z[L_past_y + n] - ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum1 + ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum2; - } -#endif - } - -#ifdef CR9_LTPF_REWRITE - /* Second quarter of the current frame */ - if (param[1] == 0) { - move_float(&buf_y[L_past_y + N4], &buf_x[L_past_x + N4], - ((L_past_x + N4 + N34) - (L_past_x + N4))); - } else { - p_x_init = &buf_x[L_past_x + N4]; - p_y_init = &buf_y[L_past_y + N4 - p2 + inter_len - 1]; - p_y2 = &buf_y[L_past_y + N4]; - for (n = 0; n < N34; n++) { - sum1 = 0; - sum2 = 0; - p_b2 = b2; - p_x = p_x_init; - - for (i = 0; i <= tilt_len; i++) { - sum1 += *p_b2 * *p_x; - p_b2++; - p_x--; - } - - p_a2 = a2; - p_y = p_y_init; - - for (i = 2*inter_len - 1; i >= 0; i--) { - sum2 += *p_a2 * *p_y; - p_a2++; - p_y--; - } - p_y_init++; - *p_y2 = *p_x_init - sum1 + sum2; - p_x_init++; - p_y2++; - } - } -#else - /* Second quarter of the current frame */ - if (param[1] == 0) { - memmove(&buf_y[L_past_y + N4], &buf_x[L_past_x + N4], - sizeof(LC3_FLOAT) * ((L_past_x + N4 + N34) - (L_past_x + N4))); - } else { - for (n = 0; n < N34; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_x + N4 + n; i >= L_past_x + n + N4 - tilt_len; i--) { - sum1 += b2[j] * buf_x[i]; - j++; - } - - j = 0; - for (i = L_past_y + N4 + n - p2 + inter_len - 1; i >= L_past_y + N4 + n - p2 - inter_len; i--) { - sum2 += a2[j] * buf_y[i]; - j++; - } - - buf_y[L_past_y + N4 + n] = buf_x[L_past_x + N4 + n] - sum1 + sum2; - } - } -#endif - /* Output */ - move_float(y, &buf_y[L_past_y], N); - - /* Update memory */ - move_float(mem_old_x, &buf_x[N], old_x_len); - move_float(mem_old_y, &buf_y[N], old_y_len); - - *mem_ltpf_active = (conf_beta > 0); - } - - /* Update ltpf param memory */ - move_int(mem_param, param, 3); - *mem_pitch_int = pitch_int; - *mem_pitch_fr = pitch_fr; - *mem_gain = gain; - *mem_beta_idx = conf_beta_idx; -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - if (bfi == 0 && hrmode == 1 && (frame_dms == 50 || frame_dms == 25)){ - pitch_delta = LC3_FABS(pitch_fl_c_old - (LC3_FLOAT)pitch_int - (LC3_FLOAT)(pitch_fr / 4.0)); - *rel_pitch_change = pitch_delta / MAX(pitch_fl_c_old, 1); - } -#endif - -#ifdef WMOPS - pop_wmops(); -#endif -} diff --git a/lib_lc3plus/ltpf_decoder_fx.c b/lib_lc3plus/ltpf_decoder_fx.c new file mode 100644 index 000000000..3bc82085e --- /dev/null +++ b/lib_lc3plus/ltpf_decoder_fx.c @@ -0,0 +1,394 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +static void ltpf_synth_filter(Word16 *synth_ltp, Word16 *synth, Word16 length, Word16 pitch_int, Word16 pitch_fr, + Word16 gain, Word16 scale_fac_idx, Word16 fs_idx, + Word16 fade /* 0=normal, +1=fade-in, -1=fade-out */); + +/*************************************************************************/ + + +void process_ltpf_decoder_fx(Word16 *x_e, Word16 L_frame, Word16 old_x_len, Word16 fs_idx, Word16 old_y_len, + Word16 *old_e, Word16 *x_in, Word16 *old_x, Word16 *y_out, Word16 *old_y, Word16 ltpf, + Word16 ltpf_active, Word16 pitch_index, Word16 *old_pitch_int, Word16 *old_pitch_fr, + Word16 *old_gain, Word16 *mem_ltpf_active, Word16 scale_fac_idx, Word16 bfi, + Word16 concealMethod, + Word16 damping, Word16 *old_scale_fac_idx, +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 *rel_pitch_change, Word16 hrmode, Word16 frame_dms, +#endif + Word8 *scratchBuffer) +{ + Counter i; + Word16 gain, s, s0, s1, pitch, pitch_int, pitch_fr, N4, N34; + Word16 *x, *y; + Word16 *z; +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 tmp32, pitch_delta; +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("process_ltpf_decoder_fx", sizeof(struct { + Counter i; + Word16 gain, s, s0, s1, pitch, pitch_int, pitch_fr, N4, N34; + Word16 *x, *y; + Word16 *z; +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 tmp32, pitch_delta; +#endif + })); +#endif + + z = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = MAX_LEN / 4 + 10 */ + + + test(); + IF ((sub(bfi, 1) == 0) && (sub(concealMethod, LC3_CON_TEC_NS_STD) == 0)) + { + ltpf = 0; move16(); + ltpf_active = 0; move16(); + pitch_int = 0; move16(); + pitch_fr = 0; move16(); + gain = 0; move16(); + } + + /* Filter parameters */ + IF (sub(bfi, 1) != 0) + { + IF (ltpf == 0) + { + pitch_int = 0; move16(); + pitch_fr = 0; move16(); + } + ELSE + { + /* Decode pitch */ + IF (sub(pitch_index, 380) < 0) + { + pitch_int = shr_pos(add(pitch_index, 64), 2); + pitch_fr = add(sub(pitch_index, shl_pos(pitch_int, 2)), 128); + } + ELSE IF (sub(pitch_index, 440) < 0) + { + pitch_int = shr_pos(sub(pitch_index, 126), 1); + pitch_fr = sub(sub(shl_pos(pitch_index, 1), shl_pos(pitch_int, 2)), 252); + } + ELSE + { + pitch_int = sub(pitch_index, 283); + pitch_fr = 0; move16(); + } + pitch = add(shl_pos(pitch_int, 2), pitch_fr); +#ifdef ENABLE_HR_MODE + IF (sub(fs_idx, 5) == 0) + { + pitch = round_fx(L_shl_pos(L_mult(shl_pos(pitch, 2), pitch_scale[4]), 1)); + } + ELSE +#endif + { + pitch = mult_r(shl_pos(pitch, 2), pitch_scale[fs_idx]); + } + pitch_int = shr_pos(pitch, 2); + pitch_fr = sub(pitch, shl_pos(pitch_int, 2)); + } + + /* Decode gain */ + if (scale_fac_idx < 0) + { + ltpf_active = 0; + ASSERT(!(*old_scale_fac_idx < 0 && *mem_ltpf_active == 1)); + } + IF (ltpf_active == 0) + { + gain = 0; move16(); + } + ELSE + { + ASSERT(scale_fac_idx >= 0); + gain = gain_scale_fac[scale_fac_idx]; move16(); + } + } + ELSE IF (sub(concealMethod, LC3_CON_TEC_NS_STD) != 0) + { + /* fix to avoid not initialized filtering for concelament + might be necessary in case of bit errors or rate switching */ + if (scale_fac_idx < 0) { + if (*mem_ltpf_active && *old_scale_fac_idx>=0) + { + scale_fac_idx = *old_scale_fac_idx; + } + } + + ltpf_active = *mem_ltpf_active; move16(); + + if ((sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0)) + { /* always start fade off to save filtering WMOPS for the remaining 7.5 ms */ + assert(bfi == 1); + ltpf_active = 0; move16(); /*always start fade off , still maintain *mem_ltpf_active */ + } + + pitch_int = *old_pitch_int; + pitch_fr = *old_pitch_fr; + gain = mult_r(*old_gain, damping); + } + + test(); test(); + IF (ltpf_active == 0 && *mem_ltpf_active == 0) + { + /* LTPF inactive */ + + basop_memmove(y_out, x_in, L_frame * sizeof(Word16)); + + /* Update */ + s = sub(*old_e, *x_e); + IF (s > 0) + { + basop_memmove(old_y, &old_y[L_frame], (old_y_len - L_frame) * sizeof(Word16)); + + IF (sub(s, 15) > 0) + { + basop_memset(&old_y[old_y_len - L_frame], 0, (L_frame) * sizeof(Word16)); + + basop_memset(old_x, 0, (old_x_len) * sizeof(Word16)); + } + ELSE + { + FOR (i = 0; i < L_frame; i++) + { + old_y[i + old_y_len - L_frame] = shr(x_in[i], s); move16(); + } + FOR (i = 0; i < old_x_len; i++) + { + old_x[i] = shr(x_in[i + L_frame - old_x_len], s); move16(); + } + } + } + ELSE + { + IF (sub(s, -15) < 0) + { + basop_memset(old_y, 0, (old_y_len - L_frame) * sizeof(Word16)); + } + ELSE + { + FOR (i = 0; i < old_y_len - L_frame; i++) + { + old_y[i] = shl(old_y[i + L_frame], s); move16(); + } + } + + basop_memmove(&old_y[old_y_len - L_frame], x_in, (L_frame) * sizeof(Word16)); + + basop_memmove(old_x, &x_in[L_frame - old_x_len], (old_x_len) * sizeof(Word16)); + + *old_e = *x_e; move16(); + } + +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + if (bfi == 0 && sub(hrmode,1) == 0 && (sub(frame_dms,50) == 0 || sub(frame_dms,25) == 0)){ + pitch_delta = abs_s(add(sub(*old_pitch_int,pitch_int) , shr_pos(sub(*old_pitch_fr, pitch_fr),2))); //int_old -int_new + (fr_old-fr_new) / 4.0)); + tmp32 = BASOP_Util_Divide3216_Scale_lc3plus(pitch_delta, MAX(add(*old_pitch_int, shr_pos(*old_pitch_fr,2)), 1),&s0);// = pitch_delta *2^15 / MAX(pitch_fl_c_old, 1); + *rel_pitch_change = L_shl_pos(tmp32,s0+16); + } +#endif + + *old_pitch_int = pitch_int; move16(); + *old_pitch_fr = pitch_fr; move16(); + *old_gain = 0; move16(); + *mem_ltpf_active = 0; move16(); + } + ELSE + { + /* Input/Output buffers */ + x = old_x + old_x_len; + y = old_y + old_y_len; + +#ifdef ENABLE_HR_MODE + assert(fs_idx < 5 && "Ltpf not supported for 96kHz!\n"); +#endif + + N4 = ltpf_overlap_len[fs_idx]; move16(); + N34 = sub(L_frame, N4); move16(); + + /* Input */ + basop_memmove(x, x_in, (L_frame) * sizeof(Word16)); + + /* Scaling */ + s0 = sub(s_min(getScaleFactor16_0(old_x, old_x_len), getScaleFactor16_0(old_y, old_y_len)), 1); + *old_e = sub(*old_e, s0); move16(); + s1 = sub(getScaleFactor16(x, L_frame), 1); + *x_e = sub(*x_e, s1); move16(); + s = sub(*old_e, *x_e); + IF (s > 0) + { + Scale_sig(x, L_frame, sub(s1, s)); + Scale_sig(old_x, old_x_len, s0); + Scale_sig(old_y, old_y_len, s0); + *x_e = *old_e; move16(); + } + ELSE + { + Scale_sig(x, L_frame, s1); + Scale_sig(old_x, old_x_len, add(s0, s)); + Scale_sig(old_y, old_y_len, add(s0, s)); + *old_e = *x_e; move16(); + } + + /* Filtering */ + IF (ltpf_active == 0) + { + ltpf_synth_filter(y, x, N4, *old_pitch_int, *old_pitch_fr, *old_gain, *old_scale_fac_idx, fs_idx, + -1); + } + ELSE IF (*mem_ltpf_active == 0) + { + ltpf_synth_filter(y, x, N4, pitch_int, pitch_fr, gain, scale_fac_idx, fs_idx, 1); + } + ELSE IF (sub(pitch_int, *old_pitch_int) == 0 && sub(*old_pitch_fr, pitch_fr) == 0) + { + ltpf_synth_filter(y, x, N4, pitch_int, pitch_fr, gain, scale_fac_idx, fs_idx, 0); + } + ELSE + { + ltpf_synth_filter(y, x, N4, *old_pitch_int, *old_pitch_fr, *old_gain, *old_scale_fac_idx, fs_idx, + -1); + basop_memmove(z, y - tilt_filter_len[fs_idx], (N4 + tilt_filter_len[fs_idx]) * sizeof(Word16)); + ltpf_synth_filter(y, z + tilt_filter_len[fs_idx], N4, pitch_int, pitch_fr, gain, scale_fac_idx, + fs_idx, 1); + } + IF (ltpf_active > 0) + { + ltpf_synth_filter(y + N4, x + N4, N34, pitch_int, pitch_fr, gain, + scale_fac_idx, fs_idx, 0); + } + ELSE + { + basop_memmove(&y[N4], &x[N4], N34 * sizeof(Word16)); + } + + /* Output */ + basop_memmove(y_out, y, (L_frame) * sizeof(Word16)); + + /* Update */ + basop_memmove(old_x, &old_x[L_frame], (old_x_len) * sizeof(Word16)); + + basop_memmove(old_y, &old_y[L_frame], (old_y_len) * sizeof(Word16)); + + *old_pitch_int = pitch_int; move16(); + *old_pitch_fr = pitch_fr; move16(); + *old_gain = gain; move16(); + *mem_ltpf_active = ltpf_active; move16(); + } + + *old_scale_fac_idx = scale_fac_idx; move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + +static void ltpf_synth_filter(Word16 *synth_ltp, Word16 *synth, Word16 length, Word16 pitch_int, Word16 pitch_fr, + Word16 gain, Word16 scale_fac_idx, Word16 fs_idx, + Word16 fade /* 0=normal, +1=fade-in, -1=fade-out */) +{ + Word16 *x0; + Word16 *y0; + Word32 s; + Word16 alpha, step; + Word16 i, k; + Counter j, l; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("ltpf_synth_filter", sizeof(struct { + Word16 *x0; + Word16 *y0; + Word32 s; + Word16 alpha, step; + Word16 i, k; + Counter j, l; + })); +#endif + + ASSERT(scale_fac_idx >= 0); + + step = 0; /* initialize just to avoid compiler warning */ + alpha = 0; /* initialize just to avoid compiler warning */ + x0 = &synth_ltp[-pitch_int + inter_filter_shift[fs_idx]]; + y0 = synth; + + alpha = 0; move16(); + IF (fade != 0) + { + if (fade < 0) + { + alpha = 0x7FFF; move16(); + } + +/* step = 1.f/(float)(length); */ + if (sub(length, 20) == 0) + { + step = 1638 /*1.f/20.f Q15*/; move16(); + } + if (sub(length, 40) == 0) + { + step = 819 /*1.f/40.f Q15*/; move16(); + } + if (sub(length, 60) == 0) + { + step = 546 /*1.f/60.f Q15*/; move16(); + } + if (sub(length, 80) == 0) + { + step = 409 /*1.f/80.f Q15*/; move16(); + } + if (sub(length, 120) == 0) + { + step = 273 /*1.f/120.f Q15*/; move16(); + } + + if (fade < 0) + step = negate(step); + } + + FOR (j = 0; j < length; j++) + { + s = L_mult(x0[0], inter_filter[fs_idx][pitch_fr][0]); + FOR (l = 1; l < inter_filter_len[fs_idx]; l++) + { + s = L_mac(s, x0[-l], inter_filter[fs_idx][pitch_fr][l]); + } + FOR (l = 0; l < tilt_filter_len[fs_idx]; l++) + { + s = L_msu(s, y0[-l], tilt_filter[fs_idx][scale_fac_idx][l]); + } + + i = msu_r(s, y0[-l], tilt_filter[fs_idx][scale_fac_idx][l]); + + k = mult_r(gain, i); + + if (fade != 0) + k = mult_r(k, alpha); + + synth_ltp[j] = add(synth[j], k); move16(); + + if (fade != 0) + alpha = add(alpha, step); + + x0++; + y0++; + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/makefile b/lib_lc3plus/makefile new file mode 100644 index 000000000..d86232d67 --- /dev/null +++ b/lib_lc3plus/makefile @@ -0,0 +1,180 @@ +#****************************************************************************** +# ETSI TS 103 634 V1.4.5 * +# Low Complexity Communication Codec Plus (LC3plus) * +# * +# Copyright licence is solely granted through ETSI Intellectual Property * +# Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +# estoppel or otherwise. * +#*****************************************************************************/ + +# Options +AFL = 0 +GCOV = 0 +NO_POST_REL_CHANGES_TEST = 0 +OPTIM = 0 +SUBSET = ALL +WMOPS = 1 +HR = 1 +CLANG = 0 +SHORT_PLC_FADEOUT = 0 + +# Paths +VPATH = . basic_op +BUILD = build +CC = gcc +LINK = $(CC) + +# Binary Name +NAME_LC3 = LC3plus +# Shared Library Name +LIB_LC3 = libLC3plus.so + +# Default tool settings +RM = rm -f + +ifndef VERBOSE +QUIET_CC = @echo ' ' Compiling $<; +QUIET_LINK= @echo ' ' Linking $@; +QUIET = @ +endif + +# C compiler flags +# Preprocessor(-I/-D) / Compiler / Linker flags +CPPFLAGS += -Ibasic_op -DSUBSET_$(SUBSET) +CFLAGS += -std=c99 -fPIC \ + -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long \ + -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \ + -Werror-implicit-function-declaration + +ifneq "$(DEBUG)" "0" +CFLAGS += -g3 +LDFLAGS += -g3 +endif + +ifeq "$(HR)" "0" +CFLAGS += -DDISABLE_HR_MODE +endif + +ifeq "$(SHORT_PLC_FADEOUT)" "1" +CFLAGS += -DPLC_TUNING_SHORT_FADEOUT +endif + +# memory sanitizer, find use of uninitialized memory +ifeq "$(CLANG)" "1" + CC = clang + CFLAGS += -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer + LDFLAGS += -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer + OPTIM = 2 +endif + +# address sanitizer, find buffer overflows +ifeq "$(CLANG)" "2" + CC = clang + CFLAGS += -fsanitize=address -fno-omit-frame-pointer + LDFLAGS += -fsanitize=address -fno-omit-frame-pointer + OPTIM = 2 +endif + +# undefined behavior sanitizer, find bugs like integer overflows +ifeq "$(CLANG)" "3" + CC = clang + CFLAGS += -fsanitize=undefined + LDFLAGS += -fsanitize=undefined + OPTIM = 2 +endif + +LDFLAGS += -lm + +DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD)/$*.Td + +ifeq "$(GCOV)" "1" +CFLAGS += -fprofile-arcs -ftest-coverage +LDFLAGS += -fprofile-arcs -ftest-coverage +endif + +OPTIM ?= 0 +CFLAGS += -O$(OPTIM) + +CFLAGS += $(foreach DIR,$(SRC_DIRS),-I$(DIR)) + +ifeq "$(NO_POST_REL_CHANGES_TEST)" "1" +CFLAGS += -DNO_POST_REL_CHANGES +endif + +# disable wmops instrumentation +ifeq "$(WMOPS)" "0" + CPPFLAGS += -DWMOPS=0 -DDONT_COUNT_MEM +endif + +# dependency magic +CC_FLAGS = '$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)' +POSTCOMPILE = mv -f $(BUILD)/$*.Td $(BUILD)/$*.d && touch $@ + +############################################################################### + +SRCS := $(notdir $(foreach DIR, $(VPATH), $(wildcard $(DIR)/*.c))) + +EXCL := ccConvert.c +SRCS := $(notdir $(foreach DIR, $(VPATH), $(wildcard $(DIR)/*.c))) +SRCS := $(filter-out $(EXCL), $(SRCS)) + +EXCL_CCC := $(BUILD)/codec_exe.o +OBJS_CCC_UNF := $(addprefix $(BUILD)/, $(SRCS:.c=.o)) +OBJS_CCC := $(filter-out $(EXCL_CCC), $(OBJS_CCC_UNF)) + +OBJS := $(addprefix $(BUILD)/, $(SRCS:.c=.o)) + +LIBSRCS := $(filter-out $(DIR)/ccConvert.c $(DIR)/codec_exe.c, $(SRCS)) +LIBOBJS := $(addprefix $(BUILD)/, $(LIBSRCS:.c=.o)) + +############################################################################### + +.PHONY: all clean help force + +all: $(NAME_LC3) + +help: + @echo 'Targets:' + @echo ' $(NAME_LC3) (default)' + @echo ' $(LIB_LC3)' + @echo ' ccConvert' + @echo 'Syntax: make [OPTION=VALUE ...]' + @echo 'Build options:' + @echo ' NO_POST_REL_CHANGES_TEST $(NO_POST_REL_CHANGES_TEST) [0,1]' + @echo ' OPTIM $(OPTIM) [0-3]' + @echo ' SUBSET $(SUBSET) [NB,WB,SSWB,SWB,FB,UB,ALL]' + @echo ' WMOPS $(WMOPS) [0,1]' + @echo ' SHORT_PLC_FADEOUT $(SHORT_PLC_FADEOUT) [0,1]' + @echo 'Debug options:' + @echo ' AFL $(AFL) [0,1]' + @echo ' CLANG $(CLANG) [0-3]' + @echo ' GCOV $(GCOV) [0,1]' + +$(NAME_LC3): $(OBJS) + @echo 'Linking' $@ + $(QUIET) $(LINK) $(OBJS) -o $@ $(LDFLAGS) + +$(LIB_LC3): $(LIBOBJS) + @echo 'Linking' $@ + $(QUIET) $(LINK) --shared $(OBJS) -o $@ $(LDFLAGS) + +ccConvert: $(BUILD)/ccConvert.o $(OBJS_CCC) + @echo 'Linking' $@ + $(QUIET) $(LINK) $? -o $@ $(LDFLAGS) + +clean: + $(QUIET) rm -rf $(NAME_LC3) $(LIB_LC3) $(BUILD) ccConvert + +$(BUILD)/%.o : %.c $(BUILD)/cc_flags + @echo 'Compiling' $< + $(QUIET) $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + $(QUIET) $(POSTCOMPILE) + +# force rebuild if compilation flags changed +$(BUILD)/cc_flags: force + $(QUIET) mkdir -p $(BUILD) + $(QUIET) echo $(CC_FLAGS) | cmp -s - $@ || echo $(CC_FLAGS) > $@ + +# force rebuild if include dependency changed +$(BUILD)/%.d: ; +include $(wildcard $(patsubst %, $(BUILD)/%.d, $(basename $(SRCS)))) diff --git a/lib_lc3plus/mdct.c b/lib_lc3plus/mdct.c deleted file mode 100644 index ef2d7c087..000000000 --- a/lib_lc3plus/mdct.c +++ /dev/null @@ -1,157 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT hrmode) -{ - if (frame_dms == 100) { - switch (length) { - case 80: - return MDCT_WINS_10ms[hrmode][0]; - case 160: - return MDCT_WINS_10ms[hrmode][1]; - case 240: - return MDCT_WINS_10ms[hrmode][2]; - case 320: - return MDCT_WINS_10ms[hrmode][3]; - case 480: - return MDCT_WINS_10ms[hrmode][4]; - case 960: - return MDCT_WINS_10ms[hrmode][5]; - default: - return NULL; - } - } -#ifdef CR8_G_ADD_75MS - else if (frame_dms == 75) { - switch (length) { - case 60: - return MDCT_WINS_7_5ms[hrmode][0]; - case 120: - return MDCT_WINS_7_5ms[hrmode][1]; - case 180: - return MDCT_WINS_7_5ms[hrmode][2]; - case 240: - return MDCT_WINS_7_5ms[hrmode][3]; - case 360: - return MDCT_WINS_7_5ms[hrmode][4]; - case 720: - return MDCT_WINS_7_5ms[hrmode][5]; - default: - return NULL; - } - } -#endif - else if (frame_dms == 50) { - switch (length) { - case 40: - return MDCT_WINS_5ms[hrmode][0]; - case 80: - return MDCT_WINS_5ms[hrmode][1]; - case 120: - return MDCT_WINS_5ms[hrmode][2]; - case 160: - return MDCT_WINS_5ms[hrmode][3]; - case 240: - return MDCT_WINS_5ms[hrmode][4]; - case 480: - return MDCT_WINS_5ms[hrmode][5]; - default: - return NULL; - } - } - else if (frame_dms == 25) { - switch (length) { - case 20: - return MDCT_WINS_2_5ms[hrmode][0]; - case 40: - return MDCT_WINS_2_5ms[hrmode][1]; - case 60: - return MDCT_WINS_2_5ms[hrmode][2]; - case 80: - return MDCT_WINS_2_5ms[hrmode][3]; - case 120: - return MDCT_WINS_2_5ms[hrmode][4]; - case 240: - return MDCT_WINS_2_5ms[hrmode][5]; - default: - return NULL; - } - } - return NULL; -} - -void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC3_INT hrmode) -{ - if (frame_dms == 100) { - mdct->leading_zeros = MDCT_la_zeroes[fs_idx]; - } -#ifdef CR8_G_ADD_75MS - else if (frame_dms == 75) { - mdct->leading_zeros = MDCT_la_zeroes_7_5ms[fs_idx]; - } -#endif - else if (frame_dms == 50) { - mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx]; - } - else if (frame_dms == 25) { - mdct->leading_zeros = MDCT_la_zeroes_2_5ms[fs_idx]; - } - else { - assert(!"invalid frame_ms"); - } - - mdct->length = length; - mdct->mem_length = length - mdct->leading_zeros; - mdct->window = mdct_window(length, frame_dms, hrmode); - mdct->mem = calloc(sizeof(*mdct->mem), mdct->mem_length); - dct4_init(&mdct->dct, length); -} - -void mdct_free(Mdct* mdct) -{ - if (mdct) { - free(mdct->mem); - dct4_free(&mdct->dct); - memset(mdct, 0, sizeof(*mdct)); - } -} - -void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct) -{ - LC3_FLOAT tmp[MAX_LEN * 2]; - LC3_INT i; - LC3_INT hlen; - - move_float(tmp, mdct->mem, mdct->mem_length); - move_float(tmp + mdct->mem_length, input, mdct->length); - zero_float(tmp + mdct->length * 2 - mdct->leading_zeros, mdct->leading_zeros); - move_float(mdct->mem, tmp + mdct->length, mdct->mem_length); - - mult_vec(tmp, mdct->window, mdct->length * 2); - - hlen = mdct->length / 2; - for (i = 0; i < hlen; i++) { - output[i] = -tmp[hlen * 3 - i - 1] - tmp[hlen * 3 + i]; - output[hlen + i] = tmp[i] - tmp[hlen * 2 - i - 1]; - } - - move_float(tmp, output, mdct->length); - - dct4_apply(&mdct->dct, tmp, output); -} - -void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct) -{ - mdct_apply(in, out, mdctStruct); -} diff --git a/lib_lc3plus/mdct_fx.c b/lib_lc3plus/mdct_fx.c new file mode 100644 index 000000000..9e9157204 --- /dev/null +++ b/lib_lc3plus/mdct_fx.c @@ -0,0 +1,223 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +/* Union holding buffers to conserve stack memory. */ + +void processMdct_fx( +#ifdef ENABLE_HR_MODE + Word32 x[], /* i: time input signal */ +#else + Word16 x[], /* i: time input signal */ +#endif + Word16 x_exp, Word16 N, /* i: block size N */ +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION +# ifdef ENABLE_HR_MODE + Word16 hrmode, /* i: indicate high precision */ +# endif +#endif +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#endif + Word16 wLen, /* i: window length */ +#ifdef ENABLE_HR_MODE + Word32 mem[], /* i/o: last block of input samples */ +#else + Word16 mem[], /* i/o: last block of input samples */ +#endif + Word16 memLen, /* i: length of last sample block */ + Word32 y[], /* o: spectral data */ + Word16 * y_e, /* o: spectal data exponent */ + Word8 * scratchBuffer) +{ + Counter i; + Word16 z, s, m; +#ifdef ENABLE_HR_MODE + Word32 *buf; +#else + Word16 *buf; +#endif + Word32 *workBuffer; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processMdct_fx", sizeof(struct { + Counter i; + Word16 z, s, m; + Word16 *buf; + Word32 *workBuffer; + })); +#endif + + /* Buffers overlap since they are not used at the same time */ +#ifdef ENABLE_HR_MODE + buf = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */ +#else + buf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */ +#endif + workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN */ + + /* Init (constant per sample rate) */ + z = (N << 1) - wLen; /* number of leading zeros in window */ + m = N >> 1; /* half block size */ + +#ifdef ENABLE_HR_MODE + basop_memmove(buf, mem, memLen * sizeof(Word32)); + + basop_memmove(&buf[memLen], x, (N - memLen) * sizeof(Word32)); + + basop_memmove(mem, &x[N - memLen], memLen * sizeof(Word32)); +#else + basop_memmove(buf, mem, memLen * sizeof(Word16)); + + basop_memmove(&buf[memLen], x, (N - memLen) * sizeof(Word16)); + + basop_memmove(mem, &x[N - memLen], memLen * sizeof(Word16)); +#endif + +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + +# ifdef ENABLE_HR_MODE + if (hrmode) + { + FOR (i = 0; i < m; i++) + { + y[m + i] = Msu_32_32_0(Mpy_32_32_0(w[i], buf[i]), w[2 * m - 1 - i], buf[2 * m - 1 - i]); move32(); + } + + FOR (i = 0; i < z; i++) + { + y[m - 1 - i] = Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]); move32(); + } + + FOR (i = i; i < m; i++) + { + y[m - 1 - i] = Mac_32_32_0(Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]), w[4 * m - 1 - i], x[4 * m - memLen - 1 - i]); move32(); + } + } else { +# ifdef CR9_B_FIX_MDCT_OVERFLOW + FOR (i = 0; i < m; i++) + { + y[m + i] = L_msu0(L_mult0(round_fx_sat(buf[i]), round_fx(w[i])), round_fx_sat(buf[2 * m - 1 - i]), round_fx(w[2 * m - 1 - i])); move32(); + } + + FOR (i = 0; i < z; i++) + { + y[m - 1 - i] = L_mult0(round_fx_sat(x[2 * m - memLen + i]), round_fx(w[2 * m + i])); move32(); + } + + FOR (i = i; i < m; i++) + { + y[m - 1 - i] = L_mac0(L_mult0(round_fx_sat(x[2 * m - memLen + i]), round_fx(w[2 * m + i])), round_fx_sat(x[4 * m - memLen - 1 - i]), + round_fx(w[4 * m - 1 - i])); move32(); + } +# else /* CR9_B_FIX_MDCT_OVERFLOW */ + FOR (i = 0; i < m; i++) + { + y[m + i] = L_msu0(L_mult0(round_fx(buf[i]), round_fx(w[i])), round_fx(buf[2 * m - 1 - i]), round_fx(w[2 * m - 1 - i])); move32(); + } + + FOR (i = 0; i < z; i++) + { + y[m - 1 - i] = L_mult0(round_fx(x[2 * m - memLen + i]), round_fx(w[2 * m + i])); move32(); + } + + FOR (i = i; i < m; i++) + { + y[m - 1 - i] = L_mac0(L_mult0(round_fx(x[2 * m - memLen + i]), round_fx(w[2 * m + i])), round_fx(x[4 * m - memLen - 1 - i]), + round_fx(w[4 * m - 1 - i])); move32(); + } +# endif /* CR9_B_FIX_MDCT_OVERFLOW */ + } +# else + /* regular resolution only */ + FOR (i = 0; i < m; i++) + { + y[m + i] = L_msu0(L_mult0(buf[i], w[i]), buf[2 * m - 1 - i], w[2 * m - 1 - i]); move32(); + } + + FOR (i = 0; i < z; i++) + { + y[m - 1 - i] = L_mult0(x[2 * m - memLen + i], w[2 * m + i]); move32(); + } + + FOR (i = i; i < m; i++) + { + y[m - 1 - i] = L_mac0(L_mult0(x[2 * m - memLen + i], w[2 * m + i]), x[4 * m - memLen - 1 - i], + w[4 * m - 1 - i]); move32(); + } +# endif + +#else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + + FOR (i = 0; i < m; i++) + { +# ifdef ENABLE_HR_MODE + y[m + i] = Msu_32_32_0(Mpy_32_32_0(w[i], buf[i]), w[2 * m - 1 - i], buf[2 * m - 1 - i]); move32(); +# else + y[m + i] = L_msu0(L_mult0(buf[i], w[i]), buf[2 * m - 1 - i], w[2 * m - 1 - i]); move32(); +# endif + } + + FOR (i = 0; i < z; i++) + { +# ifdef ENABLE_HR_MODE + y[m - 1 - i] = Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]); move32(); +# else + y[m - 1 - i] = L_mult0(x[2 * m - memLen + i], w[2 * m + i]); move32(); +# endif + } + + FOR (i = i; i < m; i++) + { +# ifdef ENABLE_HR_MODE + y[m - 1 - i] = Mac_32_32_0(Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]), w[4 * m - 1 - i], x[4 * m - memLen - 1 - i]); move32(); +# else + y[m - 1 - i] = L_mac0(L_mult0(x[2 * m - memLen + i], w[2 * m + i]), x[4 * m - memLen - 1 - i], + w[4 * m - 1 - i]); move32(); +# endif + } + +#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + + s = s_max(0, getScaleFactor32_lc3plus(y, N)); + FOR (i = 0; i < N; i++) + { + y[i] = L_shl(y[i], s); move32(); + } + + *y_e = sub(sub(x_exp, 2), s); + + /* N=20 only for 2.5ms possible */ + /* maybe implement this a pre init of shift */ + if (sub(N, 20) <= 0) + { + *y_e = add(*y_e, 2); + } + else if (sub(N, 120) <= 0) + { + *y_e = add(*y_e, 1); + } +#ifdef ENABLE_HR_MODE + dct_IV(y, y_e, N, +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + hrmode, +# endif + workBuffer); +#else + dct_IV(y, y_e, N, workBuffer); +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/mdct_shaping_fx.c b/lib_lc3plus/mdct_shaping_fx.c new file mode 100644 index 000000000..3b36265fd --- /dev/null +++ b/lib_lc3plus/mdct_shaping_fx.c @@ -0,0 +1,74 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void processMdctShaping_fx(Word32 x[], +#ifdef ENABLE_HR_MODE + Word32 scf[], +#else + Word16 scf[], +#endif + Word16 scf_exp[], const Word16 bands_offset[], Word16 fdns_npts) +{ + Counter i, j; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processMdctShaping_fx", sizeof(struct { Counter i, j; })); +#endif + + j = 0; move16(); + FOR (i = 0; i < fdns_npts; i++) + { + FOR (; j < bands_offset[i + 1]; j++) + { +#ifdef ENABLE_HR_MODE + x[j] = L_shl(Mpy_32_32_lc3plus(x[j], scf[i]), scf_exp[i]); move32(); +#else + x[j] = L_shl(Mpy_32_16_lc3plus(x[j], scf[i]), scf_exp[i]); move32(); +#endif + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + +void processScfScaling(Word16 scf_exp[], Word16 fdns_npts, Word16 *x_e) +{ + Counter i; + Word16 scf_exp_max; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processLpcGainScaling", sizeof(struct { + Counter i; + Word16 scf_exp_max; + })); +#endif + + scf_exp_max = scf_exp[0]; move16(); + + FOR (i = 1; i < fdns_npts; i++) + { + scf_exp_max = s_max(scf_exp_max, scf_exp[i]); + } + + FOR (i = 0; i < fdns_npts; i++) + { + scf_exp[i] = sub(scf_exp[i], scf_exp_max); move16(); + } + + *x_e = add(*x_e, scf_exp_max); move16(); +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/near_nyquist_detector.c b/lib_lc3plus/near_nyquist_detector.c deleted file mode 100644 index ee34361ef..000000000 --- a/lib_lc3plus/near_nyquist_detector.c +++ /dev/null @@ -1,93 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, - const LC3_INT bands_number, const LC3_FLOAT* ener -#ifdef CR8_E_TONE_DETECTOR - , const LC3_INT16 frame_dms, const LC3_INT16 hrmode -#endif -) -{ - *near_nyquist_flag = 0; -#ifdef CR8_E_TONE_DETECTOR - if (hrmode == 0) -#endif - { - if (fs_idx < 4) - { - LC3_INT i = 0; - LC3_FLOAT ener_low = FLT_EPSILON, ener_high = 0; - - for (i=0; i NN_thresh * ener_low){ - *near_nyquist_flag = 1; - } - } - } -#ifdef CR8_E_TONE_DETECTOR - else // hrmode == 1 - { - // inverse spectral flatness = mean(energy) ./ 2^(mean(log2(energy))); - LC3_INT32 td_thresh, i = 0; - LC3_FLOAT mean_ener = 0, mean_ener_log2 = 0, inv_flatness = 0; - - switch (frame_dms) - { - case 25: - td_thresh = TD_HR_thresh_2_5ms; - break; - case 50: - td_thresh = TD_HR_thresh_5ms; - break; - case 75: - td_thresh = TD_HR_thresh_7_5ms; - break; - default: /* 100 */ - td_thresh = TD_HR_thresh_10ms; - break; - } - - // calculate arithmetic mean - for (i = 0; i < bands_number; i++) - { - mean_ener += ener[i]; - } - mean_ener = mean_ener / bands_number; - - // calculate geometric mean - for (i = 0; i < bands_number; i++) - { - if (ener[i] != 0) { - mean_ener_log2 += LC3_LOGTWO(ener[i]); - } - } - mean_ener_log2 = mean_ener_log2 / bands_number; - - inv_flatness = mean_ener / LC3_POW(2,mean_ener_log2); - - if (inv_flatness > td_thresh) { - *near_nyquist_flag = 1; - } - } -#endif // CR8_E_TONE_DETECTOR -} diff --git a/lib_lc3plus/near_nyquist_detector_fx.c b/lib_lc3plus/near_nyquist_detector_fx.c new file mode 100644 index 000000000..8ae29cbb8 --- /dev/null +++ b/lib_lc3plus/near_nyquist_detector_fx.c @@ -0,0 +1,141 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void processNearNyquistdetector_fx(Word16 *near_nyquist_flag, const Word16 fs_idx, const Word16 near_nyquist_index, + const Word16 bands_number, const Word32 *ener_fx, const Word16 ener_fx_exp +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + ,Word16 frame_dms, Word16 hrmode) +#else + ) +#endif +#else + ) +#endif +{ + *near_nyquist_flag = 0; +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + IF (hrmode == 0){ +#endif +#endif + IF (sub(fs_idx, 4) < 0) + { + Dyn_Mem_Deluxe_In( + Word16 i; + Word16 nrg_above_thresh; + Word16 ener_low_exp; + Word16 ener_high_exp; + Word16 comp_energy_exp; + Word32 comp_energy; + Word32 ener_low; + Word32 ener_high; + ); + + ener_low = 0; move32(); + ener_low_exp = 0; move16(); + FOR (i = 0; i < near_nyquist_index; i++) + { + ener_low = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, ener_low, ener_low_exp, &ener_low_exp); + } + + ener_high = 0; move32(); + ener_high_exp = 0; move16(); + FOR (i = near_nyquist_index; i < bands_number; i++) + { + ener_high = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, ener_high, ener_high_exp, &ener_high_exp); + } + + comp_energy = Mpy_32_16_lc3plus(ener_low, NN_thresh); /* Mpy_32_16_lc3plus -> 32Q15 */ + comp_energy_exp = add(add(ener_low_exp, NN_thresh_exp),15); + + nrg_above_thresh = BASOP_Util_Cmp_Mant32Exp_lc3plus(ener_high, ener_high_exp, comp_energy, comp_energy_exp); /* 1 if firstNumber > secondNumber */ + + if (sub(nrg_above_thresh, 1) == 0) + { + *near_nyquist_flag = 1; + } + + Dyn_Mem_Deluxe_Out(); + } +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + } + ELSE // hrmode == 1 + { + // inverse spectral flatness = mean(energy) ./ 2^(mean(log2(energy))); + Word32 td_thresh; + + SWITCH (frame_dms) + { + case 25: + td_thresh = TD_HR_thresh_2_5ms; + BREAK; + case 50: + td_thresh = TD_HR_thresh_5ms; + BREAK; + #ifdef ENABLE_075_DMS_MODE + case 75: + td_thresh = TD_HR_thresh_7_5ms; + BREAK; + #endif + default: /* 100 */ + td_thresh = TD_HR_thresh_10ms; + BREAK; + } + + Word16 mean_ener_exp = 0; + + Word32 sum_ener = 0; move32(); + Word16 sum_ener_exp = 0; move16(); + FOR (Word16 i = 0; i < bands_number; i++) + { + sum_ener = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, sum_ener, sum_ener_exp, &sum_ener_exp); + } + + Word16 denom = sub(14,norm_s(bands_number)); + IF (sub(frame_dms, 50) == 0){ + denom = sub(15,norm_s(bands_number)); move16(); + } + + Word32 mean_ener = L_shr(sum_ener, denom); move32(); // = sum_ener / bands_number + mean_ener_exp = sum_ener_exp; move16(); + + Word32 sum_ener_log2 = 0;move32(); + Word16 sum_ener_log2_exp = 0;move16(); + Word32 mean_ener_log2 = 0;move32(); + + FOR (Word16 i = 0; i < bands_number; i++) + { + IF (ener_fx[i] != 0) { + Word32 log2Value = L_add(BASOP_Util_Log2_lc3plus(ener_fx[i]), L_shl_pos(L_deposit_l(ener_fx_exp), 25)); + /* input argument is in Q7.25 , returns pow(2,(x/64) + floatingpoint value log2_fl = log2Value/pow(2,31-6) */ + sum_ener_log2 = BASOP_Util_Add_Mant32Exp_lc3plus(log2Value, 6, sum_ener_log2, sum_ener_log2_exp, &sum_ener_log2_exp); move32(); + } + } + mean_ener_log2 = L_shr(sum_ener_log2, denom); move32(); //mean_ener_log2 = sum_ener_log2 / bands_number + Word16 mean_ener_log2_exp = sum_ener_log2_exp; + Word32 mean_ener_log2_fl = L_shr_pos(mean_ener_log2 ,s_min(31, sub(31,mean_ener_log2_exp))); //mean_ener_log2_fl = mean_ener_log2 / 2^(31-mean_ener_log2_exp) + Word32 inv_flatness = 0; + if (L_sub(norm_l(mean_ener),sub(sub(mean_ener_exp,31),mean_ener_log2_fl)) < 0 ) { + inv_flatness = maxWord32; + } + else { + inv_flatness = L_shl(mean_ener, s_max(-31,sub(sub(mean_ener_exp,31),mean_ener_log2_fl))); + } + IF (L_sub(inv_flatness, td_thresh) > 0) { + *near_nyquist_flag = 1; move16(); + } + } + #endif // ENABLE_HR_MODE +#endif // CR8_E_TONE_DETECTOR +} diff --git a/lib_lc3plus/noise_factor.c b/lib_lc3plus/noise_factor.c deleted file mode 100644 index 5e4ecd7b9..000000000 --- a/lib_lc3plus/noise_factor.c +++ /dev/null @@ -1,130 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms, - LC3_INT target_bytes -) -{ - LC3_INT sumZeroLines = 0, kZeroLines = 0, startOffset = 0, nTransWidth = 0, i = 0, j = 0, k = 0, m = 0, nzeros = 0; - LC3_FLOAT fac_ns_unq = 0, idx = 0, nsf1 = 0, nsf2 = 0; - LC3_INT zeroLines[MAX_LEN]; - - switch (frame_dms) - { - case 25: - nTransWidth = 1; - startOffset = 6; - break; - case 50: - nTransWidth = 1; - startOffset = 12; - break; -#ifdef CR8_G_ADD_75MS - case 75: - nTransWidth = 2; - startOffset = 18; - break; -#endif - case 100: - nTransWidth = 3; - startOffset = 24; - break; - } - - for (k = startOffset - nTransWidth; k < startOffset + nTransWidth; k++) - { - if (xq[k] != 0) - { - nzeros = -2 * nTransWidth - 1; - } - if (xq[k] == 0) - { - nzeros ++; - } - } - for (k = startOffset; k < BW_cutoff_idx - nTransWidth; k++) - { - if (xq[k + nTransWidth] != 0) - { - nzeros = -2 * nTransWidth - 1; - } - if (xq[k + nTransWidth] == 0) - { - nzeros ++; - } - if (nzeros >= 0) - { - zeroLines[j++] = k; - } - } - - for (k = BW_cutoff_idx - nTransWidth; k < BW_cutoff_idx; k++) - { - nzeros ++; - if (nzeros >= 0) - { - zeroLines[j++] = k; - } - } - - if (j == 0) { - fac_ns_unq = 0; - } - else - { - kZeroLines = j; - - fac_ns_unq = 0; - for (j = 0; j < kZeroLines; j++) { - fac_ns_unq += LC3_FABS(x[zeroLines[j]]); - } - - fac_ns_unq /= (gg) * kZeroLines; - - - - if (kZeroLines > 1 && target_bytes <= 20 && frame_dms == 100) { - - j = 0, k = 0, nsf1 = 0, nsf2 = 0, sumZeroLines = 0; - - for (i = 0; i < kZeroLines; i++) { - sumZeroLines += zeroLines[i]; - } - - m = floor(sumZeroLines / kZeroLines); - - for (i = 0; i < kZeroLines; i++) { - if (zeroLines[i] <= m) { - j++; - nsf1 += LC3_FABS(x[zeroLines[i]]); - } - else { - nsf2 += LC3_FABS(x[zeroLines[i]]); - k++; - } - } - - nsf1 /= (gg) * j; - nsf2 /= (gg) * k; - - fac_ns_unq = MIN(nsf1, nsf2); - } - - } - - idx = round(8 - 16 * fac_ns_unq); - idx = MIN(MAX(idx, 0), 7); - - *fac_ns_idx = idx; -} diff --git a/lib_lc3plus/noise_factor_fx.c b/lib_lc3plus/noise_factor_fx.c new file mode 100644 index 000000000..75ffb5fac --- /dev/null +++ b/lib_lc3plus/noise_factor_fx.c @@ -0,0 +1,252 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + + +void processNoiseFactor_fx(Word16 *fac_ns_idx, Word16 x_e, Word32 x[], +# ifdef ENABLE_HR_MODE + Word32 xq[], +# else + Word16 xq[], +# endif + Word16 gg, Word16 gg_e, Word16 BW_cutoff_idx, Word16 frame_dms, Word16 target_bytes, + Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + ,Word16 hrmode +# endif +) +{ + Dyn_Mem_Deluxe_In(Counter k; Word16 nzeros, s1, s2, s3, c, idx, fac_unq, *ind; + Word16 noisefillwidth, noisefillstart, N; Word32 Lsum;); + + + + ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN bytes */ + + noisefillwidth = 0; + noisefillstart = 0; + c = 0; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + N = BW_cutoff_bin_all_HR[BW_cutoff_idx]; + move16(); + } + else +#endif + { + N = BW_cutoff_bin_all[BW_cutoff_idx]; + move16(); + } + + SWITCH (frame_dms) + { + case 25: + N = shr_pos(N, 2); + noisefillwidth = NOISEFILLWIDTH_2_5MS; + noisefillstart = NOISEFILLSTART_2_5MS; + BREAK; + case 50: + N = shr_pos(N, 1); + noisefillwidth = NOISEFILLWIDTH_5MS; + noisefillstart = NOISEFILLSTART_5MS; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + N = add(shr_pos(N, 2), add(shr_pos(N, 2), shr_pos(N, 2))); + noisefillwidth = NOISEFILLWIDTH_7_5MS; + noisefillstart = NOISEFILLSTART_7_5MS; + BREAK; +# endif + case 100: + noisefillwidth = NOISEFILLWIDTH; + noisefillstart = NOISEFILLSTART; + BREAK; + } + + nzeros = -2 * noisefillwidth - 1; + move16(); + + FOR (k = noisefillstart - noisefillwidth; k < noisefillstart + noisefillwidth; k++) + { + if (xq[k] != 0) + { + nzeros = -2 * noisefillwidth - 1; + move16(); + } + if (xq[k] == 0) + { + nzeros = add(nzeros, 1); + } + } + + FOR (k = noisefillstart; k < N - noisefillwidth; k++) + { + if (xq[k + noisefillwidth] != 0) + { + nzeros = -2 * noisefillwidth - 1; + move16(); + } + if (xq[k + noisefillwidth] == 0) + { + nzeros = add(nzeros, 1); + } + if (nzeros >= 0) + { + ind[c++] = k; + move16(); + } + } + + FOR (k = N - noisefillwidth; k < N; k++) + { + nzeros = add(nzeros, 1); + if (nzeros >= 0) + { + ind[c++] = k; + move16(); + } + } + + IF (c == 0) + { + fac_unq = 0; + move16(); + } + ELSE + { + + IF (target_bytes <= 20 && frame_dms == 100) + { + Word32 ind_sum; + Word16 mean_ind; + + Word16 fac_unq1, fac_unq2; + + /* calculate mean index */ + ind_sum = ind[0]; + move32(); + FOR (k = 1; k < c; k++) + { + ind_sum = L_add(ind_sum, ind[k]); + } + + mean_ind = BASOP_Util_Divide3216_Scale_lc3plus(ind_sum, c, &s2); + mean_ind = shl(mean_ind, s2 + 1); + + assert(0 <= mean_ind && mean_ind <= ind[c - 1]); + + /* calculate noise filling gain for low frequencies */ + s2 = 0; move16(); + if (sub(mean_ind, ind[0]) > 0) + { + /* calculate scale to ensure that Lsum does not overflow */ + s2 = s_max(sub(sub(14, norm_s(c)), getScaleFactor32_lc3plus(&x[ind[0]], sub(mean_ind, ind[0]))), 0); + } + Lsum = L_shr_pos_pos(L_abs(x[ind[0]]), s2); + + FOR (k = 1; k < c && ind[k] <= mean_ind; k++) + { + /* scale before adding to Lsum */ + Lsum = L_add(Lsum, L_shr_pos_pos(L_abs(x[ind[k]]), s2)); + } + fac_unq1 = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, k, &s1); + /* add scale applied during summing */ + s1 = add(s1, s2); + fac_unq1 = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq1, gg, &s2); + s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e)))); + s2 = norm_s(fac_unq1); + test(); + IF (fac_unq1 != 0 && add(s3, s2) < 0) + { + fac_unq1 = MAX_16; + move16(); + } + ELSE + { + s3 = s_min(s_max(s3, -15), 15); + fac_unq1 = shr_r(fac_unq1, s3); + } + + /* calculate noise filling gain for high frequencies */ + Lsum = 0; + move16(); + idx = sub(c, k); + FOR (; k < c; k++) + { + Lsum = L_add(Lsum, L_abs(x[ind[k]])); + } + fac_unq2 = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, idx, &s1); + fac_unq2 = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq2, gg, &s2); + s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e)))); + s2 = norm_s(fac_unq1); + test(); + IF (fac_unq2 != 0 && add(s3, s2) < 0) + { + fac_unq2 = MAX_16; + move16(); + } + ELSE + { + s3 = s_min(s_max(s3, -15), 15); + fac_unq2 = shr_r(fac_unq2, s3); + } + + /* calculate noise filling gain as minimum over high and low frequencies */ + fac_unq = s_min(fac_unq1, fac_unq2); + } + ELSE + { + /* calculate scale to ensure that Lsum does not overflow */ + s2 = s_max(sub(sub(14, norm_s(c)), getScaleFactor32_lc3plus(&x[ind[0]], sub(N,ind[0]))), 0); + Lsum = L_abs(x[ind[0]]); + FOR (k = 1; k < c; k++) + { + /* scale before adding to Lsum */ + Lsum = L_add(Lsum, L_shr_pos_pos(L_abs(x[ind[k]]), s2)); + } + fac_unq = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, c, &s1); + /* add scale applied during summing */ + s1 = add(s1, s2); + fac_unq = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq, gg, &s2); + s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e)))); + s2 = norm_s(fac_unq); + test(); + IF (fac_unq != 0 && add(s3, s2) < 0) + { + fac_unq = MAX_16; + move16(); + } + ELSE + { + fac_unq = shr_r(fac_unq, s_max(s_min(s3, 15), -15)); + } + } + } + + idx = round_fx(L_sub(0x80000, L_mult(fac_unq, 16))); + if (sub(idx, 7) > 0) + { + idx = 7; + move16(); + } + if (idx < 0) + { + idx = 0; + move16(); + } + *fac_ns_idx = idx; + move16(); + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/noise_filling.c b/lib_lc3plus/noise_filling.c deleted file mode 100644 index b844aef08..000000000 --- a/lib_lc3plus/noise_filling.c +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx) -{ - LC3_INT zeroLines[MAX_LEN]; - LC3_INT nTransWidth, startOffset, j, k, nzeros = 0, kZeroLines; - LC3_FLOAT fac_ns = 0; - - switch (frame_dms) - { - case 25: - nTransWidth = 1; - startOffset = 6; - break; - case 50: - nTransWidth = 1; - startOffset = 12; - break; -#ifdef CR8_G_ADD_75MS - case 75: - nTransWidth = 2; - startOffset = 18; - break; -#endif - case 100: - nTransWidth = 3; - startOffset = 24; - break; - } - - fac_ns = (8.0 - fac_ns_idx) / 16.0; - - j = 0; - - for (k = startOffset - nTransWidth; k < startOffset + nTransWidth; k++) - { - if (xq[k] != 0) - { - nzeros = -2 * nTransWidth - 1; - } - if (xq[k] == 0) - { - nzeros ++; - } - } - for (k = startOffset; k < bw_stopband - nTransWidth; k++) - { - if (xq[k + nTransWidth] != 0) - { - nzeros = -2 * nTransWidth - 1; - } - if (xq[k + nTransWidth] == 0) - { - nzeros ++; - } - if (nzeros >= 0) - { - zeroLines[j++] = k; - } - } - - for (k = bw_stopband - nTransWidth; k < bw_stopband; k++) - { - nzeros ++; - if (nzeros >= 0) - { - zeroLines[j++] = k; - } - } - - kZeroLines = j; - - for (k = 0; k < kZeroLines; k++) { - nfseed = (13849 + (nfseed + 32768) * 31821) & 65535; - nfseed -= 32768; - - if (nfseed >= 0) { - if (zeroLines[k] < spec_inv_idx) - { - xq[zeroLines[k]] = fac_ns; - } else { - xq[zeroLines[k]] = fac_ns_pc; - } - } else { - if (zeroLines[k] < spec_inv_idx) - { - xq[zeroLines[k]] = -fac_ns; - } else { - xq[zeroLines[k]] = -fac_ns_pc; - } - } - } - - return; -} diff --git a/lib_lc3plus/noise_filling_fx.c b/lib_lc3plus/noise_filling_fx.c new file mode 100644 index 000000000..9da870553 --- /dev/null +++ b/lib_lc3plus/noise_filling_fx.c @@ -0,0 +1,149 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +/*************************************************************************/ + + + +void processNoiseFilling_fx(Word32 xq[], Word16 nfseed, Word16 xq_e, Word16 fac_ns_idx, Word16 BW_cutoff_idx, + Word16 frame_dms, Word16 fac_ns_pc, Word16 spec_inv_idx, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + Dyn_Mem_Deluxe_In( + Counter k; + Word16 nzeros, fac_ns, *ind, c; + Word16 noisefillwidth, noisefillstart, N; + Word32 L_tmp, L_tmp_neg, L_tmp_pc, L_tmp_neg_pc; + ); + + ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN bytes */ + + c = 0; move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode == 1) + { + N = BW_cutoff_bin_all_HR[BW_cutoff_idx]; + move16(); + } + else +#endif + { + N = BW_cutoff_bin_all[BW_cutoff_idx]; + move16(); + } + + SWITCH (frame_dms) + { + case 25: + N = shr_pos(N, 2); + noisefillwidth = NOISEFILLWIDTH_2_5MS; + noisefillstart = NOISEFILLSTART_2_5MS; + BREAK; + case 50: + N = shr_pos(N, 1); + noisefillwidth = NOISEFILLWIDTH_5MS; + noisefillstart = NOISEFILLSTART_5MS; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + N = add(shr_pos(N, 2), add(shr_pos(N, 2), shr_pos(N, 2))); + noisefillwidth = NOISEFILLWIDTH_7_5MS; + noisefillstart = NOISEFILLSTART_7_5MS; + BREAK; +#endif + default: /* 100 */ + noisefillwidth = NOISEFILLWIDTH; + noisefillstart = NOISEFILLSTART; + BREAK; + } + + nzeros = -2 * noisefillwidth - 1; move16(); + + FOR (k = noisefillstart - noisefillwidth; k < noisefillstart + noisefillwidth; k++) + { + if (xq[k] != 0) + { + nzeros = -2 * noisefillwidth - 1; move16(); + } + if (xq[k] == 0) + { + nzeros = add(nzeros, 1); + } + } + + FOR (k = noisefillstart; k < N - noisefillwidth; k++) + { + if (xq[k + noisefillwidth] != 0) + { + nzeros = -2 * noisefillwidth - 1; move16(); + } + if (xq[k + noisefillwidth] == 0) + { + nzeros = add(nzeros, 1); + } + if (nzeros >= 0) + { + ind[c++] = k; move16(); + } + } + + FOR (k = N - noisefillwidth; k < N; k++) + { + nzeros = add(nzeros, 1); + if (nzeros >= 0) + { + ind[c++] = k; move16(); + } + } + + IF (c > 0) + { + fac_ns = shl_pos(sub(8, fac_ns_idx), 11); + L_tmp = L_shr_sat(L_deposit_l(fac_ns), sub(xq_e, 16)); + L_tmp_neg = L_negate(L_tmp); + L_tmp_pc = L_shr_sat(L_deposit_l(fac_ns_pc), sub(xq_e, 16)); + L_tmp_neg_pc = L_negate(L_tmp_pc); + + FOR (k = 0; k < c; k++) + { + nfseed = extract_l(L_mac0(13849, nfseed, 31821)); + IF (nfseed >= 0) + { + IF (ind[k] < spec_inv_idx) + { + xq[ind[k]] = L_tmp; move32(); + } + ELSE + { + xq[ind[k]] = L_tmp_pc; move32(); + } + } + IF (nfseed < 0) + { + IF (ind[k] < spec_inv_idx) + { + xq[ind[k]] = L_tmp_neg; move32(); + } + ELSE + { + xq[ind[k]] = L_tmp_neg_pc; move32(); + } + } + } + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/olpa.c b/lib_lc3plus/olpa.c deleted file mode 100644 index 62a303f26..000000000 --- a/lib_lc3plus/olpa.c +++ /dev/null @@ -1,201 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input); -static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT32 len); - -void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input) -{ - /* a = 1, so denominator == 1, nothing to do here */ - LC3_INT32 i, j; - - - j = 0; - for (i = 4; i < len_input; i += 2) { - out[j++] = (buf[0] * in[i]) + (buf[1] * in[i - 1]) + (buf[2] * in[i - 2]) + (buf[3] * in[i - 3]) + (buf[4] * in[i - 4]); - } -} - -LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) -{ - LC3_INT max_i = 0, i; - LC3_FLOAT max = in[0]; - - if (len <= 0) { - return -128; - } - - for (i = 0; i < len; i++) { - if (in[i] > max) { - max = in[i]; - max_i = i; - } - } - - return max_i; -} - -void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, -#ifdef CR9_F_PITCH_WIN_LEN_FIX - LC3_INT* pitch_flag, -#endif - LC3_INT* T0_out, LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms) -{ - LC3_FLOAT norm_corr = 0, sum = 0, sum0 = 0, sum1 = 0, sum2 = 0, norm_corr2 = 0, *s6k4; - LC3_FLOAT buf[LEN_6K4 + MAX_PITCH_6K4 + MAX_LEN], R0[RANGE_PITCH_6K4]; /* constant length */ - LC3_INT i = 0, len2 = 0, T0 = 0, T02 = 0, min_pitch = 0, max_pitch = 0, L = 0, mem_in_len = 0, acflen = 0, delta = 0; - - len2 = len / 2; -#ifdef CR9_F_PITCH_WIN_LEN_FIX - switch(frame_dms) - { - case 50: - delta = len / 2; - acflen = len2 * 2; - break; - - case 25: - delta = 3*(len /2); - acflen = len2*4; - break; - - default: -#endif - delta = 0; - acflen = len2; -#ifdef CR9_F_PITCH_WIN_LEN_FIX - } -#endif - - mem_in_len = MAX_PITCH_6K4 + delta; - -#ifndef CR9_F_PITCH_WIN_LEN_FIX - if (frame_dms == 25) - { - mem_in_len += 16; - acflen += 16; - } -#endif - - /* Downsampling */ - move_float(buf, mem_s12k8, 3); - move_float(&buf[3], s_12k8, len); - move_float(mem_s12k8, &buf[len], 3); - filter_olpa(buf, R0, olpa_down2, len + 3); - - /* Compute autocorrelation */ -#ifdef CR9_F_PITCH_WIN_LEN_FIX - s6k4 = &buf[mem_in_len - delta]; - move_float(&buf[mem_in_len], R0, len2); - move_float(buf, mem_s6k4, mem_in_len); - move_float(mem_s6k4, &buf[len2], mem_in_len); -#else - s6k4 = &buf[mem_in_len]; - move_float(buf, mem_s6k4, mem_in_len); - move_float(s6k4, R0, len2); - move_float(mem_s6k4, &buf[len2], mem_in_len); - if (frame_dms == 25) - { - s6k4 = s6k4 - 16; - } -#endif - for (i = MIN_PITCH_6K4; i <= MAX_PITCH_6K4; i++) { - sum = mac_loop(s6k4, &s6k4[-i], acflen); - R0[i - MIN_PITCH_6K4] = sum; - } - - /* Weight autocorrelation and find maximum */ - - /* Second try in the neighborhood of the previous pitch */ - min_pitch = MAX(MIN_PITCH_6K4, *mem_old_T0 - 4); - max_pitch = MIN(MAX_PITCH_6K4, *mem_old_T0 + 4); - - L = searchMaxIndice(&R0[min_pitch - MIN_PITCH_6K4], max_pitch - min_pitch + 1 ); - T02 = L + min_pitch; - - for (i = 0; i < RANGE_PITCH_6K4; i++) { - R0[i] = R0[i] * olpa_acw[i]; - } - L = searchMaxIndice(R0, RANGE_PITCH_6K4); - T0 = L + MIN_PITCH_6K4; - - /* Compute normalized correlation */ - sum0 = sum1 = sum2 = 0; - - for (i = 0; i < acflen; i++) { - sum0 += s6k4[i] * s6k4[i - T0]; - sum1 += s6k4[i - T0] * s6k4[i - T0]; - sum2 += s6k4[i] * s6k4[i]; - } - sum1 = sum1 * sum2; - sum1 = LC3_SQRT(sum1) + 1.00e-05; - norm_corr = sum0 / sum1; - norm_corr = MAX(0, norm_corr); - - if (T02 != T0) { - sum0 = sum1 = sum2 = 0; - for (i = 0; i < acflen; i++) { - sum0 += s6k4[i] * s6k4[i - T02]; - sum1 += s6k4[i - T02] * s6k4[i - T02]; - sum2 += s6k4[i] * s6k4[i]; - } - sum1 = sum1 * sum2; - sum1 = LC3_SQRT(sum1) + 1.00e-05; - norm_corr2 = sum0 / sum1; - norm_corr2 = MAX(0, norm_corr2); - - if (norm_corr2 > (norm_corr * 0.85)) { - T0 = T02; - norm_corr = norm_corr2; - } - } - -#ifdef CR9_F_PITCH_WIN_LEN_FIX - switch(frame_dms) - { - case 50: - if (*pitch_flag == 1) - { - *mem_old_T0 = T0; - *pitch_flag = 0; - } - else - { - *pitch_flag += 1; - } - break; - - case 25: - if (*pitch_flag == 3) - { - *mem_old_T0 = T0; - *pitch_flag = 0; - } - else - { - *pitch_flag += 1; - } - break; - - default: -#endif - *mem_old_T0 = T0; -#ifdef CR9_F_PITCH_WIN_LEN_FIX - } -#endif - - *T0_out = T0 * 2.0; - *normcorr_out = norm_corr; - -} diff --git a/lib_lc3plus/olpa_fx.c b/lib_lc3plus/olpa_fx.c new file mode 100644 index 000000000..a72d8b61c --- /dev/null +++ b/lib_lc3plus/olpa_fx.c @@ -0,0 +1,289 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +/*************************************************************************/ + + +void process_olpa_fx(Word16 *mem_s6k4_exp, Word16 mem_s12k8[], Word16 mem_s6k4[], Word16 *pitch, Word16 *s12k8, + Word16 len, Word16 *normcorr, Word16 *mem_pitch, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + Word16 *pitch_flag, +#endif + Word16 s12k8_exp, Word16 frame_dms, Word8 *scratchBuffer) +{ + Word32 sum, sum0, sum1, sum2, prod, inv; + Word16 shift, s6k4_exp, prod_exp, min_pitch, max_pitch; + Word16 scale0, scale1, scale2, pitch2, normcorr2, len2, acflen, mem_in_len; + Word32 max32; + Word32 *ac; + Word16 *s6k4; + Counter n; + + Counter m; + Word32 L_tmp, L_tmp2; + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("process_olpa_fx", sizeof(struct { + Word32 sum, sum0, sum1, sum2, prod, inv; + Word16 shift, s6k4_exp, prod_exp, min_pitch, max_pitch; + Word16 scale0, scale1, scale2, pitch2, normcorr2, len2, acflen, mem_in_len; + Word32 max32; + Word32 *ac; + Word16 *s6k4; + Counter n; + Word32 sums[3]; + Counter m; + Word32 L_tmp, L_tmp2; + })); +#endif + + /* Buffer alignment */ + ac = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * RANGE_PITCH_6K4 = 392 bytes */ + + /* Downsample input signal by a factor of 2 (12.8kHz -> 6.4kHz) */ + mem_in_len = MAX_PITCH_6K4; move16(); + len2 = shr(len, 1); + acflen = len2; move16(); + +#ifdef CR9_F_PITCH_WIN_LEN_FIX + SWITCH(frame_dms) + { + case 50: + mem_in_len = add(mem_in_len, 32); + acflen = add(acflen, 32); + break; + + case 25: + mem_in_len = add(mem_in_len, 48); + acflen = add(acflen, 48); + break; + } +#endif + +#ifndef CR9_F_PITCH_WIN_LEN_FIX + IF (sub(frame_dms, 25) == 0) + { + mem_in_len = add(mem_in_len, 16); + acflen = add(acflen, 16); + } +#endif + + s6k4 = mem_s6k4 + mem_in_len; + sum = L_mac(L_mac(L_mult(mem_s12k8[0], 4053), mem_s12k8[1], 7712), mem_s12k8[2], 9239); + *s6k4++ = round_fx(L_mac_sat(L_mac(sum, s12k8[0], 7712), s12k8[1], 4053)); move16(); + sum = L_mac(L_mac(L_mult(mem_s12k8[2], 4053), s12k8[0], 7712), s12k8[1], 9239); + *s6k4++ = round_fx(L_mac_sat(L_mac(sum, s12k8[2], 7712), s12k8[3], 4053)); move16(); + + FOR (n = 5; n < len; n += 2) + { + sum = L_mac(L_mac(L_mult(s12k8[n - 4], 4053), s12k8[n - 3], 7712), s12k8[n - 2], 9239); + *s6k4++ = round_fx_sat(L_mac_sat(L_mac(sum, s12k8[n - 1], 7712), s12k8[n], 4053)); move16(); + } + + mem_s12k8[0] = s12k8[len - 3]; move16(); + mem_s12k8[1] = s12k8[len - 2]; move16(); + mem_s12k8[2] = s12k8[len - 1]; move16(); + + /* Scale downsampled signal */ + s6k4 = mem_s6k4 + mem_in_len; + scale0 = sub(getScaleFactor16_0(mem_s6k4, mem_in_len), 3); + *mem_s6k4_exp = sub(*mem_s6k4_exp, scale0); move16(); + scale1 = sub(getScaleFactor16_0(s6k4, len2), 3); + s6k4_exp = sub(s12k8_exp, scale1); + scale2 = sub(*mem_s6k4_exp, s6k4_exp); + IF (scale2 > 0) + { + Scale_sig(s6k4, len2, sub(scale1, scale2)); + shift = scale0; move16(); + s6k4_exp = *mem_s6k4_exp; move16(); + } + ELSE + { + Scale_sig(s6k4, len2, scale1); + shift = add(scale0, scale2); + *mem_s6k4_exp = s6k4_exp; move16(); + } +#ifdef CR9_F_PITCH_WIN_LEN_FIX + SWITCH(frame_dms) + { + case 50: + s6k4 = s6k4 - 32; + break; + + case 25: + s6k4 = s6k4 - 48; + break; + } +#endif + +#ifndef CR9_F_PITCH_WIN_LEN_FIX + if (sub(frame_dms, 25) == 0) + { + s6k4 = s6k4 - 16; + } +#endif + Scale_sig(mem_s6k4, mem_in_len, shift); + + /* Compute autocorrelation */ + FOR (n = MIN_PITCH_6K4; n <= MAX_PITCH_6K4; n++) + { + sum = L_mult0(s6k4[0], s6k4[0 - n]); + FOR (m = 1; m < acflen; m++) + { + sum = L_mac0(sum, s6k4[m], s6k4[m - n]); + } + ac[n - MIN_PITCH_6K4] = sum; move32(); + } + + /* Weight autocorrelation and find maximum */ + max32 = Mpy_32_16_lc3plus(ac[0], olpa_ac_weighting[0]); move32(); + *pitch = MIN_PITCH_6K4; move16(); + FOR (n = MIN_PITCH_6K4 + 1; n <= MAX_PITCH_6K4; n++) + { + L_tmp = Mpy_32_16_lc3plus(ac[n - MIN_PITCH_6K4], olpa_ac_weighting[n - MIN_PITCH_6K4]); + L_tmp2 = L_sub_sat(L_tmp, max32); + if (L_tmp2 > 0) + { + *pitch = n; move16(); + } + max32 = L_max(L_tmp, max32); + } + + /* Compute normalized correlation */ + sum0 = L_mult0(s6k4[0], s6k4[0 - *pitch]); + sum1 = L_mac0(1, s6k4[0 - *pitch], s6k4[0 - *pitch]); + sum2 = L_mac0(1, s6k4[0], s6k4[0]); + for (m = 1; m < acflen; m++) + { + sum0 = L_mac0(sum0, s6k4[m], s6k4[m - *pitch]); + sum1 = L_mac0(sum1, s6k4[m - *pitch], s6k4[m - *pitch]); + sum2 = L_mac0(sum2, s6k4[m], s6k4[m]); + } + scale1 = norm_l(sum1); + scale2 = norm_l(sum2); + sum1 = L_shl_pos(sum1, scale1); + sum2 = L_shl_pos(sum2, scale2); + prod = Mpy_32_32_lc3plus(sum1, sum2); + shift = norm_l(prod); + prod = L_shl_pos(prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + inv = Isqrt(prod, &prod_exp); + scale0 = norm_l(sum0); + sum0 = L_shl_pos(sum0, scale0); + prod = Mpy_32_32_lc3plus(sum0, inv); + prod_exp = add(sub(31, scale0), prod_exp); + test(); + IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0) + { + *normcorr = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16(); + } + ELSE + { + *normcorr = 32767; move16(); + } + + /* Second try in the neighborhood of the previous pitch */ + min_pitch = s_max(MIN_PITCH_6K4, sub(*mem_pitch, 4)); + max_pitch = s_min(MAX_PITCH_6K4, add(*mem_pitch, 4)); + + max32 = ac[min_pitch - MIN_PITCH_6K4]; move32(); + pitch2 = min_pitch; move16(); + FOR (n = min_pitch + 1; n <= max_pitch; n++) + { + L_tmp = L_sub_sat(ac[n - MIN_PITCH_6K4], max32); + if (L_tmp > 0) + { + pitch2 = n; move16(); + } + max32 = L_max(ac[n - MIN_PITCH_6K4], max32); + } + IF (sub(*pitch, pitch2) != 0) + { + sum0 = L_mult0(s6k4[0], s6k4[0 - pitch2]); + sum1 = L_mac0(1, s6k4[0 - pitch2], s6k4[0 - pitch2]); + sum2 = L_mac0(1, s6k4[0], s6k4[0]); + for (m = 1; m < acflen; m++) + { + sum0 = L_mac0(sum0, s6k4[m], s6k4[m - pitch2]); + sum1 = L_mac0(sum1, s6k4[m - pitch2], s6k4[m - pitch2]); + sum2 = L_mac0(sum2, s6k4[m], s6k4[m]); + } + scale1 = norm_l(sum1); + scale2 = norm_l(sum2); + sum1 = L_shl_pos(sum1, scale1); + sum2 = L_shl_pos(sum2, scale2); + prod = Mpy_32_32_lc3plus(sum1, sum2); + shift = norm_l(prod); + prod = L_shl_pos(prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + inv = Isqrt(prod, &prod_exp); + scale0 = norm_l(sum0); + sum0 = L_shl_pos(sum0, scale0); + prod = Mpy_32_32_lc3plus(sum0, inv); + prod_exp = add(sub(31, scale0), prod_exp); + test(); + IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0) + { + normcorr2 = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16(); + } + ELSE + { + normcorr2 = 32767; move16(); + } + IF (sub(normcorr2, mult_r(*normcorr, 27853)) > 0) + { + *pitch = pitch2; move16(); + *normcorr = normcorr2; move16(); + } + } + +#ifdef CR9_F_PITCH_WIN_LEN_FIX + SWITCH(frame_dms) + { + case 50: + if(*pitch_flag == 1) { + *mem_pitch = *pitch; move16(); + *pitch_flag = 0; + } + else { + *pitch_flag += 1; + } + break; + + case 25: + if (*pitch_flag == 3) { + *mem_pitch = *pitch; move16(); + *pitch_flag = 0; + } + else { + *pitch_flag += 1; + } + break; + + default: +#endif + *mem_pitch = *pitch; move16(); +#ifdef CR9_F_PITCH_WIN_LEN_FIX + } +#endif + + /* Update memory */ + basop_memmove(mem_s6k4, &mem_s6k4[len2], mem_in_len * sizeof(Word16)); + + /* Upsample pitch by a factor of 2 (6.4kHz -> 12.8kHz) */ + *pitch = shl_pos(*pitch, 1); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/pc_apply.c b/lib_lc3plus/pc_apply.c deleted file mode 100644 index 89bab44eb..000000000 --- a/lib_lc3plus/pc_apply.c +++ /dev/null @@ -1,74 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processPcApply_fl(LC3_FLOAT *q_res, LC3_FLOAT *q_old_res, LC3_FLOAT *q_d_prev, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_FLOAT *prev_gg, LC3_FLOAT *fac, LC3_INT32 *pc_nbLostCmpt) -{ - LC3_FLOAT gg, mean_nrg_low, mean_nrg_high, ener_prev, ener_curr, fac_local; - LC3_INT32 i; - - ener_prev = 0; ener_curr = 0; mean_nrg_low = 0; mean_nrg_high = 0; - - *pc_nbLostCmpt = *pc_nbLostCmpt + 1; - - assert(spec_inv_idx > 1); - - gg = LC3_POW(10, (((LC3_FLOAT) (gg_idx + gg_idx_off)) / 28.0)); - - for (i = 0; i < spec_inv_idx; i++) - { - mean_nrg_low += LC3_POW(q_d_prev[i], 2); - } - - mean_nrg_low /= (LC3_FLOAT) spec_inv_idx; - - if (spec_inv_idx < yLen) - { - for (i = spec_inv_idx; i < yLen; i++) - { - mean_nrg_high += LC3_POW(q_d_prev[i], 2); - } - } - - mean_nrg_high /= (LC3_FLOAT) (yLen - spec_inv_idx); - - for (i = 0; i < spec_inv_idx; i++) - { - ener_prev += LC3_POW(q_old_res[i], 2); - ener_curr += LC3_POW(q_res[i], 2); - } - - *fac = 1; - if (ener_prev > 0) - { - *fac = LC3_SQRT(ener_curr / ener_prev); - } - - fac_local = *fac; - if (mean_nrg_low <= mean_nrg_high || ener_prev * LC3_POW(*prev_gg, 2) <= ener_curr * LC3_POW(gg, 2)) - { - fac_local = *prev_gg / gg; - } - - for (i = spec_inv_idx; i < yLen; i++) - { - q_res[i] = q_old_res[i] * fac_local; - - if (LC3_FABS(q_res[i]) < (1 - 0.375)) - { - q_res[i] = 0; - } - } -} - diff --git a/lib_lc3plus/pc_apply_fx.c b/lib_lc3plus/pc_apply_fx.c new file mode 100644 index 000000000..42ddfb243 --- /dev/null +++ b/lib_lc3plus/pc_apply_fx.c @@ -0,0 +1,315 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "functions.h" + +#ifdef ENABLE_HR_MODE +static Word16 getScaleFactor32_withNegativeScaling(Word32 *data32, Word16 dataLen); +#else +static Word16 getScaleFactor16_withNegativeScaling(Word16 *data16, Word16 dataLen); +#endif + + +void processPCapply_fx(Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 q_old_d_fx[], Word16 spec_inv_idx, Word16 *fac, Word16 *fac_e, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 gg_idx, Word16 gg_idx_off, Word16 prev_gg, Word16 prev_gg_e, + Word16 *pc_nbLostFramesInRow) +{ + Counter i; + Word16 s, s2, s3, c, tmp16, tmp16_2, inv_gain, thr; + Word32 ener_curr, ener_prev, mean_nrg_high, mean_nrg_low; + Word16 global_gain, global_gain_e, gg2, gg2_e, prev_gg2, prev_gg2_e; + Word32 tmp32, ener_curr_gg2, ener_prev_gg2; + Word16 fac_local, fac_local_e; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Counter i; + Word16 s, s2, s3, c, tmp16, tmp16_2, inv_gain, thr; + Word32 ener_curr, ener_prev, mean_nrg_high, mean_nrg_low; + Word16 global_gain, global_gain_e, gg2, gg2_e, prev_gg2, prev_gg2_e; + Word32 tmp32, ener_curr_gg2, ener_prev_gg2; + Word16 fac_local, fac_local_e; + }; + Dyn_Mem_In("processPCapply_fx", sizeof(struct _dynmem)); +#endif + + assert(spec_inv_idx >= 0); + + *pc_nbLostFramesInRow = add(*pc_nbLostFramesInRow, 1); + + tmp32 = L_shl_pos(L_mult0(add(gg_idx, gg_idx_off), 0x797D), 7); + global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); + global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000))); + + /** Calculate rescaling factor **/ + + /* mean_nrg_low = mean(q_d_prev(1:spec_inv_idx-1).^2); + mean_nrg_high = mean(q_d_prev(spec_inv_idx:end).^2); */ + s = getScaleFactor16(q_old_d_fx, yLen); + + mean_nrg_low = 0; + move32(); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = shl_sat(q_old_d_fx[i], sub(s, 4)); + mean_nrg_low = L_mac0(mean_nrg_low, tmp16, tmp16); /* exp = 2s - 8 */ + } + + mean_nrg_high = 0; + move32(); + FOR (i = spec_inv_idx; i < yLen; i++) + { + tmp16 = shl_sat(q_old_d_fx[i], sub(s, 4)); + mean_nrg_high = L_mac0(mean_nrg_high, tmp16, tmp16); /* exp = 2s - 8 */ + } + + IF (sub(spec_inv_idx, sub(yLen, spec_inv_idx)) < 0) + { + c = div_s(spec_inv_idx, sub(yLen, spec_inv_idx)); + mean_nrg_high = Mpy_32_16_lc3plus(mean_nrg_high, c); /* exp = 2s - 8 */ + } + ELSE + { + c = div_s(sub(yLen, spec_inv_idx), spec_inv_idx); + mean_nrg_low = Mpy_32_16_lc3plus(mean_nrg_low, c); /* exp = 2s - 8 */ + } + + /* ener_prev = sum(q_old_res(1:spec_inv_idx-1).^2); + ener_curr = sum( q_res(1:spec_inv_idx-1).^2); */ + s = getScaleFactor16(q_old_res_fx, spec_inv_idx); + ener_prev = 0; move32(); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4)); + ener_prev = L_mac0(ener_prev, tmp16, tmp16); /* exp = - (2s - 8 - 2**q_old_res_fx_exp) */ + } + + ener_curr = 0; + move32(); + +#ifdef ENABLE_HR_MODE + s2 = getScaleFactor32_lc3plus(q_res_fx, spec_inv_idx); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = extract_h(L_shl_sat(q_res_fx[i], sub(s2, 4))); + ener_curr = L_mac0(ener_curr, tmp16, tmp16); /* exp = - (2s2 - 8) */ + } + s2 = s2 - 16; +#else + s2 = getScaleFactor16(q_res_fx, spec_inv_idx); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = shl_sat(q_res_fx[i], sub(s2, 4)); + ener_curr = L_mac0(ener_curr, tmp16, tmp16); /* exp = - (2s2 - 8) */ + } +#endif + + + s = shl(sub(s, *q_old_res_fx_exp), 1); + s2 = shl(s2, 1); + s3 = s_max(s, s2); + ener_prev = L_shr_sat(ener_prev, sub(s3, s2)); + ener_curr = L_shr_sat(ener_curr, sub(s3, s)); + + /* fac = 1; */ + *fac = 1; + /* if ener_prev > 0 */ + IF ( ener_prev > 0 ) + { + /* fac = sqrt(ener_curr/ener_prev); */ + s = getScaleFactor32_lc3plus(&ener_prev, 1); + s2 = getScaleFactor32_lc3plus(&ener_curr, 1); + s3 = s_min(s, s2); + tmp16 = extract_h(L_shl_sat(ener_curr, s3)); + tmp16_2 = extract_h(L_shl_sat(ener_prev, s3)); + + *fac_e = 0; move16(); + if ( tmp16_2 == 0) { + tmp16_2 = 32767; move16(); + *fac_e = 15; move16(); + } else { + tmp16_2 = Inv16_lc3plus(tmp16_2, fac_e); + } + + *fac = mult(tmp16, tmp16_2); + + IF (sub(*fac, 32767) < 0) + { + *fac = Sqrt16_lc3plus(*fac, fac_e); move16(); + } + } + + /* fac_local = fac; */ + fac_local = *fac; + fac_local_e = *fac_e; + + /* if (mean_nrg_low > mean_nrg_high) && (ener_prev * prev_gg^2 > ener_curr * gg^2) */ + prev_gg2 = mult(prev_gg, prev_gg); + prev_gg2_e = shl(prev_gg_e, 1); + ener_prev_gg2 = Mpy_32_16_lc3plus(ener_prev, prev_gg2); /* exp = prev_gg2_e */ + + gg2 = mult(global_gain, global_gain); + gg2_e = shl(global_gain_e, 1); + ener_curr_gg2 = Mpy_32_16_lc3plus(ener_curr, gg2); /* exp = gg2_e */ + + s3 = s_max(prev_gg2_e, gg2_e); + ener_prev_gg2 = L_shr_sat(ener_prev_gg2, sub(s3, prev_gg2_e)); + ener_curr_gg2 = L_shr_sat(ener_curr_gg2, sub(s3, gg2_e)); + + + test(); + IF ( (L_sub(mean_nrg_low, mean_nrg_high) <= 0) || (L_sub(ener_prev_gg2, ener_curr_gg2) <= 0) ) + { + /* fac = prev_gg/gg; */ + s = global_gain_e; move16(); + inv_gain = Inv16_lc3plus(global_gain, &s); + fac_local = mult(prev_gg, inv_gain); + fac_local_e = add(s, prev_gg_e); + } + + /* write synthesized samples */ + *q_old_res_fx_exp = add(*q_old_res_fx_exp, fac_local_e); + thr = shl_sat(20480, sub(-15, *q_old_res_fx_exp)); + FOR (i = spec_inv_idx; i < yLen; i++) + { + q_res_fx[i] = extract_h(L_mult(q_old_res_fx[i] /* exp = q_old_res_fx_exp' */, fac_local /* exp = fac_e */)); /* exp = q_old_res_fx_exp */ + + IF (sub(abs_s(q_res_fx[i]), thr) < 0) + { + q_res_fx[i] = 0; + move16(); + } + } + +#ifdef ENABLE_HR_MODE + s = getScaleFactor32_withNegativeScaling(&q_res_fx[0], spec_inv_idx) - 16; /* exp = 0 */ + s2 = getScaleFactor32_withNegativeScaling(&q_res_fx[spec_inv_idx], + sub(yLen, spec_inv_idx)) - 16; /* exp = q_old_res_fx_exp */ +#else + s = getScaleFactor16_withNegativeScaling(&q_res_fx[0], spec_inv_idx); /* exp = 0 */ + s2 = getScaleFactor16_withNegativeScaling(&q_res_fx[spec_inv_idx], + sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */ +#endif + + s3 = add(s, *q_old_res_fx_exp); + IF (sub(s3, s2) > 0) + { + tmp16 = sub(s3, s2); + s = sub(s, tmp16); + s3 = sub(s3, tmp16); + } + *q_fx_exp = sub(15, s); + move16(); + +#ifdef ENABLE_HR_MODE + s = add(s, 16); + s3 = add(s3, 16); +#endif + + s = s_max(s, -31); + s = s_min(s, 31); + s3 = s_max(s3, -31); + s3 = s_min(s3, 31); + + FOR (i = 0; i < spec_inv_idx; i++) + { +#ifdef ENABLE_HR_MODE + q_d_fx[i] = L_shl(q_res_fx[i], s); +#else + q_d_fx[i] = L_shl(L_deposit_h(q_res_fx[i]), s); +#endif + move32(); + } + FOR (; i < yLen; i++) + { +#ifdef ENABLE_HR_MODE + q_d_fx[i] = L_shl(q_res_fx[i], s3); +#else + q_d_fx[i] = L_shl(L_deposit_h(q_res_fx[i]), s3); +#endif + move32(); + } + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#ifndef ENABLE_HR_MODE +static Word16 getScaleFactor16_withNegativeScaling(Word16 *data16, Word16 dataLen) +{ + Counter i; + Dyn_Mem_Deluxe_In(Word16 tmp, shift; Word16 x_min, x_max;); + + x_max = 0; + move16(); + x_min = 0; + move16(); + + FOR (i = 0; i < dataLen; i++) + { + if (data16[i] > 0) + x_max = s_max(x_max, data16[i]); + if (data16[i] < 0) + x_min = s_min(x_min, data16[i]); + } + + tmp = s_max(x_max, negate(x_min)); + shift = norm_s(tmp); + if (tmp == 0) + { + shift = 15; + move16(); + } + + Dyn_Mem_Deluxe_Out(); + + return shift; +} + +#else +static Word16 getScaleFactor32_withNegativeScaling(Word32 *data32, Word16 dataLen) +{ + Counter i; + Dyn_Mem_Deluxe_In(Word32 tmp, shift; Word32 x_min, x_max;); + + x_max = L_add(0, 0); + x_min = L_add(0, 0); + + FOR (i = 0; i < dataLen; i++) + { + if (data32[i] >= 0) + x_max = L_max(x_max, data32[i]); + if (data32[i] < 0) + x_min = L_min(x_min, data32[i]); + } + + tmp = L_max(x_max, L_negate(x_min)); + shift = norm_l(tmp); + if (tmp == 0) + { + shift = 31; + move16(); + } + + Dyn_Mem_Deluxe_Out(); + + return shift; +} +#endif diff --git a/lib_lc3plus/pc_classify.c b/lib_lc3plus/pc_classify.c deleted file mode 100644 index 9ea5e02da..000000000 --- a/lib_lc3plus/pc_classify.c +++ /dev/null @@ -1,171 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -LC3_FLOAT pc_peak_detector(LC3_FLOAT *q_d_prev, LC3_INT32 yLen); - -void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi) -{ - LC3_INT32 maxPitchBin, xover, i; - LC3_FLOAT part_nrg, full_nrg; - - part_nrg = 0; full_nrg = 0; - - if (spec_inv_idx < (4 * frame_dms / 10)) - { - if (stab_fac < 0.5) - { - *bfi = 1; - } else if (pitch_present == 1) - { - maxPitchBin = 8; - if (frame_dms == 50) - { - maxPitchBin = 4; - } - xover = pc_peak_detector(q_d_prev, yLen); - if (spec_inv_idx < xover || spec_inv_idx < maxPitchBin) - { - *bfi = 1; - } - } else { - for (i = 0; i < spec_inv_idx; i++) - { - part_nrg += LC3_POW(q_old_res[i], 2); - } - - for (i = 0; i < yLen; i++) - { - full_nrg += LC3_POW(q_old_res[i], 2); - } - - if (part_nrg < (0.3 * full_nrg)) - { - *bfi = 1; - } - } - } -} - -LC3_FLOAT pc_peak_detector(LC3_FLOAT *q_d_prev, LC3_INT32 yLen) -{ - LC3_INT32 block_size, thresh1, i, peak, j, k; - LC3_FLOAT fac, mean_block_nrg, cur_max, block_cent, maxPeak, next_max, prev_max; - - mean_block_nrg = 0; - - block_size = 3; - thresh1 = 8; - fac = 0.3; - - for (i = 0; i < yLen; i++) - { - mean_block_nrg += LC3_POW(q_d_prev[i], 2); - } - - mean_block_nrg /= yLen; - - maxPeak = 0; - peak = 0; - - if (LC3_FABS(q_d_prev[0]) > LC3_FABS(q_d_prev[1])) - { - block_cent = LC3_POW(q_d_prev[0], 2) + LC3_POW(q_d_prev[1], 2); - - if ((block_cent / block_size) > (thresh1 * mean_block_nrg)) - { - cur_max = MAX(LC3_FABS(q_d_prev[0]), LC3_FABS(q_d_prev[1])); - next_max = array_max_abs(&q_d_prev[2], 3); - - if (cur_max > next_max) - { - maxPeak = block_cent; - peak = 1; - } - } - } - - for (i = 0; i < block_size; i++) - { - if ((LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i])) && LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i + 2])) - { - block_cent = 0; - for (j = i; j < i + block_size; j++) - { - block_cent += LC3_POW(q_d_prev[j], 2); - } - - if ((block_cent / block_size) > (thresh1 * mean_block_nrg)) - { - cur_max = array_max_abs(&q_d_prev[i], block_size); - prev_max = 0; - - for (k = i - block_size; k < i; k++) - { - if (k > 0) - { - prev_max = MAX(LC3_FABS(q_d_prev[k]), prev_max); - } - } - next_max = array_max_abs(&q_d_prev[i + block_size], block_size); - - if ((cur_max >= prev_max) && (cur_max > next_max)) - { - if (block_cent > (fac * maxPeak)) - { - peak = i + block_size - 1; - if (block_cent >= maxPeak) - { - maxPeak = block_cent; - } - } - } - } - } - } - - for (i = block_size; i < yLen - (2 * block_size); i++) - { - if ((LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i])) && LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i + 2])) - { - block_cent = 0; - for (j = i; j < i + block_size; j++) - { - block_cent += LC3_POW(q_d_prev[j], 2); - } - - if ((block_cent / block_size) > (thresh1 * mean_block_nrg)) - { - cur_max = array_max_abs(&q_d_prev[i], block_size); - prev_max = array_max_abs(&q_d_prev[i - block_size], block_size); - next_max = array_max_abs(&q_d_prev[i + block_size], block_size); - - if ((cur_max >= prev_max) && (cur_max > next_max)) - { - if (block_cent > (fac * maxPeak)) - { - peak = i + block_size - 1; - if (block_cent >= maxPeak) - { - maxPeak = block_cent; - } - } - } - } - } - } - - return peak; -} - diff --git a/lib_lc3plus/pc_classify_fx.c b/lib_lc3plus/pc_classify_fx.c new file mode 100644 index 000000000..28898f963 --- /dev/null +++ b/lib_lc3plus/pc_classify_fx.c @@ -0,0 +1,260 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "functions.h" + +#define BLOCK_SIZE 3 +#define THR1 8 +#define FAC 9830 /* 0.3 */ + +void peakDetector_fx(Word16 in_sig[], Word16 yLen, Word16 *xover); + +void processPCclassify_fx(Word16 pitch_present, Word16 frame_dms, Word16 q_old_d_fx[], Word16 q_old_res_fx[], + Word16 yLen, Word16 spec_inv_idx, Word16 stab_fac, Word16 *bfi) +{ + Dyn_Mem_Deluxe_In( + Word16 maxPitchBin, xover; + Counter i; + Word16 s, tmp16, full_nrg16, part_nrg16; + Word32 full_nrg, part_nrg; + ); + + /* Apply classifier only if lower than 2kHz signal */ + IF (sub(DEPR_i_mult(spec_inv_idx, 10), shl_pos(frame_dms, 2)) < 0 ) + { + IF (sub(stab_fac, 16384 /* 0.5 */) < 0) + { + *bfi = 1; + } + ELSE IF (sub(pitch_present, 1) == 0) + { + maxPitchBin = 8; move16(); + IF (sub(frame_dms, 50) == 0) + { + maxPitchBin = 4; move16(); + } + + /* avoid phase discontinuity in low frequencies */ + peakDetector_fx(q_old_d_fx, yLen, &xover); + test(); + IF (sub(spec_inv_idx, xover) < 0 || sub(spec_inv_idx, maxPitchBin) < 0) + { + *bfi = 1; + } + } + ELSE + { + s = getScaleFactor16(q_old_res_fx, yLen); + + part_nrg = 0; move32(); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4)); + part_nrg = L_mac0(part_nrg, tmp16, tmp16); /* exp = 2s - 8 */ + } + + full_nrg = part_nrg; move32(); + FOR (i = spec_inv_idx; i < yLen; i++) + { + tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4)); + full_nrg = L_mac0(full_nrg, tmp16, tmp16); /* exp = 2s - 8 */ + } + + s = getScaleFactor32_lc3plus(&full_nrg, 1); + full_nrg16 = extract_h(L_shl(full_nrg, s)); + part_nrg16 = extract_h(L_shl(part_nrg, s)); + + tmp16 = mult(full_nrg16, 9830 /* 0.3 */); + + IF (part_nrg16 < tmp16) + { + *bfi = 1; + } + } + } + + Dyn_Mem_Deluxe_Out(); +} + +void peakDetector_fx(Word16 in_sig[], Word16 yLen, Word16 *xover) +{ + Dyn_Mem_Deluxe_In( + Counter i, j; + Word16 tmp16, c, s, s2, mean_block_nrg16; + Word32 maxPeak, tmp32; + Word32 mean_block_nrg, block_cent; + Word16 cur_max, prev_max, next_max; + ); + + *xover = 0; + + s = getScaleFactor16(in_sig, yLen); + + mean_block_nrg = 0; move32(); + FOR (i = 0; i < yLen; i++) + { + tmp16 = shl_sat(in_sig[i], sub(s, 4)); + mean_block_nrg = L_mac0(mean_block_nrg, tmp16, tmp16); /* exp = 2s - 8 */ + } + + s2 = getScaleFactor16(&yLen, 1); + c = shl(yLen, s2); + mean_block_nrg16 = div_l(mean_block_nrg, c); /* exp = 2s - 8 - s2 - 1 */ + mean_block_nrg = L_shl(L_mult0(mean_block_nrg16, BLOCK_SIZE * THR1), add(4, s2)); /* exp = 2s - 5 */ + + maxPeak = 0; move32(); + c = sub(yLen, 2 * BLOCK_SIZE); + + test(); + IF (abs_s(in_sig[0]) >= abs_s(in_sig[1])) + { + block_cent = 0; move32(); + FOR (j = 0; j <= 1; j++) + { + tmp16 = shl_sat(in_sig[j], sub(s, 2)); + block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */ + } + block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */ + + IF (L_sub(block_cent, mean_block_nrg) > 0) + { + cur_max = abs_s(in_sig[0]); + cur_max = MAX(abs_s(in_sig[1]), cur_max); + + next_max = abs_s(in_sig[-1 + BLOCK_SIZE]); + next_max = MAX(abs_s(in_sig[-1 + BLOCK_SIZE + 1]), next_max); + next_max = MAX(abs_s(in_sig[-1 + BLOCK_SIZE + 2]), next_max); + + IF (sub(cur_max, next_max) > 0) + { + maxPeak = block_cent; move32(); + *xover = 1; + } + } + } + + FOR (i = 0; i < BLOCK_SIZE; i++) + { + test(); + IF (abs_s(in_sig[i + 1]) >= abs_s(in_sig[i]) && abs_s(in_sig[i + 1]) >= abs_s(in_sig[i + 2])) + { + block_cent = 0; move32(); + FOR (j = 0; j < BLOCK_SIZE; j++) + { + tmp16 = shl_sat(in_sig[i + j], sub(s, 2)); + block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */ + } + block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */ + + IF (L_sub(block_cent, mean_block_nrg) > 0) + { + cur_max = abs_s(in_sig[i]); + cur_max = MAX(abs_s(in_sig[i + 1]), cur_max); + cur_max = MAX(abs_s(in_sig[i + 2]), cur_max); + + prev_max = 0; move16(); + FOR (j = i - BLOCK_SIZE; j <= i - 1; j++) + { + IF (j > 0) + { + prev_max = MAX(abs_s(in_sig[j]), prev_max); + } + } + + next_max = abs_s(in_sig[i + BLOCK_SIZE]); + next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 1]), next_max); + next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 2]), next_max); + + test(); + IF (sub(cur_max, prev_max) >= 0 && sub(cur_max, next_max) > 0) + { + IF (L_sub(block_cent, maxPeak) >= 0) + { + maxPeak = block_cent; move32(); + *xover = sub(add(i, BLOCK_SIZE), 1); + } + ELSE + { + tmp32 = L_mult(FAC, extract_h(maxPeak)); + + tmp16 = extract_l(L_shr(maxPeak, 1)); + tmp16 = s_and(tmp16, 0x7fff); + tmp16 = mult(FAC, tmp16); + tmp32 = L_add_sat(tmp32, tmp16); + + IF (L_sub(block_cent, tmp32) > 0) + { + *xover = sub(add(i, BLOCK_SIZE), 1); + } + } + } + } + } + } + + FOR (i = BLOCK_SIZE; i <= c; i++) + { + test(); + IF (abs_s(in_sig[i + 1]) >= abs_s(in_sig[i]) && abs_s(in_sig[i + 1]) >= abs_s(in_sig[i + 2])) + { + block_cent = 0; move32(); + FOR (j = 0; j < BLOCK_SIZE; j++) + { + tmp16 = shl_sat(in_sig[i + j], sub(s, 2)); + block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */ + } + block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */ + + IF (L_sub(block_cent, mean_block_nrg) > 0) + { + cur_max = abs_s(in_sig[i]); + cur_max = MAX(abs_s(in_sig[i + 1]), cur_max); + cur_max = MAX(abs_s(in_sig[i + 2]), cur_max); + + prev_max = abs_s(in_sig[i - BLOCK_SIZE]); + prev_max = MAX(abs_s(in_sig[i - BLOCK_SIZE + 1]), prev_max); + prev_max = MAX(abs_s(in_sig[i - BLOCK_SIZE + 2]), prev_max); + + next_max = abs_s(in_sig[i + BLOCK_SIZE]); + next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 1]), next_max); + next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 2]), next_max); + + test(); + IF (sub(cur_max, prev_max) >= 0 && sub(cur_max, next_max) > 0) + { + IF (L_sub(block_cent, maxPeak) >= 0) + { + maxPeak = block_cent; move32(); + *xover = sub(add(i, BLOCK_SIZE), 1); + } + ELSE + { + tmp32 = L_mult(FAC, extract_h(maxPeak)); + + tmp16 = extract_l(L_shr(maxPeak, 1)); + tmp16 = s_and(tmp16, 0x7fff); + tmp16 = mult(FAC, tmp16); + tmp32 = L_add_sat(tmp32, tmp16); + + IF (L_sub(block_cent, tmp32) > 0) + { + *xover = sub(add(i, BLOCK_SIZE), 1); + } + } + } + } + } + } + + Dyn_Mem_Deluxe_Out(); +} + + diff --git a/lib_lc3plus/pc_main.c b/lib_lc3plus/pc_main.c deleted file mode 100644 index 6ee2bc072..000000000 --- a/lib_lc3plus/pc_main.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processPcMain_fl(LC3_INT32 *bfi, LC3PLUS_Dec* decoder, LC3_FLOAT *sqQdec, DecSetup* h_DecSetup, LC3_INT32 pitch_present, LC3_FLOAT stab_fac, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 fac_ns_idx, pcState *statePC, LC3_INT32 spec_inv_idx, LC3_INT32 yLen) -{ - LC3_FLOAT fac; - - /* PC Classifier */ - if (*bfi == 2) - { - processPcClassify_fl(pitch_present, decoder->frame_dms, h_DecSetup->PlcSetup.q_d_prev, statePC->q_old_res, decoder->yLen, h_DecSetup->spec_inv_idx, stab_fac, bfi); - } - - /* PC Apply */ - if (*bfi == 2) - { - processPcApply_fl(sqQdec, statePC->q_old_res, h_DecSetup->PlcSetup.q_d_prev, h_DecSetup->spec_inv_idx, decoder->yLen, gg_idx, gg_idx_off, &statePC->prev_gg, &fac, &statePC->ns_nbLostCmpt_pc); - } - - /* PC Update */ - if (*bfi != 1) - { - processPcUpdate_fl(*bfi, sqQdec, gg_idx, gg_idx_off, decoder->rframe, &h_DecSetup->BW_cutoff_idx_nf, &h_DecSetup->prev_BW_cutoff_idx_nf, fac_ns_idx, &h_DecSetup->prev_fac_ns, &fac, statePC->q_old_res, &statePC->prev_gg, spec_inv_idx, yLen); - } - - /* Reset counter */ - if (*bfi == 0) - { - statePC->ns_nbLostCmpt_pc = 0; - } -} - diff --git a/lib_lc3plus/pc_main_fx.c b/lib_lc3plus/pc_main_fx.c new file mode 100644 index 000000000..708f79d74 --- /dev/null +++ b/lib_lc3plus/pc_main_fx.c @@ -0,0 +1,57 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "functions.h" + +void processPCmain_fx(Word16 rframe, Word16 *bfi, Word16 yLen, Word16 frame_dms, Word16 q_old_res_fx[], + Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 q_old_d_fx[], Word16 spec_inv_idx, + Word16 pitch_present, Word16 stab_fac, Word32 q_d_fx[], Word16 *q_fx_exp, + Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e, Word16 *BW_cutoff_idx_nf, + Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 *pc_nbLostFramesInRow) +{ + Dyn_Mem_Deluxe_In( + Word16 fac, fac_e; + ); + + fac = 32767; fac_e = 0; + + IF (sub(*bfi, 2) == 0) + { + processPCclassify_fx(pitch_present, frame_dms, q_old_d_fx, q_old_res_fx, yLen, spec_inv_idx, stab_fac, bfi); + } + + IF (sub(*bfi, 2) == 0) + { + processPCapply_fx(yLen, q_old_res_fx, q_old_res_fx_exp, q_res_fx, q_old_d_fx, spec_inv_idx, + &fac, &fac_e, q_d_fx, q_fx_exp, gg_idx, gg_idx_off, *prev_gg, *prev_gg_e, pc_nbLostFramesInRow); + } + + IF (sub(*bfi, 1) != 0) + { + processPCupdate_fx(*bfi, yLen, q_old_res_fx, q_old_res_fx_exp, q_res_fx, spec_inv_idx, gg_idx, gg_idx_off, prev_gg, + prev_gg_e, rframe, BW_cutoff_idx_nf, prev_BW_cutoff_idx_nf, fac_ns_idx, prev_fac_ns_fx, fac, fac_e); + } + + if (*bfi == 0) + { + *pc_nbLostFramesInRow = 0; move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + + diff --git a/lib_lc3plus/pc_update.c b/lib_lc3plus/pc_update.c deleted file mode 100644 index e57016d40..000000000 --- a/lib_lc3plus/pc_update.c +++ /dev/null @@ -1,38 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processPcUpdate_fl(LC3_INT32 bfi, LC3_FLOAT *q_res, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 rframe, LC3_INT32 *BW_cutoff_idx_nf, LC3_INT32 *prev_BW_cutoff_idx_nf, - LC3_INT32 fac_ns_idx, LC3_FLOAT *prev_fac_ns, LC3_FLOAT *fac, LC3_FLOAT *q_old_res, LC3_FLOAT *prev_gg, LC3_INT32 spec_inv_idx, LC3_INT32 yLen) -{ - LC3_FLOAT gg; - - gg = LC3_POW(10.0, ((LC3_FLOAT) (gg_idx + gg_idx_off)) / 28.0); - *prev_gg = gg; - move_float(q_old_res, q_res, yLen); - - if (rframe == 0) - { - *prev_BW_cutoff_idx_nf = *BW_cutoff_idx_nf; - *prev_fac_ns = (8.0 - (LC3_FLOAT) fac_ns_idx) / 16.0; - } else if ((bfi == 2) && (*BW_cutoff_idx_nf != *prev_BW_cutoff_idx_nf) && (spec_inv_idx < yLen)) - { - *BW_cutoff_idx_nf = *prev_BW_cutoff_idx_nf; - *prev_fac_ns = *prev_fac_ns * (*fac); - *prev_fac_ns = MAX(*prev_fac_ns, (8.0 - 7.0) / 16.0); - *prev_fac_ns = MIN(*prev_fac_ns, (8.0 - 0.0) / 16.0); - } - -} - diff --git a/lib_lc3plus/pc_update_fx.c b/lib_lc3plus/pc_update_fx.c new file mode 100644 index 000000000..17b719bcd --- /dev/null +++ b/lib_lc3plus/pc_update_fx.c @@ -0,0 +1,148 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "functions.h" + +#ifdef ENABLE_HR_MODE + +void Copy_Scale_sig_32(const Word32 x[], /* i : signal to scale input Qx */ + Word16 y[], /* o : scaled signal output Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Counter i; + Word16 tmp; + + if (exp0 == 0) + { + for (i = 0; i < lg; i++) + { + y[i] = extract_h(x[i]); + } + + return; + } + + tmp = s_max(exp0, -31); + tmp = s_min(tmp, 31); + + for (i = 0; i < lg; i++) + { + y[i] = extract_h(L_shr_r(x[i], -tmp)); + } +} +#endif + +void processPCupdate_fx(Word16 bfi, Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 spec_inv_idx, Word16 gg_idx, Word16 gg_idx_off, + Word16 *prev_gg, Word16 *prev_gg_e, Word16 rframe, Word16 *BW_cutoff_idx_nf, + Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 fac, + Word16 fac_e) +{ + Word16 global_gain, global_gain_e, s, s2, s3, tmp16; + Word32 tmp32; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Word16 global_gain, global_gain_e, s, s2, s3, tmp16; + Word32 tmp32; + }; + Dyn_Mem_In("processPCupdate_fx", sizeof(struct _dynmem)); +#endif + + tmp32 = L_shl_pos(L_mult0(add(gg_idx, gg_idx_off), 0x797D), 7); + global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); + global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000))); + + *prev_gg = global_gain; move16(); + *prev_gg_e = global_gain_e; move16(); + +#ifdef ENABLE_HR_MODE + s = getScaleFactor32_lc3plus(q_res_fx, spec_inv_idx); /* exp = 0 */ +#else + s = getScaleFactor16(q_res_fx, spec_inv_idx); /* exp = 0 */ +#endif + + IF (bfi == 0) + { + *q_old_res_fx_exp = negate(s); +#ifdef ENABLE_HR_MODE + Copy_Scale_sig_32(q_res_fx, q_old_res_fx, yLen, s); + *q_old_res_fx_exp = *q_old_res_fx_exp + 16; +#else + Copy_Scale_sig(q_res_fx, q_old_res_fx, yLen, s); +#endif + } + ELSE + { +#ifdef ENABLE_HR_MODE + s2 = getScaleFactor32_lc3plus(&q_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */ + IF (s2 == 0) + s2 = 16; + s3 = add(s, *q_old_res_fx_exp); + IF (sub(s3, s2) > 0) + { + tmp16 = sub(s3, s2); + s = sub(s, tmp16); + } + s2 = add(s, *q_old_res_fx_exp); + *q_old_res_fx_exp = negate(s) + 16; + + + if (s2 > -32) + { + Copy_Scale_sig_32(&q_res_fx[spec_inv_idx], &q_old_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx), s2); + } +#else + s2 = getScaleFactor16(&q_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */ + s3 = add(s, *q_old_res_fx_exp); + IF (sub(s3, s2) > 0) + { + tmp16 = sub(s3, s2); + s = sub(s, tmp16); + } + s2 = add(s, *q_old_res_fx_exp); + *q_old_res_fx_exp = negate(s); + + s = s_max(s_min(s, 15), -15); + s2 = s_max(s_min(s2, 15), -15); + Copy_Scale_sig(q_res_fx, q_old_res_fx, spec_inv_idx, s); + Copy_Scale_sig(&q_res_fx[spec_inv_idx], &q_old_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx), s2); +#endif + } + + IF (rframe == 0) + { + *prev_BW_cutoff_idx_nf = *BW_cutoff_idx_nf; + *prev_fac_ns_fx = shl_pos(sub(8, fac_ns_idx), 11); + } + ELSE IF(sub(bfi, 2) == 0 && sub(*BW_cutoff_idx_nf, *prev_BW_cutoff_idx_nf) != 0 + && sub(spec_inv_idx, yLen) < 0) + { + *BW_cutoff_idx_nf = *prev_BW_cutoff_idx_nf; + *prev_fac_ns_fx = shl_sat(mult(*prev_fac_ns_fx, fac), fac_e); + *prev_fac_ns_fx = s_max(*prev_fac_ns_fx, 2048); + *prev_fac_ns_fx = s_min(*prev_fac_ns_fx, 16384); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/per_band_energy.c b/lib_lc3plus/per_band_energy.c deleted file mode 100644 index 5785ef82b..000000000 --- a/lib_lc3plus/per_band_energy.c +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d) -{ - LC3_INT i, j, start, stop, maxBwBin; - LC3_FLOAT sum; - -#ifdef ENABLE_HR_MODE_FL - if (hrmode) - { - maxBwBin = MAX_BW_HR; - } - else -#else - UNUSED(hrmode); -#endif - { - maxBwBin = MAX_BW; - } - switch (frame_dms) - { -#ifdef ENABLE_2_5MS_MODE - case 25: - maxBwBin = maxBwBin >> 2; - break; -#endif -#ifdef ENABLE_5MS_MODE - case 50: - maxBwBin = maxBwBin >> 1; - break; -#endif -#ifdef CR8_G_ADD_75MS - case 75: - maxBwBin = (maxBwBin >> 2) * 3; - break; -#endif - } - - for (i = 0; i < bands_number; i++) { - sum = 0; - start = acc_coeff_per_band[i]; - stop = MIN(acc_coeff_per_band[i + 1], maxBwBin); - - for (j = start; j < stop; j++) { - sum += d[j] * d[j]; - } - - if (stop - start > 0) { - sum = sum / (LC3_FLOAT)(stop - start); - } - d2[i] = sum; - } -} diff --git a/lib_lc3plus/per_band_energy_fx.c b/lib_lc3plus/per_band_energy_fx.c new file mode 100644 index 000000000..14e853212 --- /dev/null +++ b/lib_lc3plus/per_band_energy_fx.c @@ -0,0 +1,275 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" +#include "rom_basop_util.h" + +void processPerBandEnergy_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word32 *d_fx, Word16 d_fx_exp, + const Word16 *band_offsets, Word16 fs_idx, Word16 n_bands, Word16 linear, Word16 frame_dms, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + Dyn_Mem_Deluxe_In(Counter i, k, band; Word16 s; Word16 s1; Word16 s2; Word32 nrg; Word16 smax; Word16 tmp16; + Word16 nbands; Word16 maxBwBin; Word16 stopBand; Word16 bandsOffsetOne; Word16 bandsOffsetTwo; + Word16 * d2_band_fx_exp;); + + + d2_band_fx_exp = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER_PLC bytes */ + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + maxBwBin = MAX_BW_HR; + fs_idx = fs_idx + 1; + move16(); + } + else +#endif + { + maxBwBin = MAX_BW; + move16(); + } + + SWITCH (frame_dms) + { + case 25: maxBwBin = maxBwBin >> 2; move16(); + { + bandsOffsetOne = bands_offset_with_one_max_2_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_2_5ms[fs_idx]; + move16(); + } + BREAK; + case 50: maxBwBin = maxBwBin >> 1; move16(); + { + bandsOffsetOne = bands_offset_with_one_max_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_5ms[fs_idx]; + move16(); + } + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + maxBwBin = (maxBwBin >> 2) * 3; move16(); + bandsOffsetOne = bands_offset_with_one_max_7_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_7_5ms[fs_idx]; + move16(); + BREAK; +#endif + default: /* 100 */ + { + bandsOffsetOne = bands_offset_with_one_max[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max[fs_idx]; + move16(); + } + BREAK; + } + + IF (sub(linear, 1) == 0) + { + + #ifdef ENABLE_HR_MODE + if (hrmode) + { + fs_idx = fs_idx - 1; + } + #endif + + SWITCH (frame_dms) + { + case 25: + bandsOffsetOne = bands_offset_with_one_max_lin_2_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_lin_2_5ms[fs_idx]; + move16(); + BREAK; + case 50: + bandsOffsetOne = bands_offset_with_one_max_lin_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_lin_5ms[fs_idx]; + move16(); + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + bandsOffsetOne = bands_offset_with_one_max_lin_7_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_lin_7_5ms[fs_idx]; + move16(); + BREAK; +#endif + case 100: + bandsOffsetOne = bands_offset_with_one_max_lin[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_lin[fs_idx]; + move16(); + BREAK; + } + } + + /* start processing with band offsets == 1 */ + FOR (band = 0; band < bandsOffsetOne; band++) + { + ASSERT((band_offsets[band + 1] - band_offsets[band]) == 1); + ASSERT(band < maxBwBin); + + s2 = 15; + move16(); + s = norm_l(d_fx[band]); + if (d_fx[band] != 0) + s2 = s_min(s2, s); + + tmp16 = extract_h(L_shl_pos(d_fx[band], s2)); + + d2_fx[band] = L_mult0(tmp16, tmp16); + move32(); + d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1)); + move16(); + } + + /* start processing with band offsets == 2 */ + i = bandsOffsetOne; + move16(); + FOR (; band < bandsOffsetTwo; band++) + { + ASSERT((band_offsets[band + 1] - band_offsets[band]) == 2); + IF (sub(add(i, 1), maxBwBin) >= 0) + { + IF (sub(i, maxBwBin) >= 0) + { + d2_fx[band] = 0; + move32(); + d2_band_fx_exp[band] = sub(1, shl_pos(15, 1)); + move16(); + } + ELSE + { + s2 = 15; + move16(); + s = norm_l(d_fx[band]); + if (d_fx[band] != 0) + s2 = s_min(s2, s); + + tmp16 = extract_h(L_shl_pos(d_fx[band], s2)); + + d2_fx[band] = L_mult0(tmp16, tmp16); + move32(); + d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1)); + move16(); + } + } + ELSE + { + ASSERT(i + 1 < maxBwBin); + + s2 = 15; + move16(); + s = norm_l(d_fx[i]); + if (d_fx[i] != 0) + s2 = s_min(s2, s); + s = norm_l(d_fx[i + 1]); + if (d_fx[i + 1] != 0) + s2 = s_min(s2, s); + + tmp16 = extract_h(L_shl_pos(d_fx[i], s2)); + nrg = L_mult0(tmp16, tmp16); + nrg = L_min(nrg, 0x3FFFFFFF); + tmp16 = extract_h(L_shl_pos(d_fx[i + 1], s2)); + + d2_fx[band] = L_shr_pos(L_mac0(nrg, tmp16, tmp16), 1); + move32(); + d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1)); + move16(); + } + i = add(i, 2); + } + + /* proceed with band offsets > 2 */ + FOR (; band < n_bands; band++) + { + /* normalization */ + k = i; + move16(); + s1 = 15; + move16(); + + stopBand = s_min(band_offsets[band + 1], maxBwBin); + FOR (; k < stopBand; k++) + { + s = norm_l(d_fx[k]); + if (d_fx[k] != 0) + s1 = s_min(s1, s); + } + + nbands = sub(band_offsets[band + 1], band_offsets[band]); +#ifdef ENABLE_HR_MODE + if (nbands < 32) + { + nbands = s_min(s_max(0, nbands), 31); + /* specify headroom, it can be reduced by one due to use of L_mac0 */ + s2 = sub(s1, bands_nrg_scale[nbands]); + } + else + { + /* Active only in the 96 kHz case */ + s2 = sub(s1, 5); + } +#else + ASSERT(nbands < 32); + nbands = s_min(s_max(0, nbands), 31); + /* specify headroom, it can be reduced by one due to use of L_mac0 */ + s2 = sub(s1, bands_nrg_scale[nbands]); +#endif + + /* calculate energy per band */ + nrg = 0; + move32(); + + FOR (; i < stopBand; i++) + { + tmp16 = extract_h(L_shl(d_fx[i], s2)); + nrg = L_mac0(nrg, tmp16, tmp16); + } + i = band_offsets[band + 1]; + + /* calculate mean value of energy */ + nrg = Mpy_32_16_lc3plus(nrg, InvIntTable[nbands]); + + /* store normalized energy */ + s = norm_l(nrg); + d2_fx[band] = L_shl_pos(nrg, s); + move32(); + d2_band_fx_exp[band] = sub(1, add(shl_pos(s2, 1), s)); + move16(); + } + + /* Determine maximum exponent and rescale band energies */ + smax = -31; + move16(); + FOR (band = 0; band < n_bands; band++) + { + smax = s_max(smax, d2_band_fx_exp[band]); + } + FOR (band = 0; band < n_bands; band++) + { + d2_fx[band] = L_shr_pos(d2_fx[band], s_min(sub(smax, d2_band_fx_exp[band]), 31)); + move32(); + } + + /* Save exponent for all bands */ + *d2_fx_exp = s_max(add(shl_pos(d_fx_exp, 1), smax), -32); + move16(); + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/plc_apply_fx.c b/lib_lc3plus/plc_apply_fx.c new file mode 100644 index 000000000..9430d155e --- /dev/null +++ b/lib_lc3plus/plc_apply_fx.c @@ -0,0 +1,419 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "functions.h" + +void processPLCapply_fx( +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 *concealMethod, +#else + Word16 concealMethod, +#endif + Word16 nbLostFramesInRow, Word16 bfi, Word16 prev_bfi, + Word16 frame_length, Word16 la_zeroes, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 x_fx[], Word16 ola_mem[], + Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, Word16 *damping, Word16 old_pitch_int, + Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, Word16 frame_dms, AplcSetup *plcAd, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , Word32 rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , Word16 *alpha_type_2_table +#endif + ) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word32 *d2_fx; + Word32 *q_old_d_fx32; + Word32 *r_fx; + Word32 *tdc_A_32; + Word16 d2_fx_exp; + Word16 r_fx_exp; + Word16 Q_syn; + Word8 * buffer_perBandEnergy, *buffer_preEmphasis, *buffer_InverseODFT, *buffer_Levinson, + *buffer_tdac, *buffer_phecu; + Word16 y_e; /*exponent of L_ecu_rec */ + Word16 tmp_is_trans[2]; /* may be changed to a single variable */ + Word16 env_stab; + + Word16 n_bands, prev_bfi_plc2; + const Word16 *band_offsets; + Word32 * L_ecu_rec; /* local xtda output is MAX_LEN -> input buffer, + as tmp buffer for w32 fft MAX_LPROT */ + ); +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 consecutiveLostThreshold = 0; +#endif + +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + Word16 thresh_tdc_cnt; + Word16 thresh_ns_cnt; + Word16 thresh_tdc_ns_cnt; +#endif + + band_offsets = NULL; + + d2_fx = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_BANDS_NUMBER_PLC */ + q_old_d_fx32 = (Word32 *)scratchAlign(d2_fx, sizeof(*d2_fx) * MAX_BANDS_NUMBER_PLC); /* Size = 4 * MAX_BW */ + r_fx = (Word32 *)scratchAlign(d2_fx, sizeof(*d2_fx) * MAX_BANDS_NUMBER_PLC); /* Size = 4 * (M + 1) */ + tdc_A_32 = (Word32 *)scratchAlign(r_fx, sizeof(*r_fx) * (M + 1)); /* Size = 4 * (M + 1) */ + + L_ecu_rec = (Word32 *)scratchAlign(tdc_A_32, sizeof(*tdc_A_32) * (M + 1)); /* Size = 4 * MAX_LPROT bytes */ + + buffer_perBandEnergy = + (Word8 *)scratchAlign(q_old_d_fx32, sizeof(*q_old_d_fx32) * (MAX_LEN)); /* Size = 2 * MAX_BANDS_NUMBER_PLC */ + buffer_preEmphasis = + (Word8 *)scratchAlign(tdc_A_32, sizeof(*tdc_A_32) * (M + 1)); /* Size = 2 * MAX_BANDS_NUMBER_PLC */ + buffer_InverseODFT = buffer_preEmphasis; /* Size = 640 bytes */ + buffer_Levinson = buffer_preEmphasis; /* Size = 4 * (M + 1) */ + + buffer_tdac = scratchBuffer; /* Size = 2 * MAX_LEN bytes */ + buffer_phecu = scratchBuffer; /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */ + /* Buffers overlap since they are not used at once */ + + + UNUSED(ns_cum_alpha); + UNUSED(ns_seed); + + /* Apply/Prepare PLC in bfi-case */ + IF (sub(bfi, 1) == 0) + { + +#ifdef CR8_A_PLC_FADEOUT_TUNING + SWITCH(frame_dms) + { + case 25: + consecutiveLostThreshold = 16; +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT; + thresh_ns_cnt = THRESH_025_DMS_NS_CNT; + thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT; +#endif + break; + case 50: consecutiveLostThreshold = 8; +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + thresh_tdc_cnt = THRESH_050_DMS_TDC_CNT; + thresh_ns_cnt = THRESH_050_DMS_NS_CNT; + thresh_tdc_ns_cnt = THRESH_050_DMS_TDC_NS_CNT; +#endif + break; + case 75: consecutiveLostThreshold = 6; +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + thresh_tdc_cnt = THRESH_075_DMS_TDC_CNT; + thresh_ns_cnt = THRESH_075_DMS_NS_CNT; + thresh_tdc_ns_cnt = THRESH_075_DMS_TDC_NS_CNT; +#endif + break; + case 100: consecutiveLostThreshold = 4; +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + thresh_tdc_cnt = THRESH_100_DMS_TDC_CNT; + thresh_ns_cnt = THRESH_100_DMS_NS_CNT; + thresh_tdc_ns_cnt = THRESH_100_DMS_TDC_NS_CNT; +#endif + break; + default: assert(0); + } + + IF (sub(fs_idx, 2) == 0 || sub(fs_idx, 4) >= 0) + { +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + if (sub(plcAd->longterm_counter_plcTdc, thresh_tdc_cnt) < 0){ + plcAd->plc_fadeout_type = 1; + } + else if (sub(plcAd->longterm_counter_plcNsAdv, thresh_ns_cnt) < 0){ + plcAd->plc_fadeout_type = 1; + } + else if (sub(plcAd->longterm_counter_plcTdc + plcAd->longterm_counter_plcNsAdv, thresh_tdc_ns_cnt) < 0){ + plcAd->plc_fadeout_type = 1; + } + else { + plcAd->plc_fadeout_type = 0; + } + +#else + IF (((sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC1_FADEOUT, plcAd->longterm_counter_plcTdc), SHIFT1_FADEOUT)) < 0) || + (sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC1_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT1_FADEOUT)) < 0)) && + (sub(plcAd->longterm_counter_plcTdc, L_shr_pos(Mpy_32_16_lc3plus(FAC2_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT2_FADEOUT)) < 0)) + { + plcAd->plc_fadeout_type = 0; + } + ELSE + { + IF ((sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC3_FADEOUT, plcAd->longterm_counter_plcTdc), SHIFT3_FADEOUT)) > 0) || + (sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC3_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT3_FADEOUT)) > 0)) + { + plcAd->plc_fadeout_type = 1; + } ELSE { + plcAd->plc_fadeout_type = 0; + } + } +#endif + + + env_stab = norm_s(plcAd->longterm_analysis_counter_max); + IF(sub(shl_pos(plcAd->overall_counter, env_stab), mult(shl_pos(plcAd->longterm_analysis_counter_max, env_stab), PLC_LONGTERM_ANALYSIS_STARTUP_FILL)) < 0) + { + plcAd->plc_fadeout_type = 0; + } + +#ifndef CR9_H_REMOVE_SWITCH_TO_PLC_NS + IF (sub(nbLostFramesInRow, consecutiveLostThreshold) >= 0 && sub(plcAd->plc_fadeout_type, 1) == 0) + { + IF (sub(*concealMethod, LC3_CON_TEC_TDPLC) == 0) + { + *concealMethod = LC3_CON_TEC_NS_ADV; + } + } +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + IF (L_sub(rel_pitch_change,REL_PITCH_THRESH) > 0 && sub(hrmode,1) == 0 && (sub(frame_dms,50) == 0 || sub(frame_dms,25) == 0)){ + plcAd->plc_fadeout_type = 2;move16(); + } ELSE +#endif + IF((sub(nbLostFramesInRow, consecutiveLostThreshold) < 0) && (*concealMethod != LC3_CON_TEC_PHASE_ECU)) + { + plcAd->plc_fadeout_type = 0; + } + } ELSE { + plcAd->plc_fadeout_type = 0; /*fs_idx == 0,1,3 */ + } +#endif /* CR8_A_PLC_FADEOUT_TUNING */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING + SWITCH (*concealMethod) +#else + SWITCH (concealMethod) +#endif + { + case LC3_CON_TEC_PHASE_ECU: + ASSERT(frame_dms == 100); + /* call phaseEcu */ + env_stab = 32767; move16(); /* 1.0=stable , 0.0=dynamic Q15*/ + tmp_is_trans[0] = plcAd->PhECU_short_flag_prev; move16(); + tmp_is_trans[1] = plcAd->PhECU_short_flag_prev; move16(); + + ASSERT(prev_bfi == 0 || prev_bfi == 1|| prev_bfi == 2); /*PC prev_bfi has three states */ + prev_bfi_plc2 = prev_bfi; move16(); + if (sub(prev_bfi_plc2, 2) == 0) + { + prev_bfi_plc2 = 0; move16(); + } + + ASSERT(prev_bfi_plc2 == 0 || prev_bfi_plc2 == 1); /*PhEcu does not accept prev_bfi == 2 */ + IF(prev_bfi_plc2 == 0) + { /* convert pitch lag info at current fs to a normalized fractional bin-frequency */ + plcAd->PhECU_f0hzLtpBinQ7 = plc_phEcuSetF0Hz_fx(fs_idx, old_pitch_int, old_pitch_fr); move16(); + + + + /* first bfi frame calc decoded pcm energy 16,16 ms, in 26 ms buffer separated by 10 ms*/ + + { /* compute energy normalization needed for concealment method 2 Xavg and transient analysis */ + + /* left */ + processPLCUpdateXFP_w_E_hist_fx(0, 0, + &(plcAd->x_old_tot_fx[ sub(plcAd->max_len_pcm_plc , add(num_FsByResQ0[fs_idx],rectLengthTab[fs_idx] )) ]), plcAd->q_fx_old_exp,0, + + fs_idx, + &plcAd->PhECU_L_oold_xfp_w_E_fx, &plcAd->PhECU_oold_xfp_w_E_exp_fx, + &plcAd->PhECU_L_old_xfp_w_E_fx, &plcAd->PhECU_old_xfp_w_E_exp_fx, + &plcAd->PhECU_oold_Ltot_exp_fx, &plcAd->PhECU_old_Ltot_exp_fx); + + /* right */ + processPLCUpdateXFP_w_E_hist_fx(0, 0, plcAd->PhECU_xfp_fx, plcAd->PhECU_xfp_exp_fx, + plcAd->PhECU_margin_xfp, fs_idx, + &plcAd->PhECU_L_oold_xfp_w_E_fx, &plcAd->PhECU_oold_xfp_w_E_exp_fx, + &plcAd->PhECU_L_old_xfp_w_E_fx, &plcAd->PhECU_old_xfp_w_E_exp_fx, + &plcAd->PhECU_oold_Ltot_exp_fx, &plcAd->PhECU_old_Ltot_exp_fx); + } + } + + hq_phase_ecu_fx( + plcAd->PhECU_xfp_fx, /* i : only valid first Bfi frame , buffer of previous synt signal length */ + L_ecu_rec, /* o : reconstructed frame in folded tda domain xtda Word32 Q x */ + &plcAd->PhECU_time_offs, /* i/o: Sample offset for consecutive frame losses*/ + plcAd->PhECU_X_sav_fx, /* i(prev_bfi==1)/o(prev_bfi==0): Stored Complex spectrum of prototype frame */ + &plcAd->PhECU_X_savQ_fx, /* i/o: Q value of stored spectrum */ + &plcAd->PhECU_num_plocs, /* i/o: Number of identified peaks */ + plcAd->PhECU_plocs, /* i/o: Peak locations Q0 */ + plcAd->PhECU_f0est, /* i/o: Interpolated peak locations Q16 */ + env_stab, /* i : Envelope stability parameter */ + plcAd->PhECU_f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */ + plcAd->norm_corrQ15_fx, /* i : correlation for lag at f0hzLtpBinQ7 */ + prev_bfi_plc2, /* i : indicating burst frame error */ + tmp_is_trans, /* i : flags indicating previous transient frames */ + plcAd->PhECU_mag_chg_1st, /* i/o: per band magnitude modifier for transients*/ + NULL, /* o: dbg per band magnitude modifier, incl. burst attenuation */ + plcAd->PhECU_Xavg, /* i/o: Frequency group average gain to fade to */ + &plcAd->PhECU_beta_mute, /* o : Factor for long-term mute */ + fs_idx, /* i : Encoded bandwidth "nb(0),WB,sWB,WB,FB" */ + frame_length, /* i : frame length */ + NULL , /* o : seed synch dbg */ + NULL , /* o : evolved Spectrum dbg */ + plcAd->PhECU_t_adv, /* i : time adjustment excluding time_offs */ + PhECU_wins[fs_idx][2], /* i: 2 ms initial part pre_tda = mdct-ana */ + PhECU_wins[fs_idx][1], /* i: 16 ms pretda combined part IWHR+MDCT-ana */ + PhECU_wins[fs_idx][0], + plcAd->PhECU_xfp_exp_fx, + plcAd->max_lprot, + plcAd->max_plocs, + plcAd->PhECU_L_oold_xfp_w_E_fx,plcAd->PhECU_oold_xfp_w_E_exp_fx, plcAd->PhECU_oold_Ltot_exp_fx, + plcAd->PhECU_oold_grp_shape_fx, + plcAd->PhECU_L_old_xfp_w_E_fx,plcAd->PhECU_old_xfp_w_E_exp_fx, plcAd->PhECU_old_Ltot_exp_fx, + plcAd->PhECU_old_grp_shape_fx, + plcAd->PhECU_margin_xfp, +#ifdef CR8_A_PLC_FADEOUT_TUNING + plcAd->plc_fadeout_type , /* i : fadeout scheme */ + &(plcAd->PhECU_nonpure_tone_flag), /* i/o : non-pure single tone indicator state */ +#endif + buffer_phecu); + + y_e = 18; move16(); /* the fixed exponent (exp) from Lecu_rec from PhaseECU is 18 */ + + Processing_ITDA_WIN_OLA( + L_ecu_rec, /* i: X_TDA buffer data = "y" DCT-IV output */ + &y_e, /* i/o: x_tda exponent "y_e" */ + w, /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + ola_mem, /* i/o: overlap add memory */ + ola_mem_exp, /* i/o: overlap add exponent */ + x_fx, /* o: time signal out */ + LowDelayShapes_n960_len[fs_idx], /* i: window length */ + frame_length, /* i: block size */ + sub(frame_length, LowDelayShapes_n960_la_zeroes[fs_idx]) /* i: overlap add buffer size */ + ); + *q_fx_exp = y_e; move16(); /* assign updated Q */ + BREAK; + + case LC3_CON_TEC_TDPLC: + IF (sub(nbLostFramesInRow, 1) == 0) + { + plcAd->tdc_fract = old_pitch_fr; move16(); + n_bands = s_min(frame_length, MAX_BANDS_NUMBER_PLC); + SWITCH (frame_dms) + { + case 25: + band_offsets = bands_offset_lin_2_5ms[fs_idx]; move16(); + IF (sub(fs_idx, 4) == 0) + { + n_bands = 60; move16(); + } + BREAK; + case 50: + band_offsets = bands_offset_lin_5ms[fs_idx]; move16(); + IF (sub(fs_idx, 2) == 0) + { + n_bands = 40; move16(); + } + BREAK; +# ifdef CR8_G_ADD_75MS + case 75: + band_offsets = bands_offset_lin_7_5ms[fs_idx]; move16(); +# ifdef ENABLE_HR_MODE + IF (sub(fs_idx, 5) != 0) + { +# endif + IF (sub(fs_idx, 3) != 0) + { + n_bands = 60; move16(); + } +# ifdef ENABLE_HR_MODE + } +# endif + BREAK; +# endif + case 100: + band_offsets = bands_offset_lin[fs_idx]; move16(); + BREAK; + } + + FOR (i = 0; i < yLen; i++) + { + q_old_d_fx32[i] = L_deposit_h(q_old_d_fx[i]); + } + + /* LPC Analysis */ + /* calculate per band energy*/ + processPerBandEnergy_fx(d2_fx, &d2_fx_exp, q_old_d_fx32, *q_old_fx_exp, band_offsets, fs_idx, n_bands, + 1, frame_dms, buffer_perBandEnergy +#ifdef ENABLE_HR_MODE + , hrmode +#endif + ); + + /* calculate pre-emphasis */ + processPreEmphasis_fx(d2_fx, &d2_fx_exp, fs_idx, n_bands, frame_dms, buffer_preEmphasis); + + /* inverse ODFT */ + processInverseODFT_fx(r_fx, &r_fx_exp, d2_fx, d2_fx_exp, n_bands, plcAd->tdc_lpc_order, buffer_InverseODFT); + + /* lag windowing */ + processLagwin_fx(r_fx, lag_win[fs_idx], plcAd->tdc_lpc_order); + + /* Levinson Durbin */ + processLevinson_fx(tdc_A_32, r_fx, plcAd->tdc_lpc_order, NULL, NULL, buffer_Levinson); + + /* 32Q27 -> 16Qx */ + processPLCLpcScaling_fx(tdc_A_32, plcAd->tdc_A, add(plcAd->tdc_lpc_order, 1)); + } + + /* call TD-PLC */ + /* Q_syn = plcAd->q_fx_old_exp; */ /* makes q_fx_old_exp + available in processTimeDomainConcealment_Apply_fx() for + debugging */ + processTimeDomainConcealment_Apply_fx( + old_pitch_int, plcAd->tdc_preemph_fac, plcAd->tdc_A, plcAd->tdc_lpc_order, plcAd->x_old_tot_fx, frame_length, frame_dms, + fs_idx, nbLostFramesInRow, sub(frame_length, la_zeroes), plcAd->stab_fac, &plcAd->tdc_fract, + &plcAd->tdc_seed, + &plcAd->tdc_gain_c, x_fx, &Q_syn, damping, + plcAd->max_len_pcm_plc, + plcAd->harmonicBuf_fx, plcAd->synthHist_fx, &plcAd->harmonicBuf_Q, scratchBuffer +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + , plcAd->plc_fadeout_type +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , alpha_type_2_table +#endif +); + + /* exponent of TD-PLC output */ + Q_syn = add(Q_syn, sub(15, plcAd->q_fx_old_exp)); + *q_fx_exp = sub(15, Q_syn); move16(); + + /* TDAC */ + processTdac_fx(ola_mem, ola_mem_exp, x_fx, *q_fx_exp, w, la_zeroes, frame_length, buffer_tdac); + BREAK; + + case LC3_CON_TEC_NS_ADV: + *q_fx_exp = *q_old_fx_exp; move16(); + + /* call Noise Substitution */ + processPLCNoiseSubstitution_fx(q_d_fx, q_old_d_fx, yLen); + + BREAK; + default: ASSERT(!"Unsupported PLC method!"); + } + } + + Dyn_Mem_Deluxe_Out(); +} + + diff --git a/lib_lc3plus/plc_classify.c b/lib_lc3plus/plc_classify.c deleted file mode 100644 index fe650f44b..000000000 --- a/lib_lc3plus/plc_classify.c +++ /dev/null @@ -1,335 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -#ifdef CR8_A_PLC_FADEOUT_TUNING - -static LC3_INT32 change_bit_at_position(LC3_INT32 value, LC3_UINT8 bit_position, LC3_INT8 bit) -{ - LC3_INT32 helper_mask = ~(1 << bit_position); - LC3_INT32 tmp = value & helper_mask; - tmp = tmp | (bit << bit_position); - return tmp; -} - -static void update_bit_and_byte_positions(LC3_INT16 longterm_analysis_counter_max_bytebuffer, LC3_INT8 *byte_position, LC3_INT8 *bit_position) -{ - if (*bit_position == 30) - { - *bit_position = 0; - - if ((*byte_position - longterm_analysis_counter_max_bytebuffer) < -1) - { - *byte_position = *byte_position + 1; - } else { - *byte_position = 0; - } - } else { - *bit_position = *bit_position + 1; - } -} - -static void array_insert_and_shift(LC3_INT32 *array, LC3_UINT8 value, LC3_INT16 longterm_analysis_counter_max, LC3_INT16 *overall_counter, LC3_INT8 *byte_position, LC3_INT8 *bit_position) -{ - LC3_INT32 current_byte = 0; - - if (overall_counter != NULL) - { - *overall_counter = MIN(*overall_counter + 1, longterm_analysis_counter_max); - } - - current_byte = array[*byte_position]; - - current_byte = change_bit_at_position(current_byte, *bit_position, value); - - array[*byte_position] = current_byte; -} - -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER -static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int length, LC3_INT16 *counter_tdc, LC3_INT16 *counter_ns, LC3_INT16 longterm_analysis_counter_max) -#else -static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int length, LC3_INT16 *counter_tdc, LC3_INT16 *counter_ns, LC3_INT16 *counter_phecu, LC3_INT16 overall_counter, LC3_INT16 longterm_analysis_counter_max) -#endif -{ - int i, k; - LC3_INT32 current_byte_tdc = 0, current_byte_ns = 0; - LC3_INT16 counter_loc_tdc = 0, counter_loc_ns = 0, counter_tmp = 0; - - for (i = length - 1; i >= 0; i--) - { - current_byte_tdc = array_tdc[i]; - current_byte_ns = array_ns[i]; - - for (k = 0; k < 30; k++) - { - counter_loc_tdc += ((current_byte_tdc >> k) & 1); - counter_loc_ns += ((current_byte_ns >> k) & 1); - counter_tmp++; - - /* Break from both loops if full 2s buffer has been evaluated */ - if (counter_tmp >= longterm_analysis_counter_max) - { - i = -1; - k = 30; - break; - } - } - } - - *counter_tdc = counter_loc_tdc; - *counter_ns = counter_loc_ns; -#ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - *counter_phecu = overall_counter - counter_loc_tdc - counter_loc_ns; -#endif -} -#endif - -static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr); -static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *bands_offset, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc); - -void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *nbLostCmpt, LC3_INT32 bfi, - LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 pitch_int, - LC3_INT32 fs, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 tilt, PlcAdvSetup *plcAd - , LC3_INT32 hrmode -) -{ - LC3_FLOAT sc, class; -#ifdef CR8_A_PLC_FADEOUT_TUNING - int fs_idx_tmp; -#endif - - if (plcAd) - { - *xcorr = 0; - } - -#ifdef CR8_A_PLC_FADEOUT_TUNING - fs_idx_tmp = FS2FS_IDX(fs); - /* Save statistics for 24 kHz, 48 kHz and 96 kHz */ - if ((bfi == 1) || ((bfi >= 0) && (bfi <= 2) && ((fs_idx_tmp == 2) || (fs_idx_tmp == 4) || (fs_idx_tmp == 5)))) /* Partial Concealment PC(bfi==2) requires allowing value 2 to pass thru as well */ -#else - if (bfi == 1) -#endif - { -#ifdef CR8_A_PLC_FADEOUT_TUNING - if (bfi == 1) - { - *nbLostCmpt = *nbLostCmpt + 1; - } -#else - *nbLostCmpt = *nbLostCmpt + 1; -#endif - - /* Use pitch correlation at ltpf integer lag if available */ -#ifdef CR8_A_PLC_FADEOUT_TUNING - if ((*nbLostCmpt == 1) || (bfi != 1) )/* PC(bfi==2) requires allowing 2 to pass thru as well */ -#else - if (*nbLostCmpt == 1) -#endif - { -#ifdef CR8_A_PLC_FADEOUT_TUNING - *concealMethod = 4; /* Noise Substitution */ - UNUSED(plcMeth); -#else - *concealMethod = plcMeth; // this is a dangerous mapping! -#endif - - /* Advanced PLC */ - if (pitch_int > 0) - { - *concealMethod = 3; /* Timedomain PLC assumed */ - plc_xcorr_lc(plcAd->pcmbufHist, plcAd->max_len_pcm_plc, pitch_int, framelength, frame_dms, fs, xcorr); - - spectral_centroid_lc(plcAd->scf_q_old, tilt, band_offsets, bands_number, framelength, fs, &sc); - class = *xcorr * 7640.0 / 32768.0 - sc - 5112.0 / 32768.0; - - if (class <= 0) - { - if (frame_dms == 100 && hrmode == 0) - { - *concealMethod = 2; /* PhaseEcu selected */ -#ifdef CR8_A_PLC_FADEOUT_TUNING - array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); - array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); -#endif - } - else - { -#ifndef CR9_G_PLC_NS_TDC_FIX - *concealMethod = 4; /* Noise Substitution */ -#endif -#ifdef CR8_A_PLC_FADEOUT_TUNING - array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); - array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); -#endif - } - } -#ifdef CR8_A_PLC_FADEOUT_TUNING - else { - array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 1, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); - array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); - } -#endif - } - else - { - *concealMethod = 4; /* Noise Substitution */ -#ifdef CR8_A_PLC_FADEOUT_TUNING - array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); - array_insert_and_shift(plcAd->plc_longterm_advc_ns, 1, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); -#endif - } - -#ifdef CR8_A_PLC_FADEOUT_TUNING -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, plcAd->longterm_analysis_counter_max); -#else - array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, &plcAd->longterm_counter_plcPhaseEcu, plcAd->overall_counter, plcAd->longterm_analysis_counter_max); -#endif - update_bit_and_byte_positions(plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); -#endif - } - } -} - -static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc) -{ - LC3_FLOAT gains_lin[M], gains_dee[M], numerator, denumerator; - LC3_INT32 i, j, sum, len, start, stop; - LC3_INT band_offsets_local[MAX_BANDS_NUMBER + 1]; - - numerator = 0; - - for (i = 0; i < M; i++) - { - gains_lin[i] = LC3_POW(2, gains[i]); - } - - for (i = 0; i < M; i++) - { - gains_dee[i] = gains_lin[i] / LC3_POW(10, i * (LC3_FLOAT) tilt / (LC3_FLOAT) (M - 1) / 10.0); - } - - if (bands_number == 64) - { - memmove(band_offsets_local, band_offsets, (bands_number + 1) * sizeof(LC3_INT)); - } - - if (bands_number < 32) - { - band_offsets_local[0] = 0; - j = 32 - bands_number; - for (i = bands_number - 1; i >= j; i--) - { - band_offsets_local[(i + j) * 2 + 1 + 1] = band_offsets[i + 1]; - band_offsets_local[(i + j) * 2 + 0 + 1] = band_offsets[i + 1]; - } - for (i = j - 1; i >= 0; i--) - { - band_offsets_local[i * 4 + 3 + 1] = band_offsets[i + 1]; - band_offsets_local[i * 4 + 2 + 1] = band_offsets[i + 1]; - band_offsets_local[i * 4 + 1 + 1] = band_offsets[i + 1]; - band_offsets_local[i * 4 + 0 + 1] = band_offsets[i + 1]; - } - } - else - if (bands_number < 64) - { - band_offsets_local[0] = 0; - j = 64 - bands_number; - for (i = bands_number - 1; i >= j; i--) - { - band_offsets_local[i + j + 1] = band_offsets[i + 1]; - } - for (i = j - 1; i >= 0; i--) - { - band_offsets_local[i * 2 + 1 + 1] = band_offsets[i + 1]; - band_offsets_local[i * 2 + 0 + 1] = band_offsets[i + 1]; - } - } - - denumerator = 0.001; - - for (i = 0; i < M; i++) - { - sum = 0; len = 0; - start = band_offsets_local[i * 4] + 1; stop = band_offsets_local[i * 4 + 4]; - - for (j = stop; j >= start; j--) - { - sum += j; - len++; - } - - numerator += gains_dee[i] * ((LC3_FLOAT) sum / (LC3_FLOAT) framelength); - denumerator += gains_dee[i] * len; - } - - *sc = numerator / denumerator; - *sc = *sc * (LC3_FLOAT) fs / 48000.0; /* scaling, because training is for 48kHz */ -} - -static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, - LC3_INT32 frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr) -{ - LC3_INT32 max_corr_len, pitch_min, corr_len, min_corr_len, pcm_max_corr_len, range1Start, range2Start, i; - LC3_FLOAT norm_w, norm_w_t; - - norm_w_t = 0; norm_w = 0; - - assert(pitch_int >= 0); - assert(pitch_int <= MAX_LEN*100*MAX_PITCH_12K8/12800); - - *xcorr = 0; - - if (pitch_int > 0) - { - pitch_min = fs * MIN_PITCH_12K8/12800; - pcm_max_corr_len = max_len_pcm_plc - pitch_int; - - min_corr_len = 2 * pitch_min; /* at least 5 ms (=2*pitchmin*) corr length */ - max_corr_len = framelength*100/frame_dms; /* maximum 10 ms */ - max_corr_len = MIN( max_corr_len, pcm_max_corr_len ); - - corr_len = MIN( max_corr_len, pitch_int ); /* pitch_int is prefered, but maximum 10ms or left pcm buf size */ - corr_len = MAX( min_corr_len, corr_len ); - - range1Start = max_len_pcm_plc - corr_len; - range2Start = range1Start - pitch_int; - - assert( corr_len >= min_corr_len ); - assert( corr_len <= max_corr_len ); - assert( range2Start >= 0 ); - - for (i = 0; i < corr_len; i++) - { - norm_w += pcmbufHist[range1Start + i] * pcmbufHist[range1Start + i]; - } - - for (i = 0; i < corr_len; i++) - { - norm_w_t += pcmbufHist[range2Start + i] * pcmbufHist[range2Start + i]; - } - - for (i = 0; i < corr_len; i++) - { - *xcorr = *xcorr + pcmbufHist[range1Start + i] * pcmbufHist[range2Start + i]; - } - - *xcorr = *xcorr / sqrt(norm_w * norm_w_t + 0.1); - *xcorr = MAX(0, *xcorr); - } else { - *xcorr = 0; - } -} - diff --git a/lib_lc3plus/plc_classify_fx.c b/lib_lc3plus/plc_classify_fx.c new file mode 100644 index 000000000..bbb01826a --- /dev/null +++ b/lib_lc3plus/plc_classify_fx.c @@ -0,0 +1,424 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +#ifdef CR8_A_PLC_FADEOUT_TUNING + +static Word32 change_bit_at_position(Word32 value, Word8 bit_position, UWord8 bit) +{ + Word32 helper_mask = ~L_shl_pos(1, bit_position); + Word32 tmp = L_and(value, helper_mask); + tmp = L_or(tmp, L_shl_pos(bit, bit_position)); + return tmp; +} + +static void update_bit_and_byte_positions(Word16 longterm_analysis_counter_max_bytebuffer, Word8 *byte_position, Word8 *bit_position) +{ +#ifdef CR11_A_FIX_IN_PLC_LONGTERM_STATISTIC + IF (sub(*bit_position, 29) == 0) +#else + IF (sub(*bit_position, 30) == 0) +#endif + { + *bit_position = 0; move16(); + + if (sub(*byte_position, longterm_analysis_counter_max_bytebuffer) < -1) + { + *byte_position = add(*byte_position, 1); + } else { + *byte_position = 0; move16(); + } + } ELSE { + *bit_position = add(*bit_position, 1); + } +} + +static void array_insert_and_shift(Word32 *array, UWord8 value, Word16 longterm_analysis_counter_max, Word16 *overall_counter, Word8 *byte_position, Word8 *bit_position) +{ + Word32 current_byte = 0; + +#ifdef WMOPS + BASOP_sub_sub_start("PLC::array_insert_and_shift"); +#endif + + IF( overall_counter != NULL) + { + *overall_counter = s_min(add(*overall_counter, 1), longterm_analysis_counter_max); + } + + current_byte = array[*byte_position]; move16(); + current_byte = change_bit_at_position(current_byte, *bit_position, value); + array[*byte_position] = current_byte; move16(); + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +} + +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER +static void array_calculate(Word32 *array_tdc, Word32 *array_ns, int length, Word16 *counter_tdc, Word16 *counter_ns, Word16 longterm_analysis_counter_max) +#else +static void array_calculate(Word32 *array_tdc, Word32 *array_ns, int length, Word16 *counter_tdc, Word16 *counter_ns, Word16 *counter_phecu, Word16 overall_counter, Word16 longterm_analysis_counter_max) +#endif +{ + int i, k; + Word32 current_byte_tdc = 0, current_byte_ns = 0; + Word16 counter_loc_tdc = 0, counter_loc_ns = 0, counter_tmp = 0; + +#ifdef WMOPS + BASOP_sub_sub_start("PLC::array_calculate"); +#endif + + for (i = length - 1; i >= 0; i--) + { + current_byte_tdc = array_tdc[i]; + current_byte_ns = array_ns[i]; + + for (k = 0; k < 30; k++) + { + counter_loc_tdc += ((current_byte_tdc >> k) & 1); + counter_loc_ns += ((current_byte_ns >> k) & 1); + counter_tmp++; + + /* Break from both loops if full 2s buffer has been evaluated */ + if (counter_tmp >= longterm_analysis_counter_max) + { + i = -1; + k = 30; + break; + } + } + } + + *counter_tdc = counter_loc_tdc; + *counter_ns = counter_loc_ns; + +#ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + *counter_phecu = sub(sub(overall_counter, counter_loc_tdc), counter_loc_ns); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +} +#endif + +static Word16 spectral_centroid_fx_lc(Word16 old_scf_q[], const Word16 *band_offsets, Word16 bands_number, Word16 frame_length, + Word16 fs_idx, Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + , Word16 hrmode +# endif + ); + +void processPLCclassify_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, + Word16 ltpf_mem_pitch_int, Word16 frame_length, Word16 frame_dms, Word16 fs_idx, Word16 yLen, + Word16 q_old_d_fx[], const Word16 *band_offsets, Word16 bands_number, AplcSetup *plcAd, Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + , Word16 hrmode +# endif + ) +{ + Dyn_Mem_Deluxe_In( + Word16 scQ15; + Word32 class; + ); + +#ifdef WMOPS + BASOP_sub_sub_start("PLC::processPLCclassify_fx"); +#endif + + UNUSED(yLen); + UNUSED(q_old_d_fx); + + if (plcAd) + { + plcAd->norm_corrQ15_fx = 0; move16(); + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + /* assert(bfi != 2 && "Error bfi flag value, state of fadeout cntr is affected by PartialConcealment here "); */ + /* Save statistics for 24 kHz, 48 kHz and 96 kHz */ + IF((sub(bfi, 1) == 0) || (((bfi >= 0) && (sub(bfi, 2) <= 0)) && ((sub(fs_idx, 2) == 0) || (sub(fs_idx, 4) == 0) || (sub(fs_idx, 5) == 0)))) /* note for PC bfi==2 is possible */ +#else + IF (sub(bfi, 1) == 0) +#endif + { + /* increase counter of lost-frames-in-a-row */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + IF (sub(bfi, 1) == 0) + { + *nbLostFramesInRow = add(*nbLostFramesInRow, 1); + *nbLostFramesInRow = s_min(*nbLostFramesInRow, 0x100); + } +#else + *nbLostFramesInRow = add(*nbLostFramesInRow, 1); + *nbLostFramesInRow = s_min(*nbLostFramesInRow, 0x100); +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING + /*assert((bfi != 2) && "PartialConcealment checked vs bfi==0 can cause issues "); */ + IF ((sub(*nbLostFramesInRow, 1) == 0) || (bfi != 1) ) /* was "|| (bfi==0)" , NB only test bfi vs "1" as bfi can have the states [0(good),1(bad),2(good,partialConcealment) } */ +#else + IF (sub(*nbLostFramesInRow, 1) == 0) +#endif + { + *concealMethod = plcMeth; move16(); + + IF(sub(plcMeth, 1) == 0) + { + IF(ltpf_mem_pitch_int > 0) + { + *concealMethod = LC3_CON_TEC_TDPLC; move16(); /* TD-PLC */ + /* Calculate Features */ + + plcAd->norm_corrQ15_fx = plc_xcorr_lc_fx(plcAd->x_old_tot_fx, plcAd->max_len_pcm_plc, ltpf_mem_pitch_int, fs_idx); + scQ15 = spectral_centroid_fx_lc(plcAd->old_scf_q, band_offsets, bands_number, frame_length, + fs_idx, scratchBuffer +#ifdef ENABLE_HR_MODE + , hrmode +#endif + ); + + /* Classify */ + class = L_mult(plcAd->norm_corrQ15_fx, 7640); + class = L_mac(class, scQ15, -32768); + class = L_add_sat(class, -335020208); + + IF(class <= 0) + { +#ifdef ENABLE_HR_MODE + IF((frame_dms == 100) && (hrmode == 0)) +#else + IF(frame_dms == 100) +#endif + { + *concealMethod = LC3_CON_TEC_PHASE_ECU; move16(); /* Phase ECU selected */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); +#endif + } + ELSE + { +#ifndef CR9_G_PLC_NS_TDC_FIX + *concealMethod = LC3_CON_TEC_NS_ADV; move16(); /* Noise Substitution */ +#endif +#ifdef CR8_A_PLC_FADEOUT_TUNING + array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); +#endif + } + } +#ifdef CR8_A_PLC_FADEOUT_TUNING + ELSE { + array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 1, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + } +#endif + } + ELSE + { + *concealMethod = LC3_CON_TEC_NS_ADV; move16(); /* Noise Substitution */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + array_insert_and_shift(plcAd->plc_longterm_advc_ns, 1, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); +#endif + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING +# ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, plcAd->longterm_analysis_counter_max); +# else + array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, &plcAd->longterm_counter_plcPhaseEcu, plcAd->overall_counter, plcAd->longterm_analysis_counter_max); +# endif + update_bit_and_byte_positions(plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); +#endif + } + + } + } + + Dyn_Mem_Deluxe_Out(); +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +} + + +Word16 spectral_centroid_fx_lc(Word16 old_scf_q[], const Word16 *band_offsets, Word16 bands_number, Word16 frame_length, + Word16 fs_idx, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + ) +{ + Dyn_Mem_Deluxe_In( + Counter i, j; + Word32 den32, num32, tmp32; + Word16 s, sc, fac, freq, inv, startfreq, stopfreq; + Word16 s2; + Word16 *old_scf_q_mod; + Word16 *old_scf_q_mod_exp; + Word16 *band_offsets_local; + ); +#ifdef WMOPS + BASOP_sub_sub_start("PLC::spectral_centroid_fx_lc"); +#endif + +#ifdef ENABLE_HR_MODE + s2 = 0; +#else + UNUSED(s2); +#endif + + + old_scf_q_mod = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */ + old_scf_q_mod_exp = (Word16 *)scratchAlign(old_scf_q_mod, sizeof(*old_scf_q_mod) * M); /* Size = 2 * M */ + band_offsets_local = (Word16 *)scratchAlign(old_scf_q_mod_exp, sizeof(*old_scf_q_mod_exp) * (M)); /* Size = 2 * bands_number */ + + /* Linear Domain */ + FOR (i = 0; i < M; i++) + { + old_scf_q_mod[i] = BASOP_Util_InvLog2_16(old_scf_q[i], &old_scf_q_mod_exp[i]); + } + + /* De-emphasis */ + FOR (i = 0; i < M; i++) + { + old_scf_q_mod[i] = mult(old_scf_q_mod[i], lpc_warp_dee_emphasis[fs_idx][i]); move16(); + old_scf_q_mod_exp[i] = add(old_scf_q_mod_exp[i], lpc_warp_dee_emphasis_e[fs_idx][i]); move16(); + } + + IF (sub(bands_number, 64) == 0) + { + basop_memmove(band_offsets_local, band_offsets, (bands_number + 1) * sizeof(Word16)); + } + IF (sub(bands_number, 32) < 0) + { + band_offsets_local[0] = 0; move16(); + s = sub(32, bands_number); + FOR (i = sub(bands_number, 1); i >= s; i--) + { + band_offsets_local[(i + s) * 2 + 1 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[(i + s) * 2 + 0 + 1] = band_offsets[i + 1]; move16(); + } + FOR (i = sub(s, 1); i >= 0; i--) + { + band_offsets_local[i * 4 + 3 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[i * 4 + 2 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[i * 4 + 1 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[i * 4 + 0 + 1] = band_offsets[i + 1]; move16(); + } + } + ELSE + IF (sub(bands_number, 64) < 0) + { + band_offsets_local[0] = 0; move16(); + s = sub(64, bands_number); + FOR (i = sub(bands_number, 1); i >= s; i--) + { + band_offsets_local[i + s + 1] = band_offsets[i + 1]; move16(); + } + FOR (i = sub(s, 1); i >= 0; i--) + { + band_offsets_local[i * 2 + 1 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[i * 2 + 0 + 1] = band_offsets[i + 1]; move16(); + } + } + + den32 = 1; move16(); + num32 = 0; move16(); + inv = div_s(1, frame_length); + + FOR (i = 0; i < M; i++) + { + freq = 0; move16(); + startfreq = add(band_offsets_local[i * 4], 1); + stopfreq = band_offsets_local[i * 4 + 4]; + +# ifdef ENABLE_HR_MODE + IF (hrmode != 0) + { + tmp32 = 0; move32(); + FOR (j = startfreq; j <= stopfreq; j++) + { + tmp32 = L_add(tmp32, j); + } + + s2 = norm_l(tmp32); + freq = extract_h(L_shl(tmp32, s2)); + s2 = sub(add(15, s2), 31); + tmp32 = L_mult(inv, freq); + s = norm_l(tmp32); + } + ELSE +# endif + { + FOR (j = startfreq; j <= stopfreq; j++) + { + freq = add(freq, j); + } + + tmp32 = L_mult(inv, freq); + s = norm_l(tmp32); + } + + tmp32 = L_mult(old_scf_q_mod[i], extract_h(L_shl(tmp32, s))); + +# ifdef ENABLE_HR_MODE + if (hrmode != 0) + { + s = add(s, s2); + } +# endif + + num32 = L_add(num32, L_shl(tmp32, add(add(-15, old_scf_q_mod_exp[i]), sub(15, s)))); + den32 = L_add(den32, L_shl(L_mult(old_scf_q_mod[i], stopfreq - startfreq + 1), old_scf_q_mod_exp[i])); + } + + s = norm_l(den32); + s = sub(16, s); + + sc = div_s(extract_l(L_shr(num32, s)), extract_l(L_shr(den32, s))); + + SWITCH (fs_idx) + { + case 0: + fac = 5461; move16(); + BREAK; + case 1: + fac = 10922; move16(); + BREAK; + case 2: + fac = 16384; move16(); + BREAK; + case 3: + fac = 21845; move16(); + BREAK; + default: /* case 4: */ + fac = 32767; move16(); + BREAK; + } + sc = round_fx(L_mult(sc, fac)); +# ifdef ENABLE_HR_MODE + if (sub(fs_idx, 5) == 0) + { + sc = shl_pos(sc, 1); + } +# endif + + Dyn_Mem_Deluxe_Out(); +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return sc; +} + + diff --git a/lib_lc3plus/plc_compute_stab_fac.c b/lib_lc3plus/plc_compute_stab_fac.c deleted file mode 100644 index 5c7a736e6..000000000 --- a/lib_lc3plus/plc_compute_stab_fac.c +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -static void processPlcComputeStabFac_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_INT32 prev_bfi, LC3_FLOAT *stab_fac); - -void processPlcComputeStabFacMain_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_FLOAT *old_old_scf_q, LC3_INT32 bfi, LC3_INT32 prev_bfi, - LC3_INT32 prev_prev_bfi, LC3_FLOAT *stab_fac) -{ - if (bfi == 1) - { - if (prev_bfi != 1) - { - processPlcComputeStabFac_fl(old_scf_q, old_old_scf_q, prev_prev_bfi, stab_fac); - } - } - else if (bfi == 2) - { - processPlcComputeStabFac_fl(scf_q, old_scf_q, prev_bfi, stab_fac); - } -} - -static void processPlcComputeStabFac_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_INT32 prev_bfi, LC3_FLOAT *stab_fac) -{ - LC3_FLOAT tmp; - LC3_INT32 i; - - tmp = 0; - - if (prev_bfi == 1) - { - *stab_fac = 0.8; - } - else - { - for (i = 0; i < M; i++) - { - tmp += (scf_q[i] - old_scf_q[i]) * (scf_q[i] - old_scf_q[i]); - } - - *stab_fac = 1.25 - tmp / 25.0; - - if (*stab_fac > 1) - { - *stab_fac = 1; - } - - if (*stab_fac < 0) - { - *stab_fac = 0; - } - } -} - diff --git a/lib_lc3plus/plc_damping_scrambling.c b/lib_lc3plus/plc_damping_scrambling.c deleted file mode 100644 index fd9efd7c0..000000000 --- a/lib_lc3plus/plc_damping_scrambling.c +++ /dev/null @@ -1,290 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, - LC3_INT32 *pc_seed, LC3_INT32 ns_nbLostCmpt_pc, - LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, - LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi, - LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2, - LC3_FLOAT *cum_fflcAtten -#ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type -#endif - ) -{ - - LC3_INT32 processDampScramb; - - processDampScramb = 0; - - - if ( bfi != 0 ) - { - if (concealMethod == 4 || bfi == 2) - { - processDampScramb = 1; - } - -#ifdef CR8_A_PLC_FADEOUT_TUNING - if (ns_nbLostCmpt == 1) - { - *cum_fading_slow = 1; - *cum_fading_fast = 1; - *cum_fflcAtten = 1; - } -#endif - - if ( bfi == 1 ) - { - processPlcDampingScrambling_fl(spec, yLen, ns_nbLostCmpt, stabFac, processDampScramb, cum_fflcAtten, - pitch_present_bfi1, frame_dms, cum_fading_slow, cum_fading_fast, ns_seed, 0 -#ifdef CR8_A_PLC_FADEOUT_TUNING - , plc_fadeout_type -#endif - ); - } - else /* bfi == 2 */ - { - processPlcDampingScrambling_fl(spec, yLen, ns_nbLostCmpt_pc, stabFac, processDampScramb, cum_fflcAtten, - pitch_present_bfi2, frame_dms, cum_fading_slow, cum_fading_fast, pc_seed, spec_inv_idx -#ifdef CR8_A_PLC_FADEOUT_TUNING - , plc_fadeout_type -#endif - ); - processPlcUpdateSpec_fl(spec_prev, spec, yLen); - } - } -} - -void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb, - LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow, - LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx -#ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type -#endif - ) -{ - LC3_INT32 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, x, b, i, ad_ThreshFac_start; - LC3_FLOAT slow, fast, linFuncStartStop, randThreshold, ad_ThreshFac_end, ad_threshFac, frame_energy, mean_energy, energThreshold, fac, m, n, fflcAtten, cum_fading_slow_local, cum_fading_fast_local; - - frame_energy = 0; - -#ifndef CR8_A_PLC_FADEOUT_TUNING - /* Main process */ - if (nbLostCmpt == 1) - { - *cum_fading_slow = 1; - *cum_fading_fast = 1; - *cum_fflcAtten = 1; - } -#endif - - slow = 0.8 + 0.2 * (*stabFac); - fast = 0.3 + 0.2 * (*stabFac); - - switch (frame_dms) - { - case 25: - slow = LC3_SQRT(LC3_SQRT(slow)); - fast = LC3_SQRT(LC3_SQRT(fast)); - break; - case 50: - slow = LC3_SQRT(slow); - fast = LC3_SQRT(fast); - break; -#ifdef CR8_G_ADD_75MS - case 75: - slow = LC3_SQRT(LC3_SQRT(slow*slow*slow)); - fast = LC3_SQRT(LC3_SQRT(fast*fast*fast)); - break; -#endif - } - -#ifdef CR8_A_PLC_FADEOUT_TUNING - if (plc_fadeout_type == 0) - { -#endif - *cum_fading_slow = *cum_fading_slow * slow; - *cum_fading_fast = *cum_fading_fast * fast; -#ifdef CR8_A_PLC_FADEOUT_TUNING - } -#endif - - if (processDampScramb == 1) - { -#ifdef CR8_A_PLC_FADEOUT_TUNING - if (plc_fadeout_type != 0) - { - if (nbLostCmpt < (4 * (100.0 / (LC3_FLOAT)frame_dms))) { - cum_fading_slow_local = 1.0; - } - else if (nbLostCmpt < (8 * (100.0 / (LC3_FLOAT)frame_dms))) { - cum_fading_slow_local = 0.9; - } - else { - cum_fading_slow_local = 0.85; - } - - *cum_fading_slow = *cum_fading_slow * cum_fading_slow_local; - cum_fading_slow_local = *cum_fading_slow; - } - else { -#endif - fflcAtten = 1; - cum_fading_slow_local = *cum_fading_slow; - cum_fading_fast_local = *cum_fading_fast; - - if (spec_inv_idx == 0) - { - if (nbLostCmpt * frame_dms > PLC_FADEOUT_IN_MS * 10) - { - fflcAtten = 0; - *cum_fflcAtten = 0; - } - else if (nbLostCmpt * frame_dms > 200) - { - switch (frame_dms) - { - case 25: fflcAtten = PLC34_ATTEN_FAC_025; break; - case 50: fflcAtten = PLC34_ATTEN_FAC_050; break; -#ifdef CR8_G_ADD_75MS - case 75: fflcAtten = PLC34_ATTEN_FAC_075; break; -#endif - case 100: fflcAtten = PLC34_ATTEN_FAC_100; break; - } - } - - - *cum_fflcAtten = *cum_fflcAtten * fflcAtten; - cum_fading_slow_local = *cum_fading_slow * *cum_fflcAtten; - cum_fading_fast_local = *cum_fading_fast * *cum_fflcAtten; - } - - if (pitch_present == 0) - { - plc_start_inFrames = 1; - } - else { - plc_start_inFrames = floor(PLC4_TRANSIT_START_IN_MS / (frame_dms / 10.0)); - } - - plc_end_inFrames = floor(PLC4_TRANSIT_END_IN_MS / (frame_dms / 10.0)); - plc_duration_inFrames = plc_end_inFrames - plc_start_inFrames; - - if (nbLostCmpt <= plc_start_inFrames) - { - linFuncStartStop = 1; - } - else if (nbLostCmpt >= plc_end_inFrames) - { - linFuncStartStop = 0; - } - else { - x = nbLostCmpt; - m = -1.0 / plc_duration_inFrames; - b = -plc_end_inFrames; - linFuncStartStop = m * (x + b); - } - - randThreshold = -32768 * linFuncStartStop; -#ifdef CR8_A_PLC_FADEOUT_TUNING - } -#endif - - for (i = spec_inv_idx; i < yLen; i++) - { - *seed = 16831 + *seed * 12821; - - *seed = (LC3_INT16)(*seed); - if (*seed == 32768) - { - *seed -= 32768; - } - - if (*seed < 0) - { -#ifdef CR8_A_PLC_FADEOUT_TUNING - if (plc_fadeout_type != 0 || pitch_present == 0 || *seed < randThreshold ) -#else - if (pitch_present == 0 || *seed < randThreshold) -#endif - { - spec[i] = -spec[i]; - } - } - } - -#ifdef CR8_A_PLC_FADEOUT_TUNING - if (plc_fadeout_type == 0) - { -#endif - ad_ThreshFac_start = 10; - ad_ThreshFac_end = 1.2; - ad_threshFac = (ad_ThreshFac_start - ad_ThreshFac_end) * linFuncStartStop + ad_ThreshFac_end; - - if (spec_inv_idx < yLen) - { - for (i = spec_inv_idx; i < yLen; i++) - { - frame_energy = frame_energy + (spec[i] * spec[i]); - } - - mean_energy = frame_energy * 1 / (yLen - spec_inv_idx); - } - else - { - mean_energy = 0; - } - - energThreshold = LC3_SQRT(ad_threshFac * mean_energy); - fac = (cum_fading_slow_local - cum_fading_fast_local) * energThreshold; -#ifdef CR8_A_PLC_FADEOUT_TUNING - } -#endif - - for (i = spec_inv_idx; i < yLen; i++) - { -#ifdef CR8_A_PLC_FADEOUT_TUNING - if (plc_fadeout_type != 0 || LC3_FABS(spec[i]) < energThreshold ) -#else - if (LC3_FABS(spec[i]) < energThreshold) -#endif - { - m = cum_fading_slow_local; - n = 0; - } - else - { - m = cum_fading_fast_local; - - if (spec[i] > 0) - { - n = fac; - } - else if (spec[i] == 0) - { - n = 0; - } - else - { - n = -fac; - } - } - - spec[i] = m * spec[i] + n; - } - } -} - diff --git a/lib_lc3plus/plc_damping_scrambling_fx.c b/lib_lc3plus/plc_damping_scrambling_fx.c new file mode 100644 index 000000000..4c5641634 --- /dev/null +++ b/lib_lc3plus/plc_damping_scrambling_fx.c @@ -0,0 +1,430 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +void processPLCDampingScrambling_main_fx(Word16 bfi, Word16 concealMethod, Word16 ns_nbLostFramesInRow, Word16 *cum_fflcAtten, + Word16 pc_nbLostFramesInRow, Word16 *ns_seed, Word16 *pc_seed, Word16 pitch_present_bfi1, + Word16 pitch_present_bfi2, Word32 spec[], Word16 *q_fx_exp, Word16 *q_old_d_fx, + Word16 *q_old_fx_exp, Word16 L_spec, Word16 stabFac, Word16 frame_dms, + Word16 *cum_fading_slow, Word16 *cum_fading_fast, Word16 spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , UWord8 plc_fadeout_type +#endif + ) +{ + Dyn_Mem_Deluxe_In( + Word16 processDampScramb; + ); + + IF ( bfi != 0 ) + { + processDampScramb = 0; move16(); + test(); + IF (sub(concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(bfi, 2) == 0) + { + processDampScramb = 1; move16(); + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + IF (sub(ns_nbLostFramesInRow, 1) == 0) + { + *cum_fading_slow = 32767; move16(); + *cum_fading_fast = 32767; move16(); + *cum_fflcAtten = 32767; move16(); + } +#endif + + IF (sub(bfi, 1) == 0) + { + processPLCDampingScrambling_fx(spec, L_spec, ns_nbLostFramesInRow, stabFac, + processDampScramb, cum_fflcAtten, + pitch_present_bfi1, frame_dms, cum_fading_slow, + cum_fading_fast, ns_seed, 0 +#ifdef CR8_A_PLC_FADEOUT_TUNING + , plc_fadeout_type +#endif + ); + } + ELSE /* bfi == 2 */ + { + processPLCDampingScrambling_fx(spec, L_spec, pc_nbLostFramesInRow, stabFac, + processDampScramb, cum_fflcAtten, + pitch_present_bfi2, frame_dms, cum_fading_slow, + cum_fading_fast, pc_seed, spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , plc_fadeout_type +#endif + ); + + processPLCupdateSpec_fx(q_old_d_fx, q_old_fx_exp, spec, q_fx_exp, L_spec); + } + } + Dyn_Mem_Deluxe_Out(); +} + +void processPLCDampingScrambling_fx(Word32 spec[], Word16 L_spec, Word16 nbLostFramesInRow, Word16 stabFac, Word16 processDampScramb, + Word16 *cum_fflcAtten, Word16 pitch_present, Word16 frame_dms, Word16 *cum_fading_slow, + Word16 *cum_fading_fast, Word16 *seed, Word16 spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , UWord8 plc_fadeout_type +#endif + ) +{ + Counter i; + Word16 lossDuration_dms, slow, fast, tmp16; + Word16 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, linFuncStartStop; + Word16 randThreshold, ad_threshFac, energThreshold, s, s2, s3, mean_energy16; + Word32 frame_energy, mean_nrg, fac; + Word16 fflcAtten, cum_fading_slow_local, cum_fading_fast_local; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processPLCDampingScrambling_fx", sizeof(struct { + Counter i; + Word16 lossDuration_dms, slow, fast, tmp16; + Word16 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, linFuncStartStop; + Word16 randThreshold, ad_threshFac, energThreshold, s, s2, s3, mean_energy16; + Word32 frame_energy, mean_nrg, fac; + Word16 fflcAtten, cum_fading_slow_local, cum_fading_fast_local; + })); +#endif + + /** preparation */ +#ifndef CR8_A_PLC_FADEOUT_TUNING + /* init cummulative damping factors at first loss */ + IF (sub(nbLostFramesInRow, 1) == 0) + { + *cum_fading_slow = 32767; move16(); + *cum_fading_fast = 32767; move16(); + *cum_fflcAtten = 32767; move16(); + } +#endif + + /* get damping factors */ + tmp16 = mult(6554 /*0.2*/, stabFac); + slow = add(26214 /*0.8*/, tmp16); + fast = add( 9830 /*0.3*/, tmp16); + + + SWITCH (frame_dms) + { + case 25: + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + BREAK; + case 50: + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + BREAK; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: + IF (sub(slow, 32767) < 0) + { + slow = mult(slow, mult(slow, slow)); + } + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(fast, 32767) < 0) + { + fast = mult(fast, mult(fast, fast)); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + BREAK; +# endif +#endif + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type == 0) + { +#endif + *cum_fading_slow = mult_r(*cum_fading_slow, slow); + *cum_fading_fast = mult_r(*cum_fading_fast, fast); +#ifdef CR8_A_PLC_FADEOUT_TUNING + } +#endif + + IF ( sub(processDampScramb, 1) == 0 ) + { +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type != 0) + { + Word16 lost_frame_thr1 = 4; + Word16 lost_frame_thr2 = 8; + + SWITCH (frame_dms) + { + case 25: + lost_frame_thr1 = 16; + lost_frame_thr2 = 32; + BREAK; + case 50: + lost_frame_thr1 = 8; + lost_frame_thr2 = 16; + BREAK; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: + lost_frame_thr1 = 6; + lost_frame_thr2 = 11; +# endif +#endif + } + IF (sub(nbLostFramesInRow, lost_frame_thr1) < 0) + { + cum_fading_slow_local = 32767; move16(); + } + ELSE IF (sub(nbLostFramesInRow, lost_frame_thr2) < 0) + { + cum_fading_slow_local = 29491; move16(); + } + ELSE + { + cum_fading_slow_local = 27852; move16(); + } + + *cum_fading_slow = mult_r(*cum_fading_slow, cum_fading_slow_local); move16(); + cum_fading_slow_local = *cum_fading_slow; move16(); + } else { +#endif + /** rapid fading for FFLC */ + fflcAtten = 32767; move16(); + cum_fading_slow_local = *cum_fading_slow; move16(); + cum_fading_fast_local = *cum_fading_fast; move16(); + + IF (spec_inv_idx == 0) + { + lossDuration_dms = DEPR_i_mult(nbLostFramesInRow, frame_dms); + IF (sub(lossDuration_dms, PLC_FADEOUT_IN_MS*10) > 0) + { + *cum_fflcAtten = 0; move16(); + fflcAtten = 0; move16(); + } + ELSE IF (sub(lossDuration_dms, 200) > 0) + { + SWITCH (frame_dms) + { + case 25: fflcAtten = PLC34_ATTEN_FAC_025_FX; BREAK; + case 50: fflcAtten = PLC34_ATTEN_FAC_050_FX; BREAK; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: fflcAtten = PLC34_ATTEN_FAC_075_FX; BREAK; +# endif +#endif + case 100: fflcAtten = PLC34_ATTEN_FAC_100_FX; BREAK; + } + } + IF ( sub(fflcAtten, 32767) < 0 ) + { + *cum_fflcAtten = mult_r(*cum_fflcAtten, fflcAtten); + cum_fading_slow_local = mult_r(*cum_fading_slow, *cum_fflcAtten); + cum_fading_fast_local = mult_r(*cum_fading_fast, *cum_fflcAtten); + } + } + + /** prepare fade-out function */ + /* being 1 up to plc_start_inFrames, being 0 starting with + plc_end_inFrames; decreasing linearly in between */ + SWITCH (frame_dms) + { + case 25: + plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 25; move16(); + plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 25; move16(); + BREAK; + case 50: + plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 50; move16(); + plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 50; move16(); + BREAK; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: + plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 75; move16(); + plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 75; move16(); + BREAK; +# endif +#endif + default: + plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 100; move16(); + plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 100; move16(); + } + + if (pitch_present == 0) + { + plc_start_inFrames = 1; move16(); + } + plc_duration_inFrames = sub(plc_end_inFrames, plc_start_inFrames); + + IF (sub(nbLostFramesInRow, plc_start_inFrames) <= 0) + { + linFuncStartStop = 32767; move16(); + } + ELSE IF (sub(nbLostFramesInRow, plc_end_inFrames) >= 0) + { + linFuncStartStop = 0; move16(); + } + ELSE + { + /* + x = xLostFramesInRow; + m = -1 / plc_duration_inFrames; + b = -plc_end_inFrames; % shift on x axis + linFuncStartStop = m * (x + b); + */ + linFuncStartStop = div_s(sub(plc_end_inFrames, nbLostFramesInRow), plc_duration_inFrames); + } + + /** sign scrambling */ + randThreshold = mult(-32768, linFuncStartStop); +#ifdef CR8_A_PLC_FADEOUT_TUNING + } +#endif + + tmp16 = *seed; move16(); + FOR (i = spec_inv_idx; i < L_spec; i++) + { + tmp16 = extract_l(L_mac0(16831, tmp16, 12821)); + + IF (tmp16 < 0) + { + test(); +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type != 0 || pitch_present == 0 || sub(tmp16, randThreshold) < 0 ) +#else + if (pitch_present == 0 || sub(tmp16, randThreshold) < 0) +#endif + { + spec[i] = L_negate(spec[i]); + } + } + + } + *seed = tmp16; move16(); + +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type == 0) + { +#endif + /** adaptive damping */ + tmp16 = mult(18022 /* 10 - 1.2 */, linFuncStartStop); + ad_threshFac = add(shr(tmp16, 1), 1228 /* 1.2 >> 1 */); /* exp = 5 */ + + s = getScaleFactor32_lc3plus(&spec[spec_inv_idx], sub(L_spec, spec_inv_idx)); + frame_energy = 0; move32(); + FOR (i = spec_inv_idx; i < L_spec; i++) + { + tmp16 = extract_h(L_shl_sat(spec[i], sub(s, 4))); + frame_energy = L_mac0(frame_energy, tmp16, tmp16); /* exp = -(2*(s-16) - 8) */ + } + mean_energy16 = BASOP_Util_Divide3216_Scale_lc3plus(frame_energy, sub(L_spec, spec_inv_idx), &s2); /* exp = -(2*(s-16) - 8) + 16 - (15-s2) */ + + energThreshold = mult(ad_threshFac, mean_energy16); /* exp = -(2*(s-16) - 8) + 16 - (15-s2) + 5 */ + + s3 = add(sub(29, shl(sub(s, 16), 1)), s2); + IF (sub(energThreshold, 32767) < 0) + { + energThreshold = Sqrt16_lc3plus(energThreshold, &s3); + } + s3 = sub(s3, 15); + + mean_nrg = L_shl_sat(L_deposit_l(energThreshold), s3); /* exp = 0 */ + fac = mult(sub(cum_fading_slow_local, cum_fading_fast_local), energThreshold); + fac = L_shl_sat(L_deposit_l(fac), s3); /* exp = 0 */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + } +#endif + + FOR (i = spec_inv_idx; i < L_spec; i++) + { +#ifdef CR8_A_PLC_FADEOUT_TUNING + if ( ( plc_fadeout_type != 0 ) || (L_sub(L_abs(spec[i]), mean_nrg) < 0) ) +#else + if (L_sub(L_abs(spec[i]), mean_nrg) < 0) +#endif + { + spec[i] = Mpy_32_16_lc3plus(spec[i], cum_fading_slow_local); + } + else + { + if (spec[i] > 0) + { + spec[i] = L_add_sat(Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local), fac); + } + else if (spec[i] == 0) + { + spec[i] = Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local); + } + else + { + spec[i] = L_sub_sat(Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local), fac); + } + } + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/mdct_shaping.c b/lib_lc3plus/plc_lpc_scaling_fx.c similarity index 52% rename from lib_lc3plus/mdct_shaping.c rename to lib_lc3plus/plc_lpc_scaling_fx.c index eba6f3270..85ffbf942 100644 --- a/lib_lc3plus/mdct_shaping.c +++ b/lib_lc3plus/plc_lpc_scaling_fx.c @@ -1,28 +1,36 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" +#include "defines.h" #include "functions.h" -void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) +void processPLCLpcScaling_fx(Word32 tdc_A_32[], Word16 tdc_A_16[], Word16 m) { - LC3_INT i, j; - LC3_FLOAT val; + Counter i; + Word16 s; - j = 0; - for (i = 0; i < fdns_npts; i++) { - val = scf[i]; - - for (; j < bands_offset[i + 1]; j++) { - x[j] = x[j] * val; - } +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processPLCLpcScaling_fx", sizeof(struct { + Counter i; + Word16 s; + })); +#endif + + s = getScaleFactor32_lc3plus(tdc_A_32, m); + FOR (i = 0; i < m; i++) + { + tdc_A_16[i] = round_fx_sat(L_shl_sat(tdc_A_32[i], s)); move16(); } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif } + + diff --git a/lib_lc3plus/plc_main.c b/lib_lc3plus/plc_main.c deleted file mode 100644 index ca4a6bbcb..000000000 --- a/lib_lc3plus/plc_main.c +++ /dev/null @@ -1,327 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi, - PlcAdvSetup *PlcAdvSetup, PlcSetup *PlcSetup, LC3_INT plcMeth, LC3_INT ltpf_pitch_int, LC3_INT ltpf_pitch_fr, - LC3_INT tilt, const LC3_INT *bands_offset, LC3_INT bands_number, const LC3_INT *bands_offsetPLC, - LC3_INT n_bandsPLC, LC3_INT16 hrmode, pcState *statePC -) -{ - LC3_FLOAT r[MAX_BANDS_NUMBER_PLC], A[M + 1], synth[MAX_LEN + MDCT_MEM_LEN_MAX], energies[MAX_BANDS_NUMBER_PLC]; - LC3_INT32 pitch_classifier; - LC3_FLOAT xcorr; - LC3_INT32 yLen; - LC3_INT16 prev_bfi_plc2; - LC3_FLOAT phEcu_env_stab_local[1]; - LC3_FLOAT phEcu_pfind_sens[1]; - -#ifdef CR8_A_PLC_FADEOUT_TUNING - LC3_INT16 consecutiveLostThreshold = 0; -#endif - -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - LC3_INT16 thresh_tdc_cnt; - LC3_INT16 thresh_ns_cnt; - LC3_INT16 thresh_tdc_ns_cnt; -#endif - - prev_bfi_plc2 = 1; - if (PlcSetup->nbLostCmpt == 0) - { - prev_bfi_plc2 = 0; - } - assert((h_DecSetup->PlcSetup.prevBfi == 1) == (prev_bfi_plc2 == 1)); - - if (bfi == 1 && PlcAdvSetup) - { - /* FFLC increases the PFLC counter */ - statePC->ns_nbLostCmpt_pc = statePC->ns_nbLostCmpt_pc + 1; - } - - pitch_classifier = ltpf_pitch_int; -#ifdef NONBE_PLC_CLASSIFER_LAG_FIX - if (ltpf_pitch_fr > 2) - { - pitch_classifier++; - } -#endif - - processPlcClassify_fl(plcMeth, &h_DecSetup->concealMethod, &PlcSetup->nbLostCmpt, bfi, &xcorr, - decoder->frame_length, decoder->frame_dms, pitch_classifier, decoder->fs, - bands_offset, bands_number, tilt, PlcAdvSetup, hrmode - ); - - if (bfi == 1) - { -#ifdef CR8_A_PLC_FADEOUT_TUNING - switch(decoder->frame_dms) - { - case 25: - consecutiveLostThreshold = 16; -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT; - thresh_ns_cnt = THRESH_025_DMS_NS_CNT; - thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT; -#endif - break; - case 50: consecutiveLostThreshold = 8; -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - thresh_tdc_cnt = THRESH_050_DMS_TDC_CNT; - thresh_ns_cnt = THRESH_050_DMS_NS_CNT; - thresh_tdc_ns_cnt = THRESH_050_DMS_TDC_NS_CNT; -#endif - break; - case 75: consecutiveLostThreshold = 6; -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - thresh_tdc_cnt = THRESH_075_DMS_TDC_CNT; - thresh_ns_cnt = THRESH_075_DMS_NS_CNT; - thresh_tdc_ns_cnt = THRESH_075_DMS_TDC_NS_CNT; -#endif - break; - case 100: consecutiveLostThreshold = 4; -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - thresh_tdc_cnt = THRESH_100_DMS_TDC_CNT; - thresh_ns_cnt = THRESH_100_DMS_NS_CNT; - thresh_tdc_ns_cnt = THRESH_100_DMS_TDC_NS_CNT; -#endif - break; - default: assert(0); - } - - if (decoder->fs_idx == 2 || decoder->fs_idx >= 4) - { -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - if (PlcAdvSetup->longterm_counter_plcTdc < thresh_tdc_cnt){ - PlcAdvSetup->plc_fadeout_type = 1; - } - else if (PlcAdvSetup->longterm_counter_plcNsAdv < thresh_ns_cnt){ - PlcAdvSetup->plc_fadeout_type = 1; - } - else if (PlcAdvSetup->longterm_counter_plcTdc + PlcAdvSetup->longterm_counter_plcNsAdv < thresh_tdc_ns_cnt){ - PlcAdvSetup->plc_fadeout_type = 1; - } - else { - PlcAdvSetup->plc_fadeout_type = 0; - } -#else - if (((PlcAdvSetup->longterm_counter_plcPhaseEcu < PlcAdvSetup->longterm_counter_plcTdc*FAC1_FADEOUT) || - (PlcAdvSetup->longterm_counter_plcPhaseEcu < PlcAdvSetup->longterm_counter_plcNsAdv*FAC1_FADEOUT)) && - (PlcAdvSetup->longterm_counter_plcTdc / (PlcAdvSetup->longterm_counter_plcNsAdv + LC3_EPS) < FAC2_FADEOUT)) - { - PlcAdvSetup->plc_fadeout_type = 0; - } else { - if ((PlcAdvSetup->longterm_counter_plcPhaseEcu > FAC3_FADEOUT * PlcAdvSetup->longterm_counter_plcTdc) || - (PlcAdvSetup->longterm_counter_plcPhaseEcu > FAC3_FADEOUT * PlcAdvSetup->longterm_counter_plcNsAdv)) - { - PlcAdvSetup->plc_fadeout_type = 1; - } else { - PlcAdvSetup->plc_fadeout_type = 0; - } - } -#endif - - if ((PlcAdvSetup->overall_counter - (int)(PLC_LONGTERM_ANALYSIS_STARTUP_FILL * PlcAdvSetup->longterm_analysis_counter_max)) < 0) - { - PlcAdvSetup->plc_fadeout_type = 0; - } -#ifndef CR9_H_REMOVE_SWITCH_TO_PLC_NS - if (PlcSetup->nbLostCmpt >= consecutiveLostThreshold && PlcAdvSetup->plc_fadeout_type == 1) - { - if ( h_DecSetup->concealMethod == 3 ) - { - h_DecSetup->concealMethod = 4; - } - } -#endif -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - if (h_DecSetup->rel_pitch_change > REL_PITCH_THRESH && hrmode == 1 && (decoder->frame_dms == 50 || decoder->frame_dms == 25) ){ - PlcAdvSetup->plc_fadeout_type = 2; - } else -#endif - if ( h_DecSetup->concealMethod != 2 ) { - /* not PhECU */ - if (PlcSetup->nbLostCmpt < consecutiveLostThreshold ) - { - PlcAdvSetup->plc_fadeout_type = 0; - } - } - } else { - PlcAdvSetup->plc_fadeout_type = 0; - } -#endif - -#ifdef PLC_CR8_A_PRINTF - printf("plc_fadeout_type = %d\n", PlcAdvSetup->plc_fadeout_type); -#endif - switch (h_DecSetup->concealMethod) - { - case 2: - { - LC3_FLOAT pitch_fl_c; - - assert(decoder->fs_idx == floor(decoder->fs / 10000)); - /* phaseECU supports only 10ms framing*/ - assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == 100); - - if (decoder->frame_dms != 100) - { - // muting, if frame size changed during phaseECU concealment - memset(q_d_fl_c, 0, sizeof(LC3_FLOAT) * decoder->frame_length); - h_DecSetup->alpha = 0; - break; - } - - /* call phaseEcu */ - pitch_fl_c = (LC3_FLOAT)ltpf_pitch_int + (LC3_FLOAT)ltpf_pitch_fr / 4.0; /* use non-rounded pitch indeces */ - - - if (prev_bfi_plc2 == 0) - { - /* convert fractional pitch lag info at current fs to a normalized fractional bin-frequency */ - PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin = plc_phEcuSetF0Hz(decoder->fs, &pitch_fl_c); - /* several buffers used in Cflt , a copy pcmbufHist, right before calling PhEcu in bad frames */ - assert(bfi == 1); - move_float(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp, - &(PlcAdvSetup->pcmbufHist[PlcAdvSetup->max_len_pcm_plc - PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot]), - PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot); - - /* a first bfi frame:: calc windowed 16 ms energy twice in a 26 ms buffer separated by 10 ms*/ - { - const LC3_FLOAT *w, *prev_xfp; - LC3_INT32 i, oold_start; - - oold_start = PlcAdvSetup->max_len_pcm_plc - (decoder->frame_length + PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot); - assert(oold_start > 0); - w = PhECU_whr16ms_wins[decoder->fs_idx]; /* hammrect table */ - prev_xfp = &(PlcAdvSetup->pcmbufHist[oold_start + 0]); - - PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E = 0; - PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E = 0; - for (i = 0; i < PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot; i++) - { - PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E += sqrf(prev_xfp[i] * w[i]); - PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E += sqrf(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp[i] * w[i]); - } - - } - - } /* (prev_bfi_plc2 == 0)*/ - else - { - /* overwrite last 3.75 ms of xfp with most recent pcmbufHist tail , right before calling PhEcu in bursts of bad frames */ - LC3_INT32 lenCopyOla = decoder->la_zeroes; /*copy_part + ola_part = 3.75 ms for 10 ms frame*/ - - assert(bfi == 1 && prev_bfi_plc2); - move_float(&(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp[PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot-lenCopyOla]), - &(PlcAdvSetup->pcmbufHist[PlcAdvSetup->max_len_pcm_plc - lenCopyOla]), lenCopyOla); - - } - - { - LC3_FLOAT x_tda[MAX_LEN]; /* 960/2 */ - PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr = xcorr; - phEcu_env_stab_local[0] = (LC3_FLOAT)PHECU_ENV_STAB_LOCAL; - phEcu_pfind_sens[0] = (LC3_FLOAT)PHECU_PFIND_SENS; - - plc_phEcu_hq_ecu(&(PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin), - &(PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr), - PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp, - prev_bfi_plc2, - &(PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev), - decoder->fs, - &(PlcAdvSetup->PlcPhEcuSetup.PhECU_time_offs), - PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m, /* Complex */ - &(PlcAdvSetup->PlcPhEcuSetup.PhECU_num_plocs), - PlcAdvSetup->PlcPhEcuSetup.PhECU_plocs, - PlcAdvSetup->PlcPhEcuSetup.PhECU_f0est, - MDCT_WINS_10ms[hrmode][decoder->fs_idx], - - phEcu_env_stab_local, - PHECU_DELTA_CORR, - phEcu_pfind_sens, - PHECU_LA, - PlcAdvSetup->PlcPhEcuSetup.PhECU_t_adv, - PhECU_whr16ms_wins[decoder->fs_idx], - PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape, - &(PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E), - PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape, - &(PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E), - &(PlcAdvSetup->PlcPhEcuSetup.PhECU_beta_mute), - PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st, - PlcAdvSetup->PlcPhEcuSetup.PhECU_Xavg, - decoder->la_zeroes, - x_tda, /* time domain aliased output */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - , - &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), - &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft) -#ifdef CR8_A_PLC_FADEOUT_TUNING - ,PlcAdvSetup->plc_fadeout_type, - &(PlcAdvSetup->PlcPhEcuSetup.PhECU_nonpure_tone_flag) /* nonpure tone flag */ -#endif - ); - - - ProcessingITDA_WIN_OLA_fl(x_tda, decoder->frame_length, decoder->imdct_win, decoder->imdct_winLen, decoder->imdct_laZeros, - h_DecSetup->imdct_mem, synth); - move_float(syntM_fl_c, synth, decoder->frame_length); - - - } - } - break; - case 3: - if (PlcSetup->nbLostCmpt == 1) - { - PlcAdvSetup->PlcTdcSetup.fract = ltpf_pitch_fr; - } - - processPerBandEnergy_fl(n_bandsPLC, bands_offsetPLC, hrmode, decoder->frame_dms, energies, PlcSetup->q_d_prev); - processTdcPreemphasis_fl(energies, &PlcAdvSetup->PlcTdcSetup.preemphFac, n_bandsPLC); - processTdcInverseOdft_fl(energies, n_bandsPLC, r, PlcAdvSetup->PlcTdcSetup.lpcorder); - processTdcLpcEstimation_fl(r, decoder->fs_idx, PlcAdvSetup->PlcTdcSetup.lpcorder + 1, A, decoder->frame_dms); - processTdcApply_fl(ltpf_pitch_int, &PlcAdvSetup->PlcTdcSetup.preemphFac, A, PlcAdvSetup->PlcTdcSetup.lpcorder, PlcAdvSetup->pcmbufHist, PlcAdvSetup->max_len_pcm_plc, decoder->frame_length, - decoder->frame_dms, decoder->fs, PlcSetup->nbLostCmpt, decoder->frame_length - decoder->la_zeroes, &PlcAdvSetup->stabFac, PlcAdvSetup->PlcTdcSetup.harmonicBuf, - PlcAdvSetup->PlcTdcSetup.synthHist, &PlcAdvSetup->PlcTdcSetup.fract, &PlcAdvSetup->PlcTdcSetup.seed, &PlcAdvSetup->PlcTdcSetup.gain_c, - &h_DecSetup->alpha, synth -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - ,PlcAdvSetup->plc_fadeout_type -#endif -); - - processTdcTdac_fl(synth, decoder->imdct_win, decoder->frame_length, decoder->la_zeroes, h_DecSetup->imdct_mem); - memmove(syntM_fl_c, synth, sizeof(LC3_FLOAT) * decoder->frame_length); - break; - case 4: - processNoiseSubstitution_fl(q_d_fl_c, PlcSetup->q_d_prev, decoder->yLen); - break; - default: - assert("Invalid PLC method!"); - } - } - - if (bfi == 0) - { - processPlcUpdateSpec_fl(PlcSetup->q_d_prev, q_d_fl_c, decoder->yLen); - } - - yLen = MIN(decoder->frame_length, MAX_PLC_LMEM); - if (PlcAdvSetup != NULL && (decoder->frame_dms == 100) && (hrmode == 0)) - { - /* BASOP processPLCspec2shape_fx(prev_bfi, bfi, q_old_d_fx, yLen, plcAd->PhECU_oold_grp_shape_fx, plcAd->PhECU_old_grp_shape_fx);*/ - plc_phEcu_processPLCspec2shape(prev_bfi_plc2, bfi, q_d_fl_c, yLen, - PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape, PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape); - } -} - diff --git a/lib_lc3plus/plc_main_fx.c b/lib_lc3plus/plc_main_fx.c new file mode 100644 index 000000000..1948aa23a --- /dev/null +++ b/lib_lc3plus/plc_main_fx.c @@ -0,0 +1,85 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +void processPLCmain_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, Word16 prev_bfi, + Word16 frame_length, Word16 la_zeroes, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 x_fx[], Word16 ola_mem[], + Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, const Word16 *band_offsets, Word16 bands_number, Word16 *damping, + Word16 old_pitch_int, Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, + AplcSetup *plcAd, Word16 frame_dms, Word8 *scratchBuffer, Word16 *pc_nbLostFramesInRow +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + ,Word32 rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + ,Word16 *alpha_type_2_table +#endif +) +{ + IF(sub(bfi, 1) == 0 && plcAd) + { + /* FFLC increases the PFLC counter */ + *pc_nbLostFramesInRow = add(*pc_nbLostFramesInRow, 1); + } + + processPLCclassify_fx(plcMeth, concealMethod, nbLostFramesInRow, bfi, old_pitch_int, frame_length, frame_dms, + fs_idx, yLen, q_old_d_fx, band_offsets, bands_number, plcAd, scratchBuffer +#ifdef ENABLE_HR_MODE + , hrmode +#endif + ); + + processPLCapply_fx( +#ifdef CR8_A_PLC_FADEOUT_TUNING + concealMethod, +#else + *concealMethod, +#endif + *nbLostFramesInRow, bfi, prev_bfi, frame_length, la_zeroes, w, x_fx, ola_mem, + ola_mem_exp, q_old_d_fx, q_old_fx_exp, q_d_fx, q_fx_exp, yLen, fs_idx, damping, old_pitch_int, + old_pitch_fr, ns_cum_alpha, ns_seed, frame_dms, plcAd, scratchBuffer +#ifdef ENABLE_HR_MODE + , hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , alpha_type_2_table +#endif + ); + + IF (bfi == 0) + { + processPLCupdateSpec_fx(q_old_d_fx, q_old_fx_exp, q_d_fx, q_fx_exp, yLen); + } + +#ifdef ENABLE_HR_MODE + IF (plcAd != NULL && (sub(plcAd->PhECU_frame_ms , 10) == 0) && (hrmode == 0)) +#else + IF (plcAd != NULL && (sub(plcAd->PhECU_frame_ms , 10) == 0)) +#endif + { + processPLCspec2shape_fx(prev_bfi, bfi, q_old_d_fx, yLen, plcAd->PhECU_oold_grp_shape_fx, plcAd->PhECU_old_grp_shape_fx); + } + +} + + diff --git a/lib_lc3plus/plc_noise_substitution.c b/lib_lc3plus/plc_noise_substitution.c deleted file mode 100644 index c366015fc..000000000 --- a/lib_lc3plus/plc_noise_substitution.c +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processNoiseSubstitution_fl(LC3_FLOAT* spec, LC3_FLOAT* spec_prev, LC3_INT32 yLen) -{ - memmove(spec, spec_prev, sizeof(LC3_FLOAT) * yLen); - - spec[0] *= 0.2; - spec[1] *= 0.5; -} - diff --git a/lib_lc3plus/setup_com_lc3.c b/lib_lc3plus/plc_noise_substitution_fx.c similarity index 54% rename from lib_lc3plus/setup_com_lc3.c rename to lib_lc3plus/plc_noise_substitution_fx.c index 33574f577..ab618ae7e 100644 --- a/lib_lc3plus/setup_com_lc3.c +++ b/lib_lc3plus/plc_noise_substitution_fx.c @@ -1,31 +1,32 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" + +#include "defines.h" #include "functions.h" -LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) +void processPLCNoiseSubstitution_fx(Word32 spec[], Word16 spec_prev[], Word16 L_spec) { - LC3_FLOAT max; - LC3_INT32 i; - - max = LC3_FABS(in[0]); - - for (i = 0; i < len; i++) + Dyn_Mem_Deluxe_In( + Counter i; + ); + + FOR (i = 0; i < L_spec; i++) { - if (LC3_FABS(in[i]) > LC3_FABS(max)) - { - max = LC3_FABS(in[i]); - } + spec[i] = L_deposit_h(spec_prev[i]); } - - return max; + + /* High pass to prevent overflows */ + spec[0] = Mpy_32_16_lc3plus(spec[0], 6553 /* 0.2 Q15*/); move32(); + spec[1] = Mpy_32_16_lc3plus(spec[1], 16384 /* 0.5 Q15*/); move32(); + + Dyn_Mem_Deluxe_Out(); } + + diff --git a/lib_lc3plus/plc_phecu_f0_refine_first.c b/lib_lc3plus/plc_phecu_f0_refine_first.c deleted file mode 100644 index c3f8edfab..000000000 --- a/lib_lc3plus/plc_phecu_f0_refine_first.c +++ /dev/null @@ -1,76 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - -void plc_phEcu_F0_refine_first( LC3_INT32 *plocs, /* i/o 0 ... Lprot/2 +1*/ - LC3_INT32 n_plocs, - LC3_FLOAT *f0est, /* i/o f0est */ - const LC3_INT32 Xabs_len, - LC3_FLOAT *f0binPtr, /* i */ - LC3_FLOAT *f0gainPtr, /* i */ - const LC3_INT32 nSubm - ) -{ - LC3_FLOAT sens; - LC3_INT32 i, j, high_idx, breakflag; - LC3_FLOAT f0est_lim[MAX_PLC_NPLOCS]; - LC3_FLOAT f0bin; - LC3_FLOAT f0gain; - - f0bin = *f0binPtr; - f0gain = *f0gainPtr; - - if (n_plocs > 0 && f0gain > 0.25) { - - sens = 0.5; - if (f0gain < 0.75) { - sens = 0.25; - } - - high_idx = -1; - for (i = 0; i < n_plocs; i++) { - if (plocs[i] <= 25) { /* 25 ~= 1550 Hz */ - high_idx = MAX(high_idx, i); - } else { - /* Optimization, only works if plocs vector is sorted. Which it should be. */ - break; - } - } - - if (high_idx != -1) { - high_idx++; - move_float(f0est_lim, f0est, high_idx); - - breakflag = 0; - for (i = 0; i < nSubm; i++) { - for (j = 0; j < high_idx; j++) { - if (LC3_FABS(f0est_lim[j] - (i+1) * f0bin) < sens) { - f0est[j] = (i+1)*f0bin; - plocs[j] = MIN(Xabs_len-1, MAX(1,(LC3_INT32) LC3_ROUND(f0est[j]))); - breakflag = 1; - break; - } - } - if (breakflag) { - break; - } - sens *= 0.875; - } - } - } - - return; -} - diff --git a/lib_lc3plus/plc_phecu_f0_refine_first_fx.c b/lib_lc3plus/plc_phecu_f0_refine_first_fx.c new file mode 100644 index 000000000..5c01a0029 --- /dev/null +++ b/lib_lc3plus/plc_phecu_f0_refine_first_fx.c @@ -0,0 +1,100 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +void plc_phEcu_F0_refine_first_fx(Word16 * plocs, /* i/o */ + const Word16 n_plocs_in, Word32 *L_f0est, /* i/o Q16 */ + const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15, + const Word16 nSubm) + +{ + Counter subm, i; + Word16 ploc, n_plocs_ana; + Word32 L_tmp = 0, L_diff, L_f0EstQ7, L_sensitivity_Q7; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_phEcu_F0_refine_first_fx", sizeof(struct { + Counter subm, i; + Word16 ploc, n_plocs_ana; + Word32 L_tmp, L_diff, L_f0EstQ7, L_sensitivity_Q7; + })); +#endif + + + + /* single initial peak F0 correction using available LTP information */ + + IF (sub(stPhECU_f0gainLtpQ15, ((Word16)(0.25 * 32768.0))) > 0) + { + ploc = -1; move16(); /* sentinel */ + n_plocs_ana = s_min(n_plocs_in, 4); /* only analyze at first 3 deteteced LF peaks */ + + /* only apply analysis below nsubm*pitmax_freq ~= 1600Hz */ + i = sub(n_plocs_ana, 1); + WHILE (i >= 0 && sub(plocs[i], (Word16)(1600.0 / 62.5)) > 0) + { + i--; + } + n_plocs_ana = add(i, 1); + + IF ((n_plocs_ana > 0)) + { + /* % find/correct first peak in f0est , that is a submultiple of n*f0Ltp*/ + FOR (i = 0; i < n_plocs_ana; i++) + { + + L_sensitivity_Q7 = L_deposit_l(((Word32)1) << (7 - 1)); /* 0.5 in Q7 */ + if (sub(stPhECU_f0gainLtpQ15, ((Word16)(0.75 * 32768.0))) < 0) + { + L_sensitivity_Q7 = L_shr_pos(L_sensitivity_Q7, 1); /* % more picky if correlation is rather low */ + } + + L_f0EstQ7 = L_shr_pos(L_f0est[i], 9); /* Q16 to Q7 */ + + FOR (subm = 1; subm <= nSubm; subm++) + { + /*adjf0 = abs(f0est - subm*stPhECU_f0hzLtpBin*ones(size(f0est))) < sensitivity ; % L1 difference, + vector operation over f0 + ind = find(adjf0==1,1); */ + L_diff = L_msu0(L_f0EstQ7, subm, stPhECU_f0hzLtpBinQ7); + L_diff = L_abs(L_diff); + IF (L_sub(L_diff, L_sensitivity_Q7) < 0) + { + L_tmp = L_shl_pos(L_mult0(subm, stPhECU_f0hzLtpBinQ7), 16 - 7); /* to Q16 */ + ploc = i; move16(); + BREAK; + } + L_sensitivity_Q7 = Mpy_32_16_lc3plus(L_sensitivity_Q7, (Word16)(0.875 * 32768.0 )); /* 2 cycles */ + } /* subm*/ + + IF (ploc >= 0) + { + BREAK; + } + } /* i, n_ploc_ana*/ + } + + if (ploc >= 0) + { + L_f0est[ploc] = L_tmp; move32(); /* in Q16 */ + /*ideally also integer plocs should be updated , e.g. if f0est goes from 1.45(plocs=1) to 1.6(plocs==2) + */ + /* but that is costly and not required as long as corr_phase width is large enough ]*/ + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + +} + + diff --git a/lib_lc3plus/plc_phecu_fec_hq.c b/lib_lc3plus/plc_phecu_fec_hq.c deleted file mode 100644 index 9213b9ea5..000000000 --- a/lib_lc3plus/plc_phecu_fec_hq.c +++ /dev/null @@ -1,160 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - -LC3_FLOAT plc_phEcu_imax2_jacobsen_mag(const Complex *y, LC3_FLOAT *c_jacobPtr) { - - LC3_FLOAT posi; - const Complex *pY; - Complex y_m1, y_0, y_p1; - Complex N; - Complex D; - LC3_FLOAT numer, denom; - - /* Jacobsen estimates peak offset relative y_0 using - * X_m1 - X_p1 - * d = REAL ( ------------------- ) * c_jacob - * 2*X_0 - X_m1 -Xp1 - * - * Where c_jacob is a window dependent constant - */ - - /* Get the parameters into variables */ - pY = y; - y_m1 = *pY++; - y_0 = *pY++; - y_p1 = *pY++; - - /* prepare numerator real and imaginary parts*/ - N = csub(y_m1, y_p1); - - /* prepare denominator real and imaginary parts */ - D = cmul(cmplx(2.0, 0.0), y_0); - D = csub(D, y_m1); - D = csub(D, y_p1); - - /* REAL part of complex division */ - numer = N.r*D.r + N.i*D.i; - denom = D.r*D.r + D.i*D.i; - - if (numer != 0 && denom != 0) { - posi = numer / denom * (*c_jacobPtr); - } else { - posi = 0.0; /* flat top, division is not possible choose center freq */ - } - - - posi = fclampf(-1.0, posi, 1.0); - return posi; -} - -/*-------------------------------------------------------------------* - * imax() - * - * Get interpolated maximum position - *-------------------------------------------------------------------*/ - -LC3_FLOAT plc_phEcu_interp_max(const LC3_FLOAT *y, LC3_INT32 y_len) { - LC3_FLOAT posi, y1, y2, y3, y3_y1, y2i; - LC3_FLOAT ftmp_den1, ftmp_den2; - - /* Seek the extrema of the parabola P(x) defined by 3 consecutive points so that P([-1 0 1]) = [y1 y2 y3] */ - y1 = y[0]; - y2 = y[1]; - - /* If interp between two values only */ - if (y_len == 2) { - if (y1 < y2) { - return 1.0; - } else { - return 0.0; - } - } - - y3 = y[2]; - y3_y1 = y3-y1; - ftmp_den1 = (y1+y3-2*y2); - ftmp_den2 = (4*y2 - 2*y1 - 2*y3); - - if(ftmp_den2 == 0.0 || ftmp_den1 == 0.0) { - return 0.0; /* early exit with left-most value */ - } - - y2i = ((LC3_FLOAT)-0.125) * sqrf(y3_y1) /(ftmp_den1) + y2; - /* their corresponding normalized locations */ - posi = y3_y1/(ftmp_den2); - /* Interpolated maxima if locations are not within [-1,1], calculated extrema are ignored */ - if (posi >= (LC3_FLOAT)1.0 || posi <= (LC3_FLOAT)-1.0) { - posi = y3 > y1 ? (LC3_FLOAT)1.0 : (LC3_FLOAT)-1.0; - } else { - if (y1 >= y2i) { - posi = (y1 > y3) ? (LC3_FLOAT)-1.0 :(LC3_FLOAT) 1.0; - } else if (y3 >= y2i) { - posi = (LC3_FLOAT)1.0; - } - } - - return posi + (LC3_FLOAT)1.0; -} - -/*----------------------------------------------------------------------------- - * fft_spec2_sqrt_approx_ () - * - * Approximation of sqrt(Square magnitude) of fft spectrum - * if min_abs <= 0.4142135*max_abs - * abs = 0.99 max_abs + 0.197*min_abs - * else - * abs = 0.84 max_abs + 0.561*min_abs - * end - * - - *----------------------------------------------------------------------------*/ - -void plc_phEcu_fft_spec2_sqrt_approx(const Complex* x, LC3_INT32 x_len, LC3_FLOAT* x_abs) { - LC3_INT32 i; - LC3_FLOAT max_abs, min_abs, re, im; - - for (i = 0; i < x_len; i++) { - re = LC3_FABS(x[i].r); - im = LC3_FABS(x[i].i); - max_abs = MAX(re, im); - min_abs = MIN(re, im); - - if (min_abs <= (LC3_FLOAT)0.4142135 * max_abs) { - x_abs[i] = (LC3_FLOAT)0.99*max_abs + (LC3_FLOAT)0.197*min_abs; - } else { - x_abs[i] = (LC3_FLOAT)0.84*max_abs + (LC3_FLOAT)0.561*min_abs; - } - } - - return; -} - -LC3_INT32 plc_phEcu_pitch_in_plocs(LC3_INT32* plocs, LC3_INT32 n_plocs) { - - LC3_INT32 i; - LC3_INT32 p_in_plocs; - - p_in_plocs = 0; - - for (i = 0; i < n_plocs; i++) { - if (plocs[i] > 0 && plocs[i] < 7) { - p_in_plocs++; - } - } - - return p_in_plocs; -} - diff --git a/lib_lc3plus/plc_phecu_fec_hq_fx.c b/lib_lc3plus/plc_phecu_fec_hq_fx.c new file mode 100644 index 000000000..ca2a345f4 --- /dev/null +++ b/lib_lc3plus/plc_phecu_fec_hq_fx.c @@ -0,0 +1,3157 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" +#include "math.h" /*dbg*/ + +/*---------------------------------------------------------------------* + * Local constants + *---------------------------------------------------------------------*/ + +#define DELTA_CORR 5 /* Tuning parameter - defining range for phase correction around peak */ +#define DELTA_CORR_F0_INT 2 /* Tuning parameter - defining range for phase correction around peak */ + +#define MAX_INCREASE_GRPPOW_FX 0 /* max. amplification in case of transients (in dB scale) */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING +# define ONE_SIDED_SINE_WIDTH (4) /* expected pure sine main lobe maximum width (4+1+4) bins *62.5 hz/bin => approx 560 Hz total width */ +# define SIDE_LIM 12539859L /* 10^ (4.5/20.0) = 2^(a); --> x= 0.747433821 -> Lx_Q24 = round((1L<<(24))*0.747433821)) = 12539859 */ +# define LFHF_LIM 16719812L /* 10^ (6.0/20.0) = 2^(b); --> x= 0.996578428 -> Lx_Q24 = round((1L<<(24))*0.996578428)) = 16719812 */ +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING +#else + +#if PLC2_FADEOUT_IN_MS == 0 +#define BURST_ATT_THRESH (4) /* speech start attenuate with losses in a row , stable content is +1 */ +#define ATT_PER_FRAME 2 /* ptr to a table , regular voiced attenuation settings table [0.4 dBx16 frames + 6dBx16 frames] 10 ms frame */ +/* #define ATT_PER_FRAME 1 */ /* ptr to a table , regular attenuation settings table [0.3 dBx16 frames + 6dBx16 frames] 10 ms frame */ +#define BETA_MUTE_THR 20 /* time threshold from BFI start to start of beta-noise further energy attenuation, by .5 each frame */ +/* #define OFF_FRAMES_LIMIT 30 in defines.h , table size and complete zero signal after BURST_ATT_THRESH + OFF_FRAMES_LIMIT */ +#endif + +#if PLC2_FADEOUT_IN_MS != 0 /* TD_PLC muting setting */ + /*% burst attenuation scheme is allowed to be indirectly controlled by a setting from TDC-PLC settings ,if negative PLC2_FADEOUT_IN_MS */ + +#if (PLC2_FADEOUT_IN_MS < 0) +#define FADEOUT_IN_MS PLC_FADEOUT_IN_MS /*% use TDC-SETTING as input */ +#else +#define FADEOUT_IN_MS PLC2_FADEOUT_IN_MS /* % use a PLC2 individual settings as basis */ +#endif + + /* %Examples + % FADEOUT_IN_MS ==30 ms --> shortest setting, att per frame idx = 10 for PLC2 + % FADEOUT_IN_MS ==40 ms --> att per frame idx = 8 setting for PLC2 + % FADEOUT_IN_MS ==60 ms --> att per frame idx = 6 setting for PLC2 (3+4) low decay then fast decay + % FADEOUT_IN_MS ==80 ms --> att per frame idx = 4 setting for PLC2 + % FADEOUT_IN_MS ==100 ms --> att per frame idx = 2 longest = near original setting for PLC2 + */ +#define PLC_P800_SPEECH_FADEOUT_IN_FRAMES (FADEOUT_IN_MS/10) +#define PLC2_FADEOUT_IN_FRAMES MIN(OFF_FRAMES_LIMIT,MAX(6, (3*PLC_P800_SPEECH_FADEOUT_IN_FRAMES))) /* help variable */ + +#define BURST_ATT_THRESH_PRE MIN(5,MAX(1,((1*PLC2_FADEOUT_IN_FRAMES)/6))) /* nominal 10-50 ms to start actual muting, will be thresh +1 */ + +#undef ATT_PER_FRAME +#define ATT_PER_FRAME MIN(10, MAX(2, 2*(6-BURST_ATT_THRESH_PRE))) /* we let the BURST_ATT_THRESH_PRE control the initial table selection */ +/* will eventually become ATT_PER_FRAME-1 = */ + /* table ptr 1,2 --> 16 low decay, 16 high decay, "0" */ + /* table ptr 3,4 --> 8 low decay, 24 high decay, "0" */ + /* table ptr 5,6 --> 4 low decay, 28 high decay , "0"*/ + /* table ptr 7,8 --> 2 low decay, 30 high decay, "0"*/ + /* table ptr 9,10 --> 1 low decay, 31 high decay, "0"*/ +#undef BURST_ATT_THRESH +#define BURST_ATT_THRESH MIN(BURST_ATT_THRESH_PRE, 4 ) /* nominal 10-40 ms, of no regular muting , 20-50 ms */ + + /* beta mute starts to become active when the low decay mute has ended */ +#undef BETA_MUTE_THR +#define BETA_MUTE_THR MIN( 4+(OFF_FRAMES_LIMIT/2)+1 , MAX(4, BURST_ATT_THRESH + 1 +(1<<(BURST_ATT_THRESH_PRE-1)))) /* nominal time to start mandatory decrease of Xavg */ + +#if (ATT_PER_FRAME < 2) || (ATT_PER_FRAME > 10) +#pragma message(" ROM table POW_ATT_TABLES needs update to change the ATT_PER FRAME constants supported are (1),2 (3), 4, (5) ,6 dB/frame ") +#endif + +#else +#if ( ATT_PER_FRAME != 2) +#pragma (" ROM table POW_ATT_TABLES needs update to change the ATT_PER FRAME constants supported are (1),2 dB/frame ") +#endif +#endif + + +#endif + + +#define CMPLMNT_PLOC_SENS_FX 2294 /* (1.0 - p_locator_sens) in Q15 */ +#define FEC_HQ_ECU_ROOT2 23170 /*(0x5a83) */ /* sqrt(2) in Q14 */ +#define FEC_TWOTHIRDS_Q15 21845 /* round(2^15*2/3) */ + +static void get_sin_cosQ10opt(Word16 phase, /* Q10 0..1023 i.e. 1024=2*pi */ + Word16 *ptrSin, /* Q15 */ + Word16 *ptrCos); /* Q15 */ + +static Word16 sqrt2ndOrder(const Word16); + +void my_wtda_fx(const Word16 *new_audio, /* i : input audio to be windowed Q0 20 ms , OPT can be output as well */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + Word32 * L_wtda_audio, /* o : tda audio Q16 20 ms */ + const Word16 L, Word8 *scratchBuffer); + +static void windowing_L(const Word16 *, Word32 *, const Word16 *, const Word16, const Word16); +static void windowing_ola(const Word16 *, Word16 *, const Word16 *, const Word16); +static void ola_add(const Word16 *, const Word16 *, Word16 *, const Word16); +static void intlvW32_2_flippedW16(Word32 *L_x, const Word16 numPairs, const Word16 L_prot, Word16 *x); +static void flippedW16_2_intlvW32(Word16 *x, const Word16 numPairs, const Word16 Lprot, Word32 *L_x); +static Word16 imax_fx(const Word16 *, const Word16); + + +Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F); + +static Word16 imax2_jacobsen_mag_fx(const Word16 *y_re, const Word16 *y_im, const Word16 special); +static void fft_spec2_sqrt_approx_fx(const Word16 x[], Word16 xMagSqrt[], const Word16 N); +static Word16 sqrtMagnApprox_fx(const Word16 re, const Word16 im); + +#ifdef CR8_A_PLC_FADEOUT_TUNING +static Word16 plc_phEcu_nonpure_tone_ana_fx(const Word16* plocs, const Word16 n_plocs, const Word16* X, + const Word32 *L_Xavg, /* i : Frequency group amp averages for tonal tilt analysis pref. Max upshifted */ + const Word16 Lprot, const Word16 fs_idx); +#endif + + +static void rotate_W16_fx(Word16 re_in, Word16 im_in, Word16 cosFactor, Word16 sinFactor, Word16 *re_out_ptr, + Word16 *im_out_ptr) +{ +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::rotate_W16_fx"); +#endif + *re_out_ptr = msu_r(L_mult(re_in, cosFactor), im_in, sinFactor); /* 2 ops no move when inlined */ + *im_out_ptr = mac_r(L_mult(re_in, sinFactor), im_in, cosFactor); /* 2 ops no move when inlined */ +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return; +} + +static void valley_magnitude_adj_fx(Word16 *re_ptr, Word16 *im_ptr, Word16 uniFactor, Word16 cosFactor) +{ + Word16 scale_fx; +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::valley_magnitude_adj_fx"); +#endif + + /* y = 0.5*((2*rand(1,10000) + 1*cos(2*pi*x)) - 1 */ /* y will be in -1 to 1 range */ + /* y = 1*((1*rand(1,10000) + 0.5*cos(2*pi*x)) - 1 */ /* y will be in -1 to 1 range */ + + scale_fx /*Q15*/ = mac_r(L_mult(uniFactor, 16384), cosFactor, 16384); + /* make gain distribution more like N(0,1) than uniform */ + + scale_fx /*Q14*/ = round_fx(L_mac((Word32)(16384L << 16), scale_fx, 4096)); + /* create a random gain scaling value with mean 1.0 and max 1.25 and min 0.75 */ + ASSERT(scale_fx <= (16384 + 8192)); + ASSERT(scale_fx >= (-16384 - 8192)); + *re_ptr = mult_r(scale_fx, shl_sat(*re_ptr, 1)); /* no moves , should be inlined */ + *im_ptr = mult_r(scale_fx, shl_sat(*im_ptr, 1)); /* no moves , should be inlined */ + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return; +} + +/*------------------------------------------------------------------* + * rand_phase() + * + * randomized phase in form of sin and cos components + *------------------------------------------------------------------*/ +Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F) +{ + /* 4x8+8 lookup scheme requiring ~40 Words of ROM freqRes 90/8 = 11.25 degrees */ + + /* x=(0:(5*8-1))*(2*pi)/32; y=sin(x);y_int=max(-32768,min(32767,round(y*32768))), y_int/32768 */ + + const Word16 *sincos_lowres_tab_cosQ15_fx = sincos_lowres_tab_sinQ15_fx + 8; + /* position at 90 degrees , ptr init */ + Word16 seed2; + Word16 seed2_shift; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("rand_phase_fx", sizeof(struct { + const Word16 *sincos_lowres_tab_cosQ15_fx; /* position at 90 degrees */ + Word16 seed2; /* 16 bit signed */ + Word16 seed2_shift; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::rand_phase_fx"); +#endif + + seed2 = extract_l(L_mac0(13849, seed, 31821)); + seed2_shift = lshr(seed2, 11); + /* logical shift to get uniform random 5 msb bits; 0-31 , 0 degrees to 31*360/32= 348.75 */ + *sin_F = sincos_lowres_tab_sinQ15_fx[seed2_shift]; move16(); /* these moves can often be avoided by returning seed2shift and inlining */ + *cos_F = sincos_lowres_tab_cosQ15_fx[seed2_shift]; move16(); /* these moves can often be avoided by inlining */ +/* total WC 5 ops */ +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return seed2; +} + +/*----------------------------------------------------------------------------- + * trans_burst_ana_fx() + * + * Transient analysis + *----------------------------------------------------------------------------*/ +void trans_burst_ana_fx( + const Word16 *xfp, /* i : Input signal (, only used if time_offset==0) now in up_scaled *Q_spec */ + Word16 * mag_chg, /* o : Magnitude modification vector Q15 */ + Word16 * ph_dith, /* o : Phase dither, 2*PI is not included (Q15, i.e., between 0.0 and 1.0) */ + Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients Q15 */ + const Word16 output_frame, /* i : Frame length */ + const Word16 time_offs, /* i : Time offset (integral multiple of output_frame) */ + const Word16 est_stab_content, /* i : 0.0=dynamic ... 1.0=Stable (==st->env_stab ) */ + Word16 * alpha, /* o : Magnitude modification factors for fade to average */ + Word16 * beta, /* : Magnitude modification factors for fade to average */ + Word16 * beta_mute, /* i/o : Factor for long-term mute */ + Word16 * Xavg, /* o : Frequency group average gain to fade to in same Q as X_sav */ + Word16 Q_spec, Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, Word16 oold_Ltot_exp_fx, + Word16 *oold_grp_shape_fx, + + Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx, Word16 old_Ltot_exp_fx, Word16 *old_grp_shape_fx, +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 fadeout, + Word32 * L_Xavg, /* full scale band amplitudes */ +#endif + Word8 *scratchBuffer /* Size = 4*4 * MAX_LTRANA + (2*4 + 1*2) * MAX_LGW + 8 */ +) +{ + Word16 att_val, attDegreeFrames; + Word32 * L_pGrPowLeft, *L_pGrPowRight; + Word32 * L_gr_pow_left, *L_gr_pow_right; + Word16 Lgw, i, k, burst_len; + Word16 man, expo; + Word16 att_always = 0; /* fixed attenuation per frequency group if set to 1 */ + Word16 oneOverFrame, roundEstMusContent, tmp16; +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 burst_att_thresh; + Word16 att_per_frame; +#else + Word16 burst_att_thresh = BURST_ATT_THRESH; + Word16 att_per_frame = ATT_PER_FRAME; +#endif + Word16 * tr_dec; + Word32 L_acc; + Word16 fs_scale; + Word16 scale_sh; + + Word32 L_oold_tmp, L_old_tmp; + Word16 oold_exp_fx, old_exp_fx; + Word16 margin_oold, margin_old; + Word16 fs_idx; + Word16 exp_diff; + Word16 Xavg_exp_fx, Xavg_mod_exp_fx; + Word16 tr_rise[MAX_LGW]; + Word16 tr_decay[MAX_LGW]; + Word16 man_in, expo_in, tmp; + Word32 L_tmp, L_tmp2; + Word16 thresh_tr_rise_lin_Q15; + Word16 thresh_tr_decay_lin_Q15; +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 beta_mute_thr; + Word16 fade_ms_ind; +#endif + +#ifdef DYNMEM_COUNT +#ifdef CR8_A_PLC_FADEOUT_TUNING + Dyn_Mem_In("trans_burst_ana_fx", sizeof(struct { + + Word16 att_val, attDegreeFrames; + Word32 * pGrPowLeft_L, *pGrPowRight_L; + Word32 * L_gr_pow_left, *L_gr_pow_right; + Word16 Lprot; + Word16 Lgw, i, k, burst_len; + Word16 man, expo; + Word16 att_always; /* fixed attenuation per frequency group if set to 1 */ + Word16 oneOverFrame, roundEstMusContent, tmp16; + + Word16 burst_att_thresh; + Word16 att_per_frame; + + Word16 * tr_dec; + UWord16 lsb; + Word32 L_acc; + Word16 fs_scale; + Word16 scale_sh; + + Word32 L_oold_tmp; + Word32 L_old_tmp; + Word16 fs_idx; + Word16 shift32; + Word16 margin_old; + Word16 margin_oold; + + Word16 Xavg_exp_fx, Xavg_mod_exp_fx; + Word16 tr_rise[MAX_LGW]; + Word16 tr_decay[MAX_LGW]; + + Word16 man_in, expo_in, tmp; + Word32 L_tmp, L_tmp2; + Word16 thresh_tr_rise_lin_Q15; + Word16 thresh_tr_decay_lin_Q15; + + Word16 beta_mute_thr; + Word16 fade_ms_ind; + })); +#else + Dyn_Mem_In("trans_burst_ana_fx", sizeof(struct { + + Word16 att_val, attDegreeFrames; + Word32 * pGrPowLeft_L, *pGrPowRight_L; + Word32 * L_gr_pow_left, *L_gr_pow_right; + Word16 Lprot; + Word16 Lgw, i, k, burst_len; + Word16 man, expo; + Word16 att_always; /* fixed attenuation per frequency group if set to 1 */ + Word16 oneOverFrame, roundEstMusContent, tmp16; + + Word16 burst_att_thresh; + Word16 att_per_frame; + + Word16 * tr_dec; + UWord16 lsb; + Word32 L_acc; + Word16 fs_scale; + Word16 scale_sh; + + Word32 L_oold_tmp; + Word32 L_old_tmp; + Word16 fs_idx; + Word16 shift32; + Word16 margin_old; + Word16 margin_oold; + + Word16 Xavg_exp_fx, Xavg_mod_exp_fx; + Word16 tr_rise[MAX_LGW]; + Word16 tr_decay[MAX_LGW]; + })); +#endif + +#endif + + UNUSED(xfp); + UNUSED(oold_xfp_w_E_exp_fx); + UNUSED(old_xfp_w_E_exp_fx); + + if (time_offs == 0) + { +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::trans_burst_ana_fx(1st)"); +#endif + } + else + { +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::trans_burst_ana_fx(N)"); +#endif + } + + fs_idx = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */ + ASSERT(fs_idx == (output_frame / 100)); + + L_gr_pow_left = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LGW */ /* Size = 4 * MAX_LGW */ + + L_gr_pow_right = (Word32 *)scratchAlign(L_gr_pow_left, sizeof(*L_gr_pow_left) * MAX_LGW); /* Size = 4 * MAX_LGW */ + + tr_dec = (Word16 *)scratchAlign(L_gr_pow_right, sizeof(*L_gr_pow_right) * MAX_LGW); /* Size = 2bytes * MAX_LGW */ + + oneOverFrame = oneOverFrameQ15Tab[fs_idx]; + Lgw = s_min(add(fs_idx, LGW8K), LGW48K); /* 4,5,6,7, (7/8) */ + + burst_len = add(mult_r(time_offs, oneOverFrame), 1); + + UNUSED(est_stab_content); + UNUSED(roundEstMusContent); +#ifndef CR8_A_PLC_FADEOUT_TUNING + burst_att_thresh = add(BURST_ATT_THRESH, 1); /* in Q0 , stable setting */ + att_per_frame = sub(ATT_PER_FRAME, 1); /* in Q0 , stable setting */ +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING + move16(); + fade_ms_ind = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; /* a shorter fading entry in fade_scheme_tab_fx */ + test(); + if (fadeout != 0) + { + fade_ms_ind = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16(); + /* a long fading table entry in fade_scheme_tab */ + } + + move16(); move16(); move16(); + att_per_frame = fade_scheme_tab_fx[fade_ms_ind][0]; + burst_att_thresh = fade_scheme_tab_fx[fade_ms_ind][1]; /* number of 1.0 frames before muting phase */ + /* band gain muting can take place earlier due to a band transient */ + beta_mute_thr = fade_scheme_tab_fx[fade_ms_ind][2]; /* faster muting of added noise starts when slow main signal fadeout is over */ +#endif + + + + +#ifdef PLC_FADEOUT_IN_MS +#ifdef CR8_A_PLC_FADEOUT_TUNING + ASSERT(att_per_frame >= 1 && att_per_frame <= 12); /* table based lookup restriction */ +#else + ASSERT(att_per_frame >= 1 && att_per_frame <=10 ); /* table based lookup restriction */ +#endif +#else + ASSERT(att_per_frame == 1 || att_per_frame == 2); /* table based lookup restriction */ +#endif + + *ph_dith = 0; /* peak scrambling, not in use */ + + attDegreeFrames = 0; move16(); + IF(sub(burst_len, burst_att_thresh) > 0) + { + att_always = 1; move16(); + /* increase degree of attenuation */ + + /* N.B. To facilitate the subsequent 10^(-att_degree/20) implementation + * so as to use direct table-lookup, + * the first (burstLen - burst_att_thresh) are NOT multiplied by "att_per_frame". */ + attDegreeFrames = sub(burst_len, burst_att_thresh); /* multiplied by 1.0 , */ + /* Furthermore, in order to minimize the size of the lookup-table required to + * implement 10^(-att_degree/10), hard limit attDegreeFrames to (30% of 100)=30. + * If attDegreeFrames is greater than 30, it means there are more than 30 successive + * bad frames. */ + if (sub(attDegreeFrames, OFF_FRAMES_LIMIT) > 0) + {/* Hard limit the no. of frames, for table lookup */ + attDegreeFrames = OFF_FRAMES_LIMIT; move16(); + } + } + + plc_phEcu_initWord16(alpha, 32767, MAX_LGW); + basop_memset(beta, 0, (MAX_LGW) * sizeof(Word16)); + IF(sub(burst_len, 1) <= 0) + { + *beta_mute = BETA_MUTE_FAC_INI; move16(); + *beta_mute = shr_pos(*beta_mute , 1); /* perceptual decrease */ + } + + IF(sub(burst_len, 1) <= 0) + { + L_pGrPowLeft = &L_gr_pow_left[0]; /* ptr init*/ + L_pGrPowRight = &L_gr_pow_right[0]; /* ptr init*/ + + fs_scale = xfp_wE_MDCT2FFTQ11[fs_idx]; move16(); + scale_sh = 4; /* 15-11 */ move16(); + /* L_*old_xfp_w_E_fx, always upscaled to max from the calculating function */ + + + L_oold_tmp = Mpy_32_16_lc3plus(L_oold_xfp_w_E_fx, fs_scale); + L_old_tmp = Mpy_32_16_lc3plus(L_old_xfp_w_E_fx, fs_scale); + + oold_exp_fx = add(oold_Ltot_exp_fx, scale_sh); + old_exp_fx = add(old_Ltot_exp_fx, scale_sh); + + /*re-normalize L_mantissas and adjust exps */ + margin_oold = norm_l(L_oold_tmp); + L_oold_tmp = L_shl_pos(L_oold_tmp, margin_oold); + oold_exp_fx = sub(oold_exp_fx, margin_oold); + + margin_old = norm_l(L_old_tmp); + L_old_tmp = L_shl_pos(L_old_tmp, margin_old); + old_exp_fx = sub(old_exp_fx, margin_old); + + /* now time to analyze how the actual L_tot exponent scaling should be done */ + /* bring up the lowest exp to the same exp as the higher exp, and scale down the corresponding mantissa */ + exp_diff = sub(old_exp_fx, oold_exp_fx); /* energy increase from oold to old in log2 shifts */ + + /* Overflow2 fix */ + exp_diff = s_max(-31, exp_diff); + exp_diff = s_min(31, exp_diff); + if (exp_diff > 0) + { /* oold_exp < old_exp */ + /* old_exp is limiting, shift down oold mantissa */ + L_oold_tmp = L_shr_pos(L_oold_tmp, exp_diff); + } + if (exp_diff < 0) + { /* oold_exp > old_exp */ + /* oold_exp is limiting, shift down old mantissa */ + L_old_tmp = L_shr_pos(L_old_tmp, negate(exp_diff)); + } + oold_exp_fx = s_max(oold_exp_fx, old_exp_fx); + old_exp_fx = oold_exp_fx; move16(); + + /* safety set lowest energy to 2 , as one bit is shifted away in avg calculation */ + L_oold_tmp = L_max(L_oold_tmp, 2L); + L_old_tmp = L_max(L_old_tmp, 2L); + + FOR(k = 0; k < Lgw; k++) /* NB Lgw may be shorter than all defined bands , e.g at at 48k */ + { + L_gr_pow_left[k] = Mpy_32_16_lc3plus(L_oold_tmp, oold_grp_shape_fx[k]); move32(); + L_gr_pow_right[k] = Mpy_32_16_lc3plus(L_old_tmp, old_grp_shape_fx[k]); move32(); + + /*Xavg[k] = sqrt(0.5f*(gr_pow_left[k]+gr_pow_right[k])/(float)(gw[k+1]-gw[k]));*/ + Xavg_exp_fx = sub(old_exp_fx, 1); /* virtual pre divide X_avg by 2 too keep precision in summation */ + L_acc = L_add(L_shr_pos(L_gr_pow_left[k], 1), L_shr_pos(L_gr_pow_right[k], 1)); + L_acc = L_shr_pos(L_acc, gw_len_inv_shift_fx[k]); /* divide by (bandwidth/2) in bins */ + + { /* new Xavg_fx calculation */ + L_acc = L_max(L_acc, 1L); + tmp = norm_l(L_acc); + Xavg_exp_fx = sub(Xavg_exp_fx, tmp); + L_acc = L_shl_pos(L_acc, tmp); /* now between 0.5 an 1.0*/ + + expo_in = add(Xavg_exp_fx, 0); + man_in = round_fx_sat(L_acc); + + /* now allow both positive and negative expos into sqrt */ + man = sqrt2ndOrder(man_in); + if (s_and(expo_in, 1) != 0) + { + man = mult_r(man, FEC_HQ_ECU_ROOT2); /* odd exp operation */ /* 1/sqrt(2) */ + } + expo = shr_r(expo_in, 1); /* apply even part of exp , square root operation. shr_r needed for positive side exps */ + + + + L_acc = L_deposit_h(man); + Xavg_exp_fx = add(expo, 0); + /*Note: sqrt approximaton may overshoot e.g- sqrt(1.0) may become 1.0001 i.e. saturation is needed when eventually applying expo */ + + + /* Xavg (unscaled flt in L_acc*2^(exp-31)) needs to be saved in the same scale + Q as the stored 16bit + * Xsav_fx, for use in subst_spec() */ + /* move Xavg fft scale to fx domain fx-fft scale*/ + L_acc = Mpy_32_16_lc3plus(L_acc, PhEcu_Xsav_Flt2FxScaleQ15[fs_idx]); /* fs fixed fractional change */ + Xavg_mod_exp_fx = sub(Xavg_exp_fx, PhEcu_Xsav_Flt2FxDnShift[fs_idx]); /* fs fixed exp change*/ + Xavg_mod_exp_fx = add(Xavg_mod_exp_fx, Q_spec); /* signal adaptive exp change*/ + + /* :: move to Q_spec domain of Xsav , Q fixed in first BFI frames */ + + /* extract Q0 value shift so that the mantissa is in the high part with man*2,^(0-15) */ + exp_diff = sub(15, Xavg_mod_exp_fx); + + + exp_diff = s_min(31, exp_diff); /* limit to meaningfull DSP shifts as described by up to 6 bits */ + exp_diff = s_max(-32, exp_diff); + if (exp_diff > 0) + { + L_acc = L_shr_pos(L_acc, exp_diff); /* may underflow */ + } + + if (exp_diff < 0) + { + L_acc = L_shr_sat(L_acc, exp_diff); + } +#ifdef CR8_A_PLC_FADEOUT_TUNING + L_Xavg[k] = L_acc; /* export full 31 bit scale band amplitude */ +#endif + Xavg[k] = round_fx_sat(L_acc); /* extract high part */ + + } /*end of new Xavg_fx calculation */ + /* internal transition detection */ + + { /* pure percentage based transient detection */ + thresh_tr_rise_lin_Q15 = PhEcu_frac_thr_rise_lin_Q15[k]; + thresh_tr_decay_lin_Q15 = PhEcu_frac_thr_decay_lin_Q15[k]; + + /* analyse rise */ + /* one of L_left or L_right should be pre-upshifted to a near max mantissa, (in one band ) */ + L_tmp2 = L_deposit_h(0); + L_tmp = Mpy_32_16_lc3plus(*L_pGrPowRight, thresh_tr_rise_lin_Q15); + if (L_sub(*L_pGrPowLeft, L_tmp) <= 0) + { + L_tmp2 = L_deposit_l(1); + } + + if (*L_pGrPowLeft == 0) /* denominator zero special cases */ + { + /* rise: Right/Left ; " * / 0 " --> tr_rise=1 ; "0/0" --> tr_rise = 0 */ + L_tmp2 = L_min(*L_pGrPowRight, 1L); + } + tr_rise[k] = extract_l(L_tmp2); move16(); + + /* analyse decay */ + L_tmp2 = L_deposit_h(0); + L_tmp = Mpy_32_16_lc3plus(*L_pGrPowLeft, thresh_tr_decay_lin_Q15); + if (L_sub(L_tmp, *L_pGrPowRight) >= 0) + { + L_tmp2 = L_deposit_l(1); + } + if (*L_pGrPowRight == 0) /* right side no energy , special cases */ + { + /* decay: Right/Left ; " 0 / * " --> tr_decay=0 ; "0/0" --> tr_decay = 0 */ + L_tmp2 = L_deposit_h(0); + } + tr_decay[k] = extract_l(L_tmp2); move16(); + + tr_dec[k] = s_max(tr_rise[k], tr_decay[k]); move16(); + + } /* percentage tr_dec */ + /* magnitude modification, calculated for decay only */ + IF(add(tr_dec[k], att_always) != 0) + { + +#if MAX_INCREASE_GRPPOW_FX != 0 +#error trans_burst_ana_fx-- The following implementation is incorrect +#endif + att_val = 32767; move16(); + IF(L_sub(*L_pGrPowRight, 0) > 0) + { + IF(L_sub(*L_pGrPowRight, *L_pGrPowLeft) < 0) /* decay , i.e., (gr_pow_right/gr_pow_left) < 1.0 */ + { + /* Compute sqrt(grp_pow_chg), where grp_pow_chg = gr_pow_right/gr_pow_left. */ + tmp16 = plc_phEcu_ratio_fx(*L_pGrPowRight, *L_pGrPowLeft, &expo); /* output tmp16 in Q14 */ + + expo = sub(expo, (15 - 14)); /* Now, tmp16 is considered in Q15 */ + i = norm_s(tmp16); + man = shl_pos(tmp16, i); /* Mandatory normalization before sqrtNthOrder(). */ + expo = add(expo, i); + man = sqrt2ndOrder(man); + if (s_and(expo, 1) != 0) /* Check even or odd. */ + { + man = mult_r(man, FEC_HQ_ECU_ROOT2); + } + expo = shr_pos(expo, 1); /* Divided by 2-- square root operation. */ + att_val = shr(man, expo); /* Denormalize the mantissa back to Q15. */ + } + /* ELSE + { + do nothing because (gr_pow_right/gr_pow_left) >= 1.0 + } + */ + } + + mag_chg_1st[k] = att_val; move16(); + mag_chg[k] = att_val; move16(); + } + ELSE + { + mag_chg_1st[k] = 32767; move16(); + mag_chg[k] = 32767; move16(); /* Set to ]1.0 in Q15 */ + } + + L_pGrPowLeft++; + L_pGrPowRight++; + } /* FOR band k */ + } + ELSE /* sub(burst_len, 1) <= 0) */ + { + /* BURST path */ + + /* Since attDegreeFrames is discrete (integer) and hard limited to OFF_FRAMES_LIMIT, + * it is easier to implement 10^(-att_degree/20.0) by a simply direct + * table-lookup. Also, att_per_frame is discrete as well and can be + * either ATT_PER_FRAME-1 or ATT_PER_FRAME and nothing else. This + * means only 2 tables of size=(OFF_FRAMES_LIMIT+1) each are required. + * To take square root into account, it is divided by 20 instead of 10. */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (sub(burst_len, beta_mute_thr) > 0) /* beta_mute_thr coincides/close to stronger 6dB muting phase */ + { + *beta_mute = shr_pos_pos(*beta_mute, 1); + } +#endif + + + FOR(k = 0; k < Lgw; k++) /* Lgw may be shorter than all bands at 48k */ + { + /* global burst attenuation */ + #if PLC2_FADEOUT_IN_MS != 0 + #ifdef CR8_A_PLC_FADEOUT_TUNING + /* att_per_frame idx = "1:12") */ +#else + /* att_per_frame idx = "1:10") */ +#endif + att_val = POW_ATT_TABLES[att_per_frame][s_min(OFF_FRAMES_LIMIT, attDegreeFrames)]; move16(); +#else + /* att_per_frame idx = "1:2") */ + att_val = POW_ATT_TABLES[att_per_frame][s_min(OFF_FRAMES_LIMIT, attDegreeFrames)]; move16(); + /* 10^(-attDegreeFrames*(att_per_frame = "1 or 2")/20) */ +#endif + + mag_chg[k] = mult_r(mag_chg_1st[k], att_val); /* Q15 */ + +#ifndef CR8_A_PLC_FADEOUT_TUNING + if (sub(burst_len, BETA_MUTE_THR) > 0) /* BETA_MUTE_THR ~= (5+15) coincides/close to stronger 6dB muting phase */ + { + *beta_mute = shr_pos_pos(*beta_mute, 1); + } +#endif + alpha[k] = mag_chg[k]; move16(); + ASSERT(beta[k] == 0); /* initialization required */ + IF(sub(alpha[k], 32766) < 0) + { + /* beta_pre[k] = sqrt(1.0f - SQR(alpha[k])); */ + /* beta[k] = beta_pre[k]* *beta_mute;*/ + /* (1.0-alpha.^2), in exp 1 due to L_mult0; */ + + L_acc = L_sub((INT32_MAX >> 1) + 1, L_mult0(alpha[k], alpha[k])); + { + + /* use lower complex(WMOPS/ROM) 2nd-order sqrt approximation */ + Word32 L_man, L_acc2 = L_acc; + Word16 tmp, expo_in, expo2, man_in, man; + /* updated code using the 2nd order approximation routine */ + /* form is flt=(L_acc2*2.^(-31 + 1) */ + + tmp = norm_l(L_acc2); /* tmp is always 1 or higher due to Lmac0 downshift */ + man_in = round_fx_sat(L_shl_pos(L_acc2, tmp)); + expo_in = sub(1, tmp); /* 1 due to original 1 bit margin gain in L_mult0 */ + + /* both positive and negative expos into sqrt */ + man = sqrt2ndOrder(man_in); + if (s_and(expo_in, 1) != 0) + { + man = mult_r(man, FEC_HQ_ECU_ROOT2); /* odd exp operation */ /* sqrt(2)/2 */ + } + + expo2 = shr_r(expo_in, 1); /* apply square root operation. shr_r needed for pos and neg exps */ + ASSERT(expo2 <= 1); + + L_man = L_deposit_h(man); + L_man = L_shl_sat(L_man, expo2); /* move to a zero exp , _sat needed for 1.0 input (due to approximation overshoot) */ + + man = round_fx_sat(L_man); /* better perf with round here */ + + + beta[k] = mult_r(*beta_mute, man); move16(); + } + + /* bw Lowpass shape additive component */ + /* tab[LGW48K + 1] = { 1.0, ....1.0, 0.5,0.5, ... 0.1, 0.1 } */ + + IF(sub(k, LGW32K - 1) >= 0) + { + beta[k] = mult_r(beta[k], 3277); /* 0.1 in Q15 */ + } + ELSE IF(sub(k, LGW16K - 1) >= 0) + { + beta[k] = mult_r(beta[k], 16384); /* 0.5 in Q15 */ + } + + /* + % limit Xavg noise contribution further in case of offset/tr_decay + % attenuation was already active + + if (burst_len <= burst_att_thresh) && ( stPhECU_mag_chg_1st(k) < (32766/32768) ) + XavgFadeinFactor = (burst_len-1)/burst_att_thresh; + XavgFadeinFactor = min(1.0, XavgFadeinFactor); + beta(k) = beta(k)*XavgFadeinFactor; + % limit initial Xavg noise contribution until We have reached regular burst attenuation + end + end + */ + IF( sub(mag_chg_1st[k], 32767) <0 ) + { /* offset muting was started before burst muting phase */ + /* Xavg noise gradually increased during a short period */ + Word16 XavgFadeinFactor = 32767; + Word16 ratio2_3_4_5tab[4][5 - 1] = { + {(Word16)(.5 * 32768.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0)}, /* 1/2*/ + {(Word16)(.333 * 32768.0), (Word16)(.666 * 32768.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0)}, /* 1/3*/ + {(Word16)(.25 * 32768.0), (Word16)(.5 * 32768.0), (Word16)(.75 * 32768.0), (Word16)(1.0 * 32767.0)}, /* 1/4 */ + {(Word16)(.2 * 32768.0), (Word16)(.4 * 32768.0), (Word16)(.6 * 32768.0), (Word16)(.8 * 32768.0)} /* 1/5 */ + + }; + ASSERT(burst_att_thresh >= 1 && burst_att_thresh <= 5); + ASSERT(burst_len >= 2); + if (sub(burst_len,burst_att_thresh) <= 0) + { + ASSERT(burst_len - 2 < (5-1)); + ASSERT(burst_att_thresh-1-1 < (4)); + XavgFadeinFactor = ratio2_3_4_5tab[burst_att_thresh-1-1][burst_len - 2]; /* second bfi frame burst_len= is 2 */ + } + beta[k] = mult_r(beta[k], XavgFadeinFactor); /* n Q15 */ + } + } /* IF (sub(alpha[k], 32766) < 0) */ + } /* FOR k*/ + + } /* BURST */ + + + + IF(sub(output_frame, L_FRAME48K) == 0) + { /* for 48kHz set/handle scalings of last group/band the same way as previous lower freq band(s) */ + + FOR(k = Lgw; k < MAX_LGW; k++) + { + tr_dec[k] = tr_dec[k - 1]; move16(); /* only available in first bfi frame */ + Xavg[k] = Xavg[k - 1]; move16(); + mag_chg_1st[k] = mag_chg_1st[k - 1]; move16(); + mag_chg[k] = mag_chg[k - 1]; move16(); + alpha[k] = alpha[k - 1]; move16(); + beta[k] = beta[k - 1]; move16(); + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +} + +/*----------------------------------------------------------------------------- + * imax_fx() + * + * Get interpolated maximum position + *-----------------------------------------------------------------------------*/ +static Word16 imax_fx( /* o: The location, relative to the middle of the 3 given data point, of the maximum. (Q15) */ + const Word16 *y, /* i: The 3 given data points. */ + const Word16 special /* i: -1 = left edge special case, 0 = normal, +1 = right edge special case */ +) +{ + Word16 posi; + Word16 man, expo, edge; + const Word16 *pY; + Word32 L_y1, L_y2, L_y3, L_numer, L_denom, L_sign, L_acc, L_y3_y1; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("imax_fx", sizeof(struct { + Word16 posi; + Word16 man, expo, edge; + const Word16 *pY; + Word32 L_y1, L_y2, L_y3, L_numer, L_denom, L_sign, L_acc, L_y3_y1; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::imax_fx"); +#endif + + /* Seek the extremum of the parabola P(x) defined by 3 consecutive points + so that P([-1 0 1]) = [y1 y2 y3] */ + pY = y; + L_y1 = L_deposit_l(*pY++), L_y2 = L_deposit_l(*pY++), L_y3 = L_deposit_l(*pY); + + /* The extremum value: + * y2i = -0.125f * SQR(y3_y1) / (y1+y3-2*y2)+y2 + * is not computed. Alternatively, the derivative of the parabola evaluated at y=0, + * dP/dy|y=0, is used to determine whether the extremum is maximum or not. + */ + + /* Compute the extremum location: posi = (y3 - y1)/(4*y2 - 2*y1 - 2*y3). */ + L_y3_y1 = L_sub(L_y3, L_y1); + L_acc = L_shl_pos(L_y2, 1); /* N.B. y2 is multiplied by 2 not 4. */ + L_acc = L_sub(L_acc, L_y1); /* N.B. Y1 is not multiplied by 2. */ + L_denom = L_sub(L_acc, L_y3); /* N.B. Y3 is not multiplied by 2. */ + L_sign = L_xor(L_y3_y1, L_denom); /* Preserve the sign since div_s() only takes positive arguments. */ + L_numer = L_abs(L_y3_y1); + L_denom = L_abs(L_denom); + + test(); + IF(L_numer == 0 || L_denom == 0) + { + posi = 0; move16(); /* flat top , exit with center freq. */ + } + ELSE + { + + IF(L_sub(L_denom, L_shr_pos_pos(L_numer, 1)) > 0) + { + /* Although the output of ratio() is in Q14, adding the missing factor of 2 (See above) + * in the denominator, the output is now considered to be in Q15. */ + man = plc_phEcu_ratio_fx(L_numer, L_denom, &expo); /* The mantissa is considered in Q15 */ + + posi = shr_sat(man, expo); /* in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */ + } + ELSE + { + posi = 0x7fff; move16(); + } + + if (L_sign < 0) /* Restore the sign. */ + { + posi = negate(posi); + } + + /* For both edges (left and right), the extremum found above may be minimum. + * It needs to reject the minimum. */ + IF(special != 0) /* Either edge special case. */ + { + edge = 0x7fff; /* 1 in Q15 for the right edge special case */ move16(); + if (special < 0) + { + edge = 0; /* Left edge special case */ move16(); + } + + /* The derivative (slope) of the interpolating parabola = 2*A*y + B, + * where A = (y3 + y1)/2 - y2 + * and B = (y3 - y1)/2. + * Therefore, the slope at y=0 is simply B. Use this slope to determine + * if the parabola is concave upward or downward. + */ + IF(posi > 0) /* The extremum is in between the middle and the right given data points. */ + { + posi = sub(0x7fff, posi); /* maximum case */ + if (L_sub(L_y3, L_y1) <= 0) /* Check the slope at y=0, i.e., at the middle given data point. */ + { + posi = edge; /* minimum case */ move16(); + } + } + ELSE /* The extremum is in between the left and the middle given data points. */ + { + posi = add(0x7fff, posi); /* maximum case */ + if (L_sub(L_y3, L_y1) >= 0) + { + posi = edge; /* minimum case */ move16(); + } + } + } + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return posi; + /* Q15. The position either left or right relative to the index of the middle of the 3 given data points. */ +} + + /*----------------------------------------------------------------------------- + * spec_ana_fx() + * + * Spectral analysis + *-----------------------------------------------------------------------------*/ + /* OPT add the FB transient input flags , and skip peakfinder if fullband transient is set */ + void spec_ana_fx(Word16 * xfp, /* i/o : Input 16ms pre-upscaled time signal, output xfp utility buffer */ + Word16 * plocs, /* o : The indicies of the identified peaks Q0 */ + Word32 * L_plocsi, /* o : Interpolated positions of the identified peaks Q16 */ + Word16 * num_plocs, /* o : Number of identified peaks Q0 */ + Word16 * X_sav, /* o : Stored fft spectrum */ + const Word16 output_frame, /* i : Frame length Q0 */ + const Word16 bwidth_fx, /* i : Encoded Fs index Q0 */ + const Word16 *sp_ana_win, /* i : spectral analysis window Q15 */ + const Word16 f0hzLtpBinQ7, /* i : LTP bin frequency in normalized Hz Q7 */ + const Word16 norm_corrQ15_fx, /* i : correlation for lag at f0hzLtpBinQ7 */ + Word16 maxLprot, Word16 maxPlocs, + Word8 *scratchBuffer /* Size = 4 * (MAX_LPROT + MAX_LPROT_RED + 1) + 2 * MAX_PLOCS */ + ) + { + Counter n, k; + Word16 nJacob, Lprot, hamm_len2 = 0, Lprot2, Lprot2p1; + Word32 *L_xfp; + + Word16 *pXfp; + Word16 *pPlocs; + Word16 Xmax, Xmin, sens; + Word16 rectLength, fraction; + Word32 *pPlocsi_L; + Word32 L_acc; + Word16 peak_range_1; + Word16 stop_band_start; + Word16 stop_band_length; + Word16 fft_scale; + Word8 * buffer_fft; + Word16 currPlocs, endPlocs; + Word16 P_in_plocs; + Word16 n_real_interp_tail; + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::spec_ana_fx(1st)"); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("spec_ana_fx", sizeof(struct { + Counter n, k; + Word16 nJacob ,Lprot, hamm_len2, Lprot2, Lprot2p1; + Word32 *L_xfp; + Word32 *pXfp_L; + Word16 *y_re_ptr, *y_im_ptr; /* otrs to Xsav as xfp was overwritten */ + Word16 *pXfp, *pXfp1, *pPlocs; + Word16 Xmax, Xmin, sel; + Word16 rectLength, fraction, special; + Word32 *pPlocsi_L; + Word32 L_acc; + Word16 peak_range_1; + Word16 stop_band_start; + Word16 stop_band_length; + Word16 fft_scale; + Word8 * buffer_fft; + Word16 fft_scale_by4; + Word16 currPlocs, endPlocs; + Word16 P_in_plocs; + Word16 n_real_interp_tail; + })); +#endif + /* Initialize for 48k to avoid warnings + Lprot - length of saved prototype samples + hamm_len2 - half Hamming window length + pFftTbl - Table for real input FFT + LprotLog2Minus1 - FFT stages for complex input FFT + */ + + + L_xfp = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LPROT bytes */ + buffer_fft = scratchAlign(L_xfp, sizeof(*L_xfp) * maxLprot); /* Size = 4 * (MAX_LPROT_RED + 1) + 2 * MAX_PLOCS */ + + ASSERT(bwidth_fx >= 0 && bwidth_fx <= 4); /* avoid bwidth_fx variable warning */ + + Lprot = LprotSzPtr[bwidth_fx]; + move16(); + hamm_len2 = DEPR_i_mult(3, mult(output_frame, (Word16)(3277) /* divBy10 + floor */)); /* 3 ms */ + fft_scale = PhEcuFftScale[bwidth_fx]; + move16(); /* 32,16,8 kHz all have fft scale 0, 24 has 8, 48 has 4 */ + Lprot2 = shr_pos(Lprot, 1); + Lprot2p1 = add(Lprot2, 1); /* Magnitude lengths */ + rectLength = sub(Lprot, shl_pos(hamm_len2, 1)); + /* The length of the rectangular portion of the Hamming-Rectangular window. */ + { +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::WhrAnaWin+fft"); +#endif + + /* Apply hamming-rect window */ + windowing_L(xfp, L_xfp, sp_ana_win, rectLength, hamm_len2); + BASOP_rfftN(L_xfp, Lprot, &fft_scale, buffer_fft); + } +#ifdef WMOPS + BASOP_sub_sub_end(); /* anawin+fft */ +#endif + + /* Convert 32 Bit intlv FFT into phecu 16 bit flipped fft format */ + /* can not yet be an inplace operation */ + + intlvW32_2_flippedW16(L_xfp, sub(Lprot2, 1), Lprot, xfp); + + /* Apply zeroing of non-coded FFT spectrum above 20 kHz */ + IF(sub(output_frame, ((L_FRAME48K) * 40) / 48) >= 0) /* only relevant for 48kHz in LC3plus */ + { + stop_band_start = ((LPROT48K / 2) * 40) / 48; /* initial start position in real part , 320 */ + stop_band_length = ((LPROT48K * 8) / 48) - 1; /* real tail and into Im parts , 128-1 */ + stop_band_start = add(stop_band_start, 1); /* exclude DC ... */ + + basop_memset(xfp + stop_band_start, 0, (stop_band_length) * sizeof(Word16)); + } + + peak_range_1 = s_min(Lprot2p1, MAX_LPROT_RED / 2 + 1); /* limit preliminary only active for 48k to save WMOPS */ + + basop_memmove(X_sav, xfp, (Lprot) * sizeof(Word16)); + + /* Magnitude representation */ + fft_spec2_sqrt_approx_fx(xfp, xfp, Lprot); + /* inplace, i.e. [ Dc, real part of xfp ,Fs/2 ] will be replaced by magnitude(scaled by .5) */ + + /* Find global maximum and minimum. */ + plc_phEcu_maxval_fx(xfp, peak_range_1, &Xmax); + plc_phEcu_minval_fx(xfp, peak_range_1, &Xmin); + sens = mult_r(sub(Xmax, Xmin), CMPLMNT_PLOC_SENS_FX); + + + plc_phEcu_peak_locator_fx(xfp, peak_range_1, plocs, num_plocs, sens, Xmax, Xmin, MAX_LPROT_RED, buffer_fft); + + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::Peaks_refine"); +#endif + + /* Refine peaks */ + pPlocsi_L = L_plocsi; + pPlocs = plocs; + /* n = sub(*num_plocs, 1); */ /* -1 so as to exclude the very last peak. */ + n = *num_plocs; /* number of peaks to process */ + /* Special case-- The very 1st peak if it is at 0 index position (DC) */ + /* With DELTA_CORR_F0_INT == 2 one needs to handle both *pPlocs==0 and *pPlocs==1 */ + logic16(); + IF((n > 0) && (sub(*pPlocs, 0) == 0)) /* Very 1st peak position possible to have a peak at 0/DC index position. */ + { + fraction = imax_fx(xfp, -1); /* -1 signifies special left edge case. */ + L_acc = L_deposit_h(*pPlocs++); /* N.B., (*pPlocs) must be zero here. */ + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */ + n = sub(n, 1); /* This special case is taken care of -- one less peak to go */ + } + logic16(); + IF((n > 0) && (sub(*pPlocs, 1) == 0)) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ + { + fraction = imax_fx(xfp, 0); /* for parabolic this is not a special case. */ + L_acc = L_deposit_h(*pPlocs++); /* N.B., (*pPlocs) must be 1 here. */ + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */ + n = sub(n, 1); /* This special case is taken care of -- one less peak to go */ + } + + /* All remaining peaks except the very last two possible integer positions */ + currPlocs = *pPlocs++; move16(); + endPlocs = sub(Lprot2p1, DELTA_CORR_F0_INT); /* last *pPlocs position for Jacobsen */ + + /* precompute number of turns based on endpoint integer location and make into a proper FOR loop */ + IF(n > 0) + { + nJacob = n; move16(); + + /* catch all three xxx01 , xxx10 and xxx11 , + and not only xxx01, xxx10 */ + + n_real_interp_tail = 0; move16(); + if (sub(endPlocs, plocs[sub(*num_plocs, 1)]) <= 0) + { + n_real_interp_tail = add(n_real_interp_tail, 1); + } + + logic16(); + if (sub(n,1) > 0 && sub(endPlocs, plocs[sub(*num_plocs, 2)]) <= 0) + { + n_real_interp_tail = add(n_real_interp_tail, 1); + } + + nJacob = sub(nJacob, n_real_interp_tail); + + FOR (k = 0; k < nJacob; k++) + { + fraction = imax2_jacobsen_mag_fx(&(X_sav[currPlocs - 1]), &(X_sav[Lprot - 1 - currPlocs]), 0); /* in Q15 */ /* not endpoint */ + move16(); move16(); /* account for inloop indirect ptrs into Xsav */ + + L_acc = L_deposit_h(currPlocs); + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16. Append the fractional part to the integral part. */ + currPlocs = *pPlocs++; move16(); + } + n = sub(n, nJacob); + } + + /* At this point there should at most two plocs left to process */ + /* the position before fs/2 and fs/2 both use the same magnitude points */ + + IF(n > 0) + { + /* [ . . . . . . . ] Lprot/2+1 positions */ + /* | | | */ + /* 0 (Lprot/2-2) (Lprot/2) */ + + pXfp = xfp + sub(Lprot2, 2); + IF(sub(currPlocs, sub(Lprot2p1, DELTA_CORR_F0_INT)) == 0) + /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ + { + fraction = imax_fx(pXfp, 0); /* for parabolic this is not a special case. */ + + L_acc = L_deposit_h(currPlocs); /* N.B., (*pPlocs) must be 1 here. */ + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */ + currPlocs = *pPlocs++; move16(); + n = sub(n, 1); /* This special case is taken care of -- one less peak to go */ + + if (n > 0) + { + /* allow for an additional consecutive final plocs after (Fs/2-1) at Fs/2 */ + currPlocs = *pPlocs++; move16(); + } + } + + /* Here the only remaining point would be a fs/2 plocs */ + /* pXfp = xfp + sub(Lprot2,1); already set just a reminder where it whould point */ + IF(n > 0) /* fs/2 which makes special case . */ + { + fraction = imax_fx(pXfp, 1); /* for parabolic this is a special case. */ + + L_acc = L_deposit_h(currPlocs); /* N.B., (*pPlocs) must be 1 here. */ + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */ + currPlocs = *pPlocs++; move16(); + n = sub(n, 1); /* This special case is taken care of -- one less peak to go */ + } + } + + /* here n should be 0 if all peaks have been processed */ + ASSERT(n == 0); + + /* Check number of plocs within an assumed pitch range */ + P_in_plocs = 0; move16(); + FOR(n = 0; n < *num_plocs; n++) + { + /* count number of peaks in locations 1,2,3,4,5,6 , ~= 60 Hz ... 380 Hz */ + fraction = s_min(1, plocs[n]); /* 0 stays zero , otherwise 1 */ + if (sub(plocs[n], 7) < 0) + { + P_in_plocs = add(P_in_plocs, fraction); + } + } + +#ifdef WMOPS + BASOP_sub_sub_end(); /* peaks refine */ +#endif + + logic16(); + IF(f0hzLtpBinQ7 > 0 && P_in_plocs > 0) + { + Word16 n_plocs_in, n_plocs_out; + + n_plocs_in = *num_plocs; move16(); + + /* NB LF peak analysis may add adjacent peaks in { plocs, L_plocsi}, (output from peakfinder did not have + * adjacent peaks ) */ + plc_phEcu_LF_peak_analysis_fx(plocs /* i/o */, num_plocs /* i/o */, L_plocsi /* i/o */, xfp, f0hzLtpBinQ7, + norm_corrQ15_fx, 2, maxPlocs, buffer_fft); + n_plocs_out = *num_plocs; move16(); + + IF(sub(n_plocs_in, n_plocs_out) == 0) + { + /* adjust first peak coinciding with LTPF0 measures if it indicates so */ + plc_phEcu_F0_refine_first_fx(plocs /* i/o */, *num_plocs, L_plocsi /* i/o */, f0hzLtpBinQ7, norm_corrQ15_fx, + 3); + } + } + /* moved inside spec_ana_fx , to include validated pitch peak P_in_plocs*/ + { + Word16 peak_limits_fx[5] = { 14 /*NB*/, 14 /*WB*/, 14 /*sWB*/, 14 /*SWB*/, + 14 /* FB */ }; /* to be trained for each BW */ + + test(); + test(); + IF((sub(norm_corrQ15_fx, 0) > 0) && /* == 0 indicates a negative correlation, which could be likely stable */ + (sub((Word16)(0.5 * 32768), norm_corrQ15_fx) > 0) && (sub(*num_plocs, peak_limits_fx[bwidth_fx]) > 0)) + { + if (P_in_plocs > 0) + { + *num_plocs = 0; move16(); /*activate noise only path only if normcorr vas valid energywise */ + } + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + } + + /*-------------------------------------------------------------------* + * subst_spec_fx() + * + * Substitution spectrum calculation + *-------------------------------------------------------------------*/ + + void subst_spec_fx( + const Word16 *plocs, /* i : The indices of the identified peaks Q0 */ + const Word32 *L_plocsi, /* i : Interpolated positions of the identified peaks Q16 */ + Word16 * num_plocs, /* i/o : Number of identified peaks Q0 */ + const Word16 time_offs, /* i : Time offset Q0 */ + Word16 * X, /* i/o : FFT spectrum */ + const Word16 *mag_chg, /* i : Magnitude modification Q15 */ + const Word16 ph_dith, /* i : Phase dither, 2*PI is not included. (Q15, i.e., between 0.0 and 1.0) */ + const Word16 *is_trans, /* i : (Transient) noise generation flags (either 0 or not 1 ) */ + const Word16 output_frame, /* i : Frame length Q0 */ + Word16 * seed, /* i/o : Random seed */ + const Word16 *alpha, /* i : Magnitude modification factors for fade to average Q15 */ + const Word16 *beta, /* i : Magnitude modification factors for fade to average Q15 */ + const Word16 *Xavg, /* i : Frequency group averages to fade to Q0 */ + const Word16 t_adv /* i : time adjustement excluding time_offs Q0 */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,const Word16 fadeout, /* need for DC muting */ + Word16 * nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */ + const Word32 * L_Xavg /* i : Frequency group amp averages for tonal tilt analysis Max upshifted */ +#endif + ) + { + Word16 Xph_short; + Word32 L_corr_phase[MAX_PLOCS], L_Xph; + Word32 *pCorrPhase_L; + Word16 cos_F, sin_F, tmp; + Word16 peak_sin_F = 0, peak_cos_F = 0; + Word16 sin_F_fade2avg, cos_F_fade2avg; + Word16 fs_idx; + Word16 Lprot, m, i, e, im_ind, delta_corr_up, delta_corr_dn, delta_tmp; + UWord16 lsb; + Word16 j, re, im, *pReX, *pImX, lastPeak, lprotBy2Minus1, segmentLen; + Word16 pkLocation_1, pkLocation, pkLocation1; + const Word16 *pPlocs; + const Word32 *pPlocsi_L; + Word32 L_acc; + Word16 Lprot_inv; + Word16 k; + Word16 tmp2; + Word16 alpha_local; + Word32 tmp_L; + Word16 mag_chg_local; + const Word16 *gwlpr_fxPlus1; + Word16 one_peak_flag_mask; + Word16 noise_mag_scale_neg; + Word16 up_shift_adj; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("subst_spec_fx", sizeof(struct { + Word16 Xph_short; + Word32 L_corr_phase[MAX_PLOCS], L_Xph; + Word32 *pCorrPhase_L; + Word16 cos_F, sin_F, tmp; + Word16 peak_sin_F, peak_cos_F; + Word16 sin_F_fade2avg, cos_F_fade2avg; + Word16 fs_idx; + Word16 Lprot, m, i, e, im_ind, delta_corr_up, delta_corr_dn, delta_tmp; + UWord16 lsb; + Word16 j, re, im, *pReX, *pImX, lastPeak, lprotBy2Minus1, segmentLen; + Word16 pkLocation_1, pkLocation, pkLocation1; + const Word16 *pPlocs; + const Word32 *pPlocsi_L; + Word32 L_acc; + Word16 Lprot_inv; + Word16 k; + Word16 tmp2; + Word16 alpha_local; + Word16 expo; + Word32 tmp_L; + Word16 mag_chg_local; + const Word16 *gwlpr_fxPlus1; + Word16 one_peak_flag_mask; + Word16 noise_mag_scale_neg; + Word16 up_shift_adj; + })); +#endif + + if (time_offs == 0) + { +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::subst_spec_fx(1st)"); +#endif + } + else + { +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::subst_spec_fx(N)"); +#endif + } + + + gwlpr_fxPlus1 = &(gwlpr_fx[1]); /* ptr init */ + fs_idx = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */ + ASSERT(fs_idx == (output_frame / 100)); + Lprot = LprotSzPtr[fs_idx];move16(); + Lprot_inv = InvLprot_Q22[fs_idx]; move16(); + + tmp2 = add(mult_r(time_offs, oneOverFrameQ15Tab[fs_idx]), 1);/* save a local burst_len for securing DC and fs/2 muting */ + + /* Correction/evolution phase of the identified peaks */ + IF(s_or(is_trans[0], is_trans[1]) != 0) + { + *num_plocs = 0; move16(); + } + ELSE + { + + tmp = t_adv; + + tmp = add_sat(tmp, time_offs); + /* NB tmp can be stored in Word16 Q0 as max used value is 684+(OFF FRAMELIMIT==60)*480 = 29484 */ + tmp_L = L_mult0(tmp, Lprot_inv); + + + tmp = norm_l(tmp_L); + up_shift_adj = s_max(0, sub(4, tmp)); /* 48kHz : PLC frame 1..49 -> tmp_L<<4 , frame 50..60 -> tmpL<<3 */ + tmp_L = L_shl_sat(tmp_L, sub(4, up_shift_adj)); + tmp = round_fx_sat( tmp_L); + + + pPlocsi_L = L_plocsi; + pCorrPhase_L = L_corr_phase; + FOR(m = 0; m < *num_plocs; m++) + { + + /* tmp has variable resolution 10 or 9 bits */ + ASSERT( up_shift_adj >= 0); + Mpy_32_16_ss(L_shl_pos(*pPlocsi_L++, up_shift_adj), tmp, &L_acc, &lsb); + L_acc = L_add(L_shl_pos(L_acc, 5), lshr(lsb, 11)); + /* 5 lsb's actually unused though, as 6 bits are shifted out */ + *pCorrPhase_L++ = L_acc; move32();/* in Q16. 2*PI is not included. */ + } + } + + one_peak_flag_mask = (Word16)0xFFFF; move16(); /* all ones mask -> keep */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + test(); logic16(); + IF((*num_plocs > 0) && sub(*num_plocs, 3) < 0) + { + one_peak_flag_mask = 0x0000; move16(); /* all zeroes mask -> zeroes in valleys, single clean tone assumed */ + + /* revert initial pure tone decision in some cases */ + logic16(); logic16(); + IF((sub(*nonpure_tone_flag_ptr, 0) < 0) && + ((sub(fs_idx, 2) == 0)/* SemiSWB 24 kHz */ || (sub(fs_idx, 4) >= 0)) /* FB 48 kHz */ + ) + { + /* in the first lost frame analyze spectra and spectral bands to possibly reverse an initial pure sine assumption */ + *nonpure_tone_flag_ptr = plc_phEcu_nonpure_tone_ana_fx(plocs, *num_plocs, X, L_Xavg, Lprot, fs_idx); + +#ifdef LOCAL_PLC2_TON_ANA_DEACTIVATE + *nonpure_tone_flag_ptr = 0; /* dbg of inactive tone analysis */ +#endif + } + + + if (sub(*nonpure_tone_flag_ptr, 0) > 0) + { + /* actually revert single pure tone detection */ /* 0-> mute all surrounding valley bins in evolution , 0xff -> generate noise in all valleys */ + one_peak_flag_mask = (Word16)0xFFFF; move16(); /* all ones mask -> keep */ + } + } +#else + logic16(); + if ((*num_plocs > 0) && sub(*num_plocs, 3) < 0) + { + one_peak_flag_mask = 0x0000; move16(); /* all zeroes mask -> zero */ + } +#endif + + + noise_mag_scale_neg = 0; move16(); /* no change of valley noise magnitude */ + logic16(); + if ((*num_plocs == 0) || (time_offs != 0)) + { /* only adj_scale noise amplitude when we have no WC path , or in all noise frame */ + noise_mag_scale_neg = -32768; move16(); /* all ones --> scale_noise */ + } + + IF(*num_plocs == 0) + { + X[0] = 0; move16(); /* reset DC if there are no peaks */ + X[shr_pos(Lprot, 1)] = 0; move16(); /* also reset fs/2 if there are no peaks */ + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + /* the binary selection of fadeout scheme */ + tmp = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16(); + if (fadeout != 0) + { + tmp = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16(); + } + + IF(sub(tmp2, add(fade_scheme_tab_fx[tmp][1],1) ) > 0) +#else + IF(sub(tmp2, (BURST_ATT_THRESH+1)) > 0) +#endif + { + /* also start DC scaling attenuation */ + X[0] = mult(alpha[0], X[0]); move16(); + /* start fs/by2 attenuation */ + X[shr_pos(Lprot, 1)] = mult(alpha[s_min(add(fs_idx, LGW8K), LGW48K)], X[shr_pos(Lprot, 1)]); move16(); + } + + + lprotBy2Minus1 = sub(shr_pos(Lprot, 1), 1); + + /* for 48k the last (63+1+63) 128/2-1 values above 20 kHz are always zeroes */ + { /* after a last, peak no need to evolve above 20kHz , those coeffs have been/ will be zeroed already */ + /* DC, Xused,ReZeroed, fs/2, ImZeroed, ImUsed */ + /*N: 1, 320 , 63 , 1 , 63 , 320 */ + /*Cind: 0, 1-320, 321-383 , 384 , 385-447, 448 -767 */ + lprotBy2Minus1 = s_min( lprotBy2Minus1, 320); + /*only process up to bin X[320] , 63 coeffs X[321] fwd should already be zeroed */ + } + + i = 1; move16(); /* index in the X[DC, ReX part of X_Sav ,i.e *pReX == X[i] */ + k = 0; move16(); + + pReX = X + i; + im_ind = (Lprot - 1); /* ptr init */ + pImX = X + im_ind; + pPlocs = plocs; + pCorrPhase_L = L_corr_phase; + + + pkLocation_1 = -4; move16(); /* dummy value to avoid Out of Array Read */ + pkLocation = -3; move16(); /* dummy value to avoid Out of Array Read for the *num_plocs==0 case */ + pkLocation1 = -2; move16(); /* dummy value to avoid Out of Array Read */ + + IF (*num_plocs != 0) + { + + pkLocation = *pPlocs; move16(); /* N.B. No post-increment */ + lastPeak = sub(*num_plocs, 1); + if (lastPeak >= 0) + { + pkLocation1 = *pPlocs++; move16(); /* get a next peak */ + } + } + + FOR(m = 0; m < *num_plocs; m++) + { + pkLocation_1 = pkLocation; /* plocs[m - 1] */ move16(); + pkLocation = pkLocation1; /* plocs[m] */move16(); + + /*location dependent update of plocs[m + 1] */ + if ( sub(lastPeak, m) > 0) + { /* only read additional peak when teher is a valid position to read */ + pkLocation1 = *pPlocs++; /* plocs[m + 1] */ move16(); + } + + delta_tmp = shr_pos(sub(sub(pkLocation, pkLocation_1), 1), 1); + if (m == 0) + { + delta_tmp = DELTA_CORR; move16(); /* first peak special case */ + } + delta_corr_dn = s_min(delta_tmp, DELTA_CORR); + + delta_tmp = shr_pos(sub(sub(pkLocation1, pkLocation), 1), 1); + if (sub(m, lastPeak) >= 0) + { + delta_tmp = DELTA_CORR; move16(); + } + delta_corr_up = s_min(delta_tmp, DELTA_CORR); /* last peak special case */ + + + /* Input Xph */ + segmentLen = sub(sub(pkLocation, delta_corr_dn), i); /* may be negative */ + + ASSERT(pReX == &(X[i])); + ASSERT(*pReX == X[i]); /*before first, nth valley*/ + + FOR(j = 0; j < segmentLen; j++) /* valley section , may be skipped for segmentlen < 0 */ + { + + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + + /* phase scrambling */ + rotate_W16_fx(*pReX, *pImX, cos_F, sin_F, &tmp, &im); /* tmp=real part, should be inlined */ + UNUSED(re); + + /* i.e. add a bit of magnitude scrambling around 1.0 in longer bursts */ + *seed = rand_phase_fx(*seed, &sin_F_fade2avg, &cos_F_fade2avg); + IF(noise_mag_scale_neg != 0) + { + valley_magnitude_adj_fx(&tmp, &im, *seed, cos_F); + /* use two random variables */ /*reuse cosF from regular X scrambling, + reuse *seed from fade2avg + */ + } + + IF( beta[k] != 0 ) + { + alpha_local = alpha[k]; /* no move as alpha_local is only needed for debug */ + /* the fade2avg mixing branch, fade2avg and transient downscaling and evolution rotation */ + tmp2 = mult_r(beta[k], Xavg[k]); + + { + tmp2 = s_and(tmp2, one_peak_flag_mask); + tmp = s_and(tmp, one_peak_flag_mask); + im = s_and(im, one_peak_flag_mask); + } + + *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F_fade2avg); move16(); + *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F_fade2avg); move16(); + } + ELSE + { /* the no fade2avg mixing branch, only transient downscaling and evolution rotation */ + { + tmp = s_and(tmp, one_peak_flag_mask); + im = s_and(im, one_peak_flag_mask); + } + + + *pReX++ = mult_r(mag_chg[k], tmp); move16(); + *pImX-- = mult_r(mag_chg[k], im); move16(); + } + i = add(i, 1); + ASSERT(pReX == &(X[i])); /* nth Valley */ + ASSERT(*pReX == X[i]); /* nth Valley */ + if (sub(i, gwlpr_fxPlus1[k]) >= 0) + { + k = add(k, 1); + } + } /* segment_len 1st++ etc valley excluding last */ + + /* peak area section */ + + e = s_min(lprotBy2Minus1, add(pkLocation, delta_corr_up)); + segmentLen = sub(e, sub(i, 1)); + + + L_Xph = *pCorrPhase_L; move32(); + /* rounding here, add "0.5" before extracting the 10 bits for table lookup */ + Xph_short = s_and(extract_l(L_shr_pos_pos(L_add(L_Xph, (1L << (16 - 10 - 1))), 16 - 10)), 0x3ff); + /* 10 bits precision after radix point, for a virtual 0-1023 sin/cos table lookup */ + + + get_sin_cosQ10opt(Xph_short, &peak_sin_F, &peak_cos_F); + + + ASSERT(pReX == &(X[i])); /*before peak*/ + FOR(j = 0; j < segmentLen; j++) + { + mag_chg_local = mag_chg[k]; /* mag_chg_local actually only need for debugging , no move16()*/ + + UNUSED(ph_dith); + *seed = extract_l(L_mac0(13849, *seed, 31821)); + rotate_W16_fx(*pReX, *pImX, peak_cos_F, peak_sin_F, &tmp, &im); /* should be inlined */ + UNUSED(re); + + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + + IF( beta[k] != 0 ) + { /* fade2avg path alpha*X_sav + beta *Xavg */ + alpha_local = mag_chg_local; /* no move alpha_local only needed for dbg */ + tmp2 = mult_r(beta[k], Xavg[k]); + + + *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F); move16(); + *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F); move16(); + } + ELSE + { + *pReX++ = mult_r(mag_chg_local, tmp); move16(); + *pImX-- = mult_r(mag_chg_local, im); move16(); + } + + i = add(i, 1); + ASSERT(pReX == &(X[i])); + ASSERT(*pReX == X[i]); + if (sub(i, gwlpr_fxPlus1[k]) > 0) + { + k = add(k, 1); + } + } /* segment_length Peak*/ + pCorrPhase_L++; + } + + segmentLen = sub(lprotBy2Minus1, sub(i, 1)); /* tail/valley noise-bins */ + + /* for 48k the last 63+1+63 = values above 20 kHz */ + { /* after last, peak no need to scramble above 20kHz , those coeffs have been/ will be zeroed already */ + /* DC, Xused,ReZeroed, fs/2, ImZeroed, ImUsed */ + /*N: 1, 320 , 63 , 1 , 63 , 320 */ + /*ind: 0, 1-320, 321-383 ,384 , 385-447, 448 -767 */ + /* segmentLen = sub(320, i-1); */ /*only process up to bin X[320] , 63 coeffs X[321] fwd should already be + zeroed */ + /* ASSERT(i-1+ segmentLen == lprotBy2Minus1 ); */ + } + + ASSERT(*pReX == X[i]); /* before a final valley*/ + FOR(j = 0; j < segmentLen; j++) + { + + + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + rotate_W16_fx(*pReX, *pImX, cos_F, sin_F, &tmp, &im); /* should be inlined , tmp=real part */ + + *seed = rand_phase_fx(*seed, &sin_F_fade2avg, &cos_F_fade2avg); + /* i.e. add a bit of magnitude scrambling around 1.0 in longer bursts */ + IF(noise_mag_scale_neg != 0) + { + valley_magnitude_adj_fx(&tmp, &im, *seed, cos_F); + /*reuse cosF from regular X scrambling, + reuse *seed from fade2avg */ + } + + tmp = s_and(tmp, one_peak_flag_mask); + im = s_and(im, one_peak_flag_mask); + IF(beta[k] != 0) + { /* fade2avg path never in first BFI frame */ + + alpha_local = alpha[k]; /* no move as alpha_local is only needed for debug */ + tmp2 = mult_r(beta[k], Xavg[k]); + { + tmp2 = s_and(tmp2, one_peak_flag_mask); + } + + + *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F_fade2avg); move16(); + *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F_fade2avg); move16(); + } + ELSE + { + + *pReX++ = mult_r(mag_chg[k], tmp); move16(); + *pImX-- = mult_r(mag_chg[k], im); move16(); + } + i = add(i, 1); + ASSERT(*pReX == X[i]); + if (sub(i, gwlpr_fxPlus1[k]) > 0) + { + k = add(k, 1); + } + } /* segment_len last valley */ + + + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + } + + void my_wtda_fx(const Word16 *new_audio, /* i : input audio to be windowed Q0 20 ms , OPT can be output as well */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + Word32 *L_wtda_audio, /* o : tda audio Q16 20 ms */ + const Word16 L, Word8 *scratchBuffer) /* Size = 8 * MAX_L_FRAME */ + { + Word16 i, L2; /*,L4;*/ + const Word16 *pX; + const Word16 *pW; + Word32 *p1_L, *p2_L, *p3_L, *p4_L; + Word32 *L_w_audio; /*OPt 1 use input buffer , OPT2, may be shortened from 20 ms to 16 ms due to + zeroed parts*/ + Word32 *pY_L, *pa1_L, *pa2_L; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("my_wtda_fx", sizeof(struct { + Word16 i, L2; /*,L4;*/ + const Word16 *pX; + const Word16 *pW; + Word32 *p1_L, *p2_L, *p3_L, *p4_L; + Word32 *L_w_audio; /*OPT 1 use input buffer, OPT2, may be shortened from 20 ms to 16.25+(1.75) ms + due to zeroed parts*/ + Word32 *pY_L, *pa1_L, *pa2_L; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::my_wtda_fx"); +#endif + + L_w_audio = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 2 * MAX_L_FRAME */ + + /* |111111|222222|333333|444444 */ + /* |p1 p2| p3||p4 */ + + /* Apply analysis window */ + + pX = new_audio; + pY_L = L_w_audio; + + pW = win2ms_init; + FOR(i = 0; i < ((2 * L / 10)); i++) /* Loop over 2ms window MDCT-ana length */ + { + *pY_L++ = L_mult(*pX++, *pW++); move32(); + } + + pW = win16ms_center; + /* 20 ms - 2ms - 3.75 ms = 14.25 ms */ + FOR(i = 0; i < (2 * L - (2 * L / 10) - ((3 * 2 * L) / 16)); + i++) /* Loop over remaining 14.25ms, currently out of a 16 ms stored length */ + { + *pY_L++ = L_mult(*pX++, *pW++); move32(); + } + + + /* tda */ + L2 = shr_pos_pos(L, 1); /* length of tda blocks */ + + p1_L = L_w_audio; /* block 1 fwd */ + p2_L = L_w_audio + L - 1; /* block 2 rev */ + p3_L = L_w_audio + L + L2 - 1; /* block 3 rev */ + p4_L = L_w_audio + L + L2; /* block 4 fwd */ + + pa1_L = L_wtda_audio; /* first part output */ + pa2_L = L_wtda_audio + L2; /* second part output */ + + FOR(i = 0; i < (L / 8); i++) + { + /* first 1.25ms part of tda signal -p3_rev -p4_fwd */ + *pa1_L++ = L_negate(L_add_sat(*p3_L--, *p4_L++)); move32(); + } + FOR(; i < L2; i++) + { + /* first front part 3.75 ms p4_l is zeroes -p3_rev + (-p4_fwd==0) */ + *pa1_L++ = L_negate(*p3_L--); move32(); + } + + FOR(i = 0; i < L2; i++) + { + /* second part of tda signal p1 -p2_rev */ + *pa2_L++ = L_sub_sat(*p1_L++, *p2_L--); move32(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return; + } + + /*-------------------------------------------------------------------------- + * rec_wtda() + * + * Windowing and TDA of reconstructed frame + *--------------------------------------------------------------------------*/ + + + static void + rec_wtda_fx( + Word16 *X, /* i : iFFT(X-evolved) TD-signal o: dbg 16 ms */ + Word32 *L_ecu_rec, /* o : Reconstructed frame in tda domain Qx? */ + const Word16 output_frame, /* i : Frame length */ + const Word16 Lprot, /* i : Prototype frame length */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + const Word16 maxLen, + const Word16 *prevsynth, + const Word16 Q_psMinus1, /*i: Q prev_synth minus 1 , (-1 to match Q of Xsav in first bfi frame ) */ + Word8 *scratchBuffer) /* Size = 12 * MAX_L_FRAME */ + { + Word16 l, Lprot2; + Word16 *rec_buf; + Word16 *xsubst_; /*,*out_ptr;*/ + + Word16 ola_old[COPY_LEN_48K + OLA_LEN_48K]; /* 3.75 ms */ + Word16 work_len; + Word16 copy_len; + Word16 ola_len; + + + Word8 *buffer_wtda; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("rec_wtda_fx", sizeof(struct { + Word16 l, Lprot2; + Word16 *rec_buf; + Word16 *xsubst_; /*,*out_ptr;*/ + Word8 *buffer_wtda; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::rec_wtda_fx"); +#endif + + rec_buf = scratchAlign(scratchBuffer, 0); /* Size = 2 * 2 * MAX_L_FRAME */ + buffer_wtda = (Word8 *)scratchAlign(rec_buf, sizeof(*rec_buf) * (2 * maxLen)); /* Size = 4 * 2 * MAX_L_FRAME */ + + xsubst_ = rec_buf; + Lprot2 = shr_pos_pos(Lprot, 1); + + /* extract reconstructed frame with ld window into rec_buf */ + l = sub(output_frame, Lprot2); + basop_memmove(xsubst_ + l, X, (Lprot) * sizeof(Word16)); /* 16 ms IFFT raw output */ + copy_len = COPY_LEN[FRAME2FS_IDX(output_frame)]; + ola_len = OLA_LEN[FRAME2FS_IDX(output_frame)]; + work_len = add(copy_len, ola_len); + /* Copy and scale copy part 2ms from prevsynth */ + basop_memmove(rec_buf, &prevsynth[Lprot - work_len], (copy_len) * sizeof(Word16)); /* 2ms out of 3.75 ms copied */ + Scale_sig_sat(rec_buf, copy_len, sub(-3, Q_psMinus1)); /* inplace scaling by 2^(-Q_ps-4) */ + + + /* Copy, window and scale 1.75 ms ola part from prevsynth , into a temporary buffer ola_old */ + + + windowing_ola(&prevsynth[Lprot - ola_len], ola_old, w_old[FRAME2FS_IDX(output_frame)], ola_len); /* 1.75 ms */ + + Scale_sig_sat(ola_old, ola_len, sub(-3, Q_psMinus1)); /* inplace scaling by 2^(-Qps-4) */ + + /* Window 1.75 ms length inplace recreated X=IFFT(prototype) signal copied into rec_buf signal */ + windowing_ola(&rec_buf[copy_len], &rec_buf[copy_len], w_new[FRAME2FS_IDX(output_frame)], ola_len); + /* mix add the two windowed components */ + ola_add(&rec_buf[copy_len], ola_old, &rec_buf[copy_len], ola_len); /* OPT: sat check */ + + my_wtda_fx(rec_buf, + win2ms_init, /* i: 2 ms initial part of pre_tda window */ + win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + L_ecu_rec, output_frame, buffer_wtda); /* */ + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + + return; + } + + /*-------------------------------------------------------------------------- + * rec_frame_fx() + * + * Frame reconstruction + *--------------------------------------------------------------------------*/ + void rec_frame_fx(Word16 * x, /* i : FFT spectrum 16 ms, o: ifft() TD debug signal 16ms */ + Word32 * L_ecu_rec, /* o : Reconstructed frame in tda domain 10ms buffer */ + const Word16 output_frame, /* i : Frame length */ + const Word16 Q, /* i : Xsav Q */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + Word16 maxLprot, + const Word16 *prevsynth, + const Word16 Q_prevsynthMinus1, /* i : prevsynthQ-1 or xfp Q */ + Word8 *scratchBuffer /* Size = 4 * MAX_LPROT + 12 * MAX_L_FRAME */ + ) + { + Counter i; + Word16 Lprot; + Word32 *L_x; + Word32 *pX_L; + Word16 *pX; + Word16 fft_scale; + Word8 * buffer_fft; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("rec_frame_fx", sizeof(struct { + Counter i; + Word16 Lprot; + Word32 *L_x; + Word32 *pX_L; + Word16 *pX; + Word16 fft_scale; + Word8 * buffer_fft; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::rec_frame_fx"); +#endif + + L_x = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LPROT */ + buffer_fft = (Word8 *)scratchAlign(L_x, sizeof(*L_x) * maxLprot); /* Size = 4* (2+1) * MAX_L_FRAME */ + + /* Initialize to FB constants */ + Lprot = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */ + ASSERT(Lprot == (output_frame / 100)); + Lprot = LprotSzPtr[Lprot]; move16(); + + + /* Convert stored 16 bit into 32bit for fft */ + flippedW16_2_intlvW32(x, sub(shr_pos_pos(Lprot, 1), 1), Lprot, L_x); + /*scratch x now free for re-use */ + + fft_scale = -1; move16(); + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::IFFT_fx"); +#endif + BASOP_irfftN(L_x, Lprot, &fft_scale, buffer_fft); +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + + pX_L = &L_x[0]; + pX = &x[0]; /* scratch x reused */ + + { + FOR(i = 0; i < Lprot; i++) + { + *pX++ = extract_h(L_shl_sat(*pX_L++, fft_scale)); move16(); + } + } + /* Scratch L_x may be released */ + + + /* Saturation possible when rescaling to Q0 if there are random bit errors in the bit stream + * One may use one guard bit to better handle this - though it should not be needed for normal + * operation. + */ + Scale_sig_sat(x, Lprot, negate(Q)); /* scale by 2^(-Q) */ + + /*scratch x is Lprot word16 */ + /* scatch need for win-TDA XXX */ + /* scrcatch need for TDA XXX */ + + rec_wtda_fx(x, L_ecu_rec, output_frame, Lprot, + win2ms_init, /* i: 2 ms initial part of pre_tda window */ + win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + s_max(output_frame, 160), + prevsynth, + Q_prevsynthMinus1, /* NB: prevsynth Q may change from prev_bfi=0 to prev_bfi==1, due to phase + of signal or PLC2-muting */ + buffer_fft); + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return; + } + + /*-------------------------------------------------------------------------- + * hq_phase_ecu_fx() + * + * Main routine for HQ phase ECU + *--------------------------------------------------------------------------*/ + void hq_phase_ecu_fx( + const Word16 *prevsynth, /* i : buffer of previously synthesized signal currently 16ms */ + Word32 * L_ecu_rec, /* o : reconstructed frame in tda domain , also tmp w32_fft buffer */ + Word16 * time_offs, /* i/o: Sample offset for consecutive frame losses*/ + Word16 * X_sav, /* i/o: Stored spectrum of prototype frame */ + Word16 * Q_spec, /* o: Q value of stored spectrum */ + Word16 * num_p, /* i/o: Number of identified peaks */ + Word16 * plocs, /* i/o: Peak locations */ + Word32 * L_plocsi, /* i/o: Interpolated peak locations Q16 */ + const Word16 env_stab, /* i : Envelope stability parameter */ + const Word16 f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */ + const Word16 norm_corrQ15_fx, /*i : correlation for lag at f0hzLtpBinQ7 */ + const Word16 prev_bfi, /* i : indicating burst frame error */ + Word16 old_is_transient[2], /* i/o : flags indicating noise generation frames */ + Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients*/ + Word16 * mag_chg_gr, /* o: per band magnitude modifier, incl burst attenuation */ + Word16 * Xavg, /* i/o: Frequency group average gain to fade to */ + Word16 * beta_mute, /* o : Factor for long-term mute */ + const Word16 bwidth_fx, /* i : Encoded bandwidth */ + const Word16 output_frame, /* i : frame length */ + Word16 * seed_out_fxPtr, /* o: utput dbg NULL may be used*/ + Word16 * X_out, /* o: utput dbg NUll may be used */ + const Word16 t_adv, /* i : time adjustment including time_offs */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + const Word16 *sp_ana_win, /* i : whr 3+10+3 window */ + Word16 q_fx_old_exp, /* i : exp of prev_synth */ + + Word16 maxLprot, /* i : maz spectrum buffer size */ + Word16 maxPlocs, /* i : max nb of peaks */ + Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, /* exp of time signale */ + Word16 oold_Ltot_exp_fx, /*true exp of energy */ + Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx, /* exp of time signale */ + Word16 old_Ltot_exp_fx, /*true exp of energy */ + Word16 *old_grp_shape_fx, + Word16 margin_prevsynth, +#ifdef CR8_A_PLC_FADEOUT_TUNING + const Word16 fadeout, + Word16 *nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */ +#endif + Word8 *scratchBuffer /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */ + ) + { + Word16 lprot; + Word16 *mag_chg, ph_dith, *X; + Word16 *xfp; + Word16 seed; + Word16 alpha[MAX_LGW], beta[MAX_LGW] ; + Word16 prevsynth_man_upshift; + Word16 Q_prevsynthMinus1; + Word8 *buffer; +# ifdef CR8_A_PLC_FADEOUT_TUNING + Word32 L_Xavg[MAX_LGW]; /* i/o : Frequency group amp averages for tonal tilt analysis Max upshifted */ +# endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("hq_phase_ecu_fx", sizeof(struct { + Counter i; + Word16 lprot; + Word16 *mag_chg, ph_dith, *X; + Word16 seed; + Word16 alpha[MAX_LGW], beta[MAX_LGW]; + Word16 prevsynth_man_upshift; + Word16 Q_prevsynthMinus1; + Word8 *buffer; + // ToDO Word32 L_Xavg[MAX_LGW]; + })); +#endif + + if (!prev_bfi) + { +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::hq_phase_ecu_fx(1st)"); +#endif + } + else + { +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::hq_phase_ecu_fx(N)"); +#endif + } + + mag_chg = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LGW */ + X = (Word16 *)scratchAlign(mag_chg, sizeof(*mag_chg) * MAX_LGW); /* Size = 2 * MAX_LPROT == 1 Word16*MAX_LPROT */ + xfp = (Word16 *)scratchAlign(X, sizeof(*X) * maxLprot); /* Size = 2 * MAX_LPROT == 1 Word16*MAX_LPROT */ + buffer = (Word8 *)scratchAlign(xfp, sizeof(*xfp) * maxLprot); /* Size = 4 * MAX_LPROT + 12 * MAX_L_FRAME */ + + /* buffer size = Word32 * MAX_LPROT (FFT, IFFT) DRAM + + 3*Word32 * MAX_L_FRAME */ + + basop_memset(alpha, 0, MAX_LGW*sizeof(Word16)); + basop_memset(beta, 0, MAX_LGW*sizeof(Word16)); + + lprot = LprotSzPtr[bwidth_fx]; move16(); + + test(); + ASSERT(prev_bfi >= 0 && prev_bfi <= 1); + IF( prev_bfi == 0 ) /* inside PhECU we can check vs 0 */ + { + *time_offs = 0; move16(); +#ifdef CR8_A_PLC_FADEOUT_TUNING + *nonpure_tone_flag_ptr = -1; move16(); /* flag nonpure tone flag for new analysis */ +#endif + /* analysis made outside, up/down scaling here from static RAM to dynamic RAM */ + /* prevsynth_in_flt = prev_synth_man*2.^(-15 + exp_old) */ + /* X_sav_flt = X_man/2.^(Q_spec) */ + + /* 1 bit headroom needed in xfp_tmp_buf for FFT processing into X_sav */ + /* margin_prevsynth = actual margin in incoming 16 ms xpf segment */ + /* q_fx_old_exp was computed on full 21+ ms updatepcm buffer) */ + + ASSERT(margin_prevsynth >= 0 && (margin_prevsynth <= 16)); + + prevsynth_man_upshift = + sub(margin_prevsynth, 1); /* 0 --> -1(==down), 1--> 0 , 2 --> 1(==up), ... */ + ASSERT(prevsynth_man_upshift >= -16 && prevsynth_man_upshift <= 15); /* avoid Overflow in shr, shl */ + *Q_spec = sub(15, sub(q_fx_old_exp, prevsynth_man_upshift)); + /* Q_spec target is to create 1 additional bit of margin in the xfp TD buffer , before converting to + * Xsav + */ + + if (margin_prevsynth == 0) + { + Word16 Qold = 15 - (q_fx_old_exp + 1); + Word16 tmp_man_upshift = margin_prevsynth - 1; /* 1 .. -15 */ + Word16 Qnew = 15 - (q_fx_old_exp - tmp_man_upshift); + assert(Qold == Qnew); + UNUSED(Qold); + UNUSED(Qnew); + } + if (margin_prevsynth == 1) + { + Word16 Qold = 15 - (q_fx_old_exp + 0); + assert(*Q_spec == Qold); + UNUSED(Qold); + } + if (margin_prevsynth == 2) + { + Word16 Qold = 15 - (q_fx_old_exp - 1); + assert(*Q_spec == Qold); + UNUSED(Qold); + } + + Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, +1)); /* dbg to use non-scaled prevsynth for OLA */ + + /* Q of prev_synth now separated from prev_bfi=0 and prev_bfi==1 */ + +#ifdef USE_TMPXFP_IN_OLA + Q_prevsynthMinus1 = *Q_spec; /* a possibly upscaled Q */ +#endif + + + Copy_Scale_sig( + prevsynth, xfp, lprot, + prevsynth_man_upshift); /* unscaled prevsynth is still used by rec_frame, copy to a temporary + xfp analysis buffer, and scale down to a margin of 1 bit */ + + + trans_burst_ana_fx( + ((void *)NULL), + mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, alpha, beta, beta_mute, Xavg, + (*Q_spec), L_oold_xfp_w_E_fx, oold_xfp_w_E_exp_fx, oold_Ltot_exp_fx, oold_grp_shape_fx, + L_old_xfp_w_E_fx, old_xfp_w_E_exp_fx, old_Ltot_exp_fx, old_grp_shape_fx, +#ifdef CR8_A_PLC_FADEOUT_TUNING + fadeout, + L_Xavg, /* full scale band amplitudes in first bfi frame */ +#endif + buffer); + + spec_ana_fx(&(xfp[0]), plocs, L_plocsi, num_p, X_sav, output_frame, bwidth_fx, + sp_ana_win, f0hzLtpBinQ7, norm_corrQ15_fx, maxLprot, maxPlocs, buffer); + } + ELSE + { + /* analysis made outside, possible up/down scaling here from static RAM to dynamic RAM */ + ASSERT(margin_prevsynth >= 0 && (margin_prevsynth <= 15)); + + /* prev_synth may have been scaled outside by update_pcm() function */ + /* prevsynth_in_flt = prev_synth_man*2.^(-15 + exp_old) */ + /* first bfi frame: X_sav_flt = X_man/2.^(*Q_spec) */ + /* this bfi frame prev_synth(TD) is mixed with ifft signal(TD,from Q_spec) in rec_frame_fx + variable Q_prevsynthMinus1 provided to rec_frame for this TD+TD mixing + */ + + Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, +1)); /* for now, "old" use of unscaled prevsynth for added OLA */ + +#ifdef USE_TMPXFP_IN_OLA + { /* DBG target here is to instead upshift to a zero margin */ + /* but Q value is maintained to match the save Xsav *Q_spec which is used with an offset of " -1" */ + /* prevsynth_man_upshift = -prevsynth_margin ; */ + Word16 tmp, worklen = add(hamm_len2Tab[bwidth_fx], shr(hamm_len2Tab[bwidth_fx], 2)); + tmp = mult(7680, lprot); /* needs to truncate to integer */ + ASSERT(tmp == worklen); + Copy_Scale_sig(&prevsynth[lprot - worklen], &xfp[lprot - worklen], worklen, + margin_prevsynth); /* only scale up last 3.75 ms */ + Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, margin_prevsynth)); /*-1 does not make sense */ + } +#endif + + *time_offs = add_sat(*time_offs, output_frame); + + trans_burst_ana_fx( + ((void *)NULL), + mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, alpha, beta, beta_mute, Xavg, + (0), /* *Q_spec input only used in first bfi frames for burst analysis */ + L_oold_xfp_w_E_fx, oold_xfp_w_E_exp_fx, oold_Ltot_exp_fx, oold_grp_shape_fx, L_old_xfp_w_E_fx, + old_xfp_w_E_exp_fx, old_Ltot_exp_fx, old_grp_shape_fx, +#ifdef CR8_A_PLC_FADEOUT_TUNING + fadeout, + NULL, /* full scale band amplitudes , only used in first bfi frame */ +#endif + buffer); + } + /* cpy LPROT Word16 from Static RAM Xsav to working DRAM/scratch buffer X ;*/ + basop_memmove(X, X_sav, (lprot) * sizeof(Word16)); + /* seed for own_rand2 */ + seed = *time_offs; move16(); + + if (mag_chg_gr != NULL) /* o: dbg per band magnitude modifier, incl. burst attenuation */ + { + Counter k; + Word16 lgw_local = s_min(add(bwidth_fx, LGW8K), LGW48K); /* 4,5,6,7, (7/8) */ + for (k = 0; k < lgw_local; k++) + { + mag_chg_gr[k] = mag_chg[k]; /* dbg SNR output */ + } + } + + subst_spec_fx(plocs, L_plocsi, num_p, *time_offs, X, mag_chg, ph_dith, old_is_transient, output_frame, + &seed, alpha, beta, + Xavg, t_adv +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,fadeout, + nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */ + L_Xavg /*i : only used in first bfi frame */ +#endif + ); + + if (seed_out_fxPtr != NULL) + { + *seed_out_fxPtr = seed; /* verify seed synch after subst_spec */ + } + + + if (X_out != NULL) + { + Word16 ii; + for (ii = 0; ii < lprot; ii++) + { + X_out[ii] = X[ii]; /* evolve spectrum, no moves counted as this is a dbg-vector info cpy */ + } + } + + /* reconstructed frame in tda domain */ + /* NB *Q_spec only updated in first bfi frame */ + + /*Scratch Analysis at this point */ + /* X fft input needed as evolved spectrum Lprot* Word16 */ + /* xfp not needed any longer Word16* Lprot */ + /* IFFT operation needs Word32*Lprot in and Word32*Lprot out */ + /* MDCT win operation may be inplace 2x MAX_L_FRAME */ + /* TDA output is 1x MAX_L_FRAME */ + + rec_frame_fx(X, L_ecu_rec, output_frame, *Q_spec, + win2ms_init, win16ms_center, + maxLprot, +#ifdef USE_TMPXFP_IN_OLA + xfp, /* only last 3.75 ms used, in both prevbfi=0 and prevBfi=1 i.e frames, xfp is an + upscaled prev_synth */ +#else + prevsynth, /*only last 3.75 ms used in both prevbfi=0 and prevBfi=1 i.e frames */ +#endif + Q_prevsynthMinus1, + buffer); + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + } + + + static Word16 sqrt2ndOrder( /* o: in Q15 (2nd order least square approx.) */ + const Word16 x /* i: x must be in between 0.5 and 1.0 (Q15). */ + ) + { + Word32 acc; + Word16 z; +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::sqrt2ndOrder"); +#endif + + ASSERT(x >= 16384); + + acc = 1890205600L; /* 0.880195572812922 in Q31 */ move32(); + z = mac_r(acc, x, -6506); /* -0.198537395405340 in Q15 */ + acc = 682030261L; /* 0.317595089462249 in Q31 */ move32(); + z = mac_r(acc, z, x); /* in Q15 */ + + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return z; + } + + + /* Modified version to produce Word32 input to FFT */ + static void windowing_L( + const Word16 *x, /* i: Input signal */ + Word32 * L_y, /* o: Windowed output */ + const Word16 *win, /* i: Window coefficients */ + const Word16 rectLength, /* i: Offset in between the 1st and 2nd symmetric halves of the Hamming window */ + const Word16 halfLength /* i: Half of the total length of a complete Hamming window. */ + ) + { + Counter i; + Word32 * pY_L; + const Word16 *pX, *pW; + Word16 tmp_RL; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("windowing_L", sizeof(struct { + Counter i; + Word32 * pY_L; + const Word16 *pX, *pW; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::windowing_L"); +#endif + + pX = x; + pW = win; + pY_L = L_y; + + FOR(i = 0; i < halfLength; i++) /* 1st symmetric half of the Hamming window */ + { + *pY_L++ = L_mult(*pX++, *pW++); move32(); + } + /* Periodic filter - one more rect sample before end tapering */ + + tmp_RL = add(rectLength, 1); + + if (rectLength == 0) + { + tmp_RL = 0; move16(); + } + /* If rectLength is zero, it's a pure Hamming window; otherwise Hamming-Rectangular. */ + FOR(i = 0; i < tmp_RL;i++) + { + *pY_L++ = L_deposit_h(*pX++); move32(); + } + tmp_RL = sub(halfLength, 1); + if (rectLength == 0) + { + tmp_RL = halfLength; move16(); + } + FOR(i = 0; i < tmp_RL; i++) /* 2nd symmetric half of the Hamming window. */ + { + *pY_L++ = L_mult(*pX++, *(--pW)); move32(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + } + + /* Modified version to produce Word16 input to FFT */ + static void windowing_ola(const Word16 *x, /* i: Input signal */ + Word16 * y, /* o: Windowed output */ + const Word16 *win, /* i: Window coefficients */ + const Word16 Length /* i: Half of the total length of a complete Hamming window. */ + ) + { + Counter i; + Word16 * pY; + const Word16 *pX, *pW; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("windowing_ola", sizeof(struct { + Counter i; + Word16 * pY; + const Word16 *pX, *pW; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::windowing_ola"); +#endif + + pX = x; + pW = win; + pY = y; + + FOR(i = 0; i < Length; i++) /* 1st symmetric half of the Hamming window */ + { + *pY++ = mult_r(*pX++, *pW++); move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + } + + /* Modified version to produce Word16 input to FFT */ + static void ola_add(const Word16 *x, /* i: Input signal 1 */ + const Word16 *y, /* i: Input signal 2 */ + Word16 * z, /* o: Output signal */ + const Word16 Length /* i: Half of the total length of a complete window. */ + ) + { + Counter i; + Word16 * pZ; + const Word16 *pX, *pY; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("windowing_ola", sizeof(struct { + Counter i; + Word16 * pY; + const Word16 *pX, *pW; + })); +#endif + + + + pX = x; + pY = y; + pZ = z; + + FOR(i = 0; i < Length; i++) /* 1st symmetric half of the Hamming window */ + { + *pZ++ = add_sat(*pX++, *pY++); move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + } + + /*----------------------------------------------------------------------------- + * magnSqrtApprox_fx() + * + * Approximation of sqrt(Square magnitude) of fft spectrum + * if min_abs <= 0.4142135*max_abs + * abs = 0.99*max_abs + 0.197*min_abs + * else + * abs = 0.84*max_abs + 0.561*min_abs + * end + * + * Note: even to handle the dynamics of sqrt(re^2+im^2) located on + * a scaled unit circle. One need to scale down the results + * with a factor 2, that is Q_out = Q_in - 1 + * sqrt(32768.^2+32768.^2) results in = 23170 Q0-1, + * which corresponds to 46341 in the Q0 domain + *----------------------------------------------------------------------------*/ + Word16 sqrtMagnApprox_fx( /* o : sqrt of magnitude square spectrum Q_in-1*/ + const Word16 re, /* i : Real part Q_in */ + const Word16 im /* i : Imag part Q_in */ + ) + { + /* Constants for Approximation of sqrt(Square magnitude) of fft spectrum + * >> num2str(round(0.4142135]*2.^15)) + * ans = 13573 + * >> num2str(round([0.99 0.197 0.84 0.561]*2.^14)) + * ans = 16220 3228 13763 9191 + */ + +#define C_0p4142135_Q15 13573 + +#define C_0p99_Q14 16220 +#define C_0p197_Q14 3228 +#define C_0p84_Q14 13763 +#define C_0p561_Q14 9191 + Word16 sgn_bit, re_abs, im_abs, max_abs, min_abs, sum; + Word16 jcoeffs[2][2] = { {C_0p99_Q14, C_0p197_Q14}, {C_0p84_Q14, C_0p561_Q14} }; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("sqrtMagnApprox_fx", sizeof(struct { + Word16 sgn_bit, re_abs, im_abs, max_abs, min_abs, sum; + Word16 jcoeffs[2][2]; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::sqrtMagnApprox_fx"); +#endif + + /* Get values and move pointers */ + re_abs = abs_s(re); /* 1 cycle */ + im_abs = abs_s(im); /* 1 cycle */ + + /* Find max and min value */ + min_abs = s_min(re_abs, im_abs); /* 1 cycle */ + max_abs = s_max(re_abs, im_abs); /* 1 cycle */ + + /* Calc approximation depending on relation */ + sgn_bit = lshr(sub(mult(max_abs, C_0p4142135_Q15), min_abs), 15); /* 3 cycles */ + sum = mac_r(L_mult(max_abs, jcoeffs[sgn_bit][0]), min_abs, jcoeffs[sgn_bit][1]); /* 2 cycles */ +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return sum; + } + + /*----------------------------------------------------------------------------- + * fft_spec2_sqrt_approx_fx() + * + * Approximation of sqrt(Square magnitude) of fft spectrum + * if min_abs <= 0.4142135*max_abs + * abs = 0.99 max_abs + 0.197*min_abs + * else + * abs = 0.84 max_abs + 0.561*min_abs + * end + * + * Note: even to handle the dynamics of sqrt(re^2+im^2) located on + * a scaled unit circle. One need to scale down the results + * with a factor 2, that is Q_out = Q_in - 1 + * sqrt( -32768.^2 + -32768.^2 ) results in = 23170 Qin-1, + * which corresponds to 46341 in the Qin domain + *----------------------------------------------------------------------------*/ + + void fft_spec2_sqrt_approx_fx(const Word16 x[], /* i : Input vector: complex spectrum , Qin */ + Word16 xMagSqrt[], /* o : sqrt of magnitude square spectrum Qout=Qin-1*/ + const Word16 N /* i : Input vector x length */ + ) + { + Counter i; + Word16 l; + const Word16 *pRe, *pIm; + Word16 * pMagSqrt; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("fft_spec2_sqrt_approx_fx", sizeof(struct { + Counter i; + Word16 l; + const Word16 *pRe, *pIm; + Word16 * pMagSqrt; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::fft_spec2_sqrt_approx_fx"); +#endif + + /* Magnitude at 0. only real component */ + pMagSqrt = &xMagSqrt[0]; + pRe = &x[0]; + *pMagSqrt++ = mult(abs_s(*pRe++), C_0p99_Q14); move16(); + + /* From 1 to (N/2 - 1). */ + pIm = &x[N - 1]; + + l = sub(shr_pos_pos(N, 1), 1); /* N/2 - 1. */ + l = s_min(l, (LPROT48K_RED / 2 - 1) + DELTA_CORR_F0_INT); + /* at 48 k the top 8 khz are always zero, and further peaks are not + located above LPROT48K_RED 32 kHz */ + FOR(i = 0; i < l; i++) + { + *pMagSqrt++ = sqrtMagnApprox_fx(*pRe++, *pIm--); move16(); + } + + /* The sqrt magnitude square at N/2 - only real component */ + *pMagSqrt = mult(abs_s(*pRe), C_0p99_Q14); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return; + } + + Word16 + imax2_jacobsen_mag_fx(/* o: The location, relative to the middle of the 3 given data point, of the maximum. + (Q15) */ + const Word16 *y_re, /* i: The 3 given data points. real part order -1 0 1 */ + const Word16 *y_im, /* i: The 3 given data points. imag part order 1 0 -1 (from FFT)*/ + const Word16 + special /* i: -1 = left edge special case, 0 = normal, +1 = right edge special case */ + ) + { + Word16 posi; + Word16 man, expo; + const Word16 *pY; + Word16 y_m1_re, y_0_re, y_p1_re; + Word16 y_m1_im, y_0_im, y_p1_im; + + Word16 D_re, D_im, N_re, N_im; + + Word32 L_sign, L_denom, L_numer; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("imax2_jacobsen_mag_fx", sizeof(struct { + Word16 posi; + Word16 man, expo; + const Word16 *pY; + Word16 y_m1_re, y_0_re, y_p1_re; + Word16 y_m1_im, y_0_im, y_p1_im; + Word16 D_re, D_im, N_re, N_im; + Word32 L_sign, L_denom, L_numer; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::imax2_jacobsen_mag_fx"); +#endif + + /* Jacobsen estimates peak offset relative y_0 using + * X_m1 - X_p1 + * d = REAL ( ------------------- ) * c_jacob + * 2*X_0 - X_m1 -Xp1 + * + * Where c_jacob is a window dependent constant + */ +#define C_JACOB_Q14 18725 /* c_jacob = 1.1429; % assume 0.1875 hammrect window 'periodic' */ + + ASSERT(special == 0); /* always use other imax for edges cases */ + UNUSED(special); + + /* Get the bin parameters into variables */ + pY = y_re; + y_m1_re = *pY++; + y_0_re = *pY++; + y_p1_re = *pY++; + + /* Same for imaginary parts - note reverse order from FFT */ + pY = y_im; + y_p1_im = *pY++; + y_0_im = *pY++; + y_m1_im = *pY++; + + test(); + IF( norm_s(y_0_re) == 0 || norm_s(y_0_im) == 0 ) + { +#define JACOB_MARGIN 2 + /* for very high peaks the Complex denominator values may need to be downshifted 2 steps */ + y_0_re = shr_pos(y_0_re, JACOB_MARGIN); + y_0_im = shr_pos(y_0_im, JACOB_MARGIN); + + y_m1_re = shr_pos(y_m1_re, JACOB_MARGIN); + y_m1_im = shr_pos(y_m1_im, JACOB_MARGIN); + + y_p1_re = shr_pos(y_p1_re, JACOB_MARGIN); + y_p1_im = shr_pos(y_p1_im, JACOB_MARGIN); + } + + /* prepare numerator real and imaginary parts*/ + N_re = sub(y_m1_re, y_p1_re); + N_im = sub(y_m1_im, y_p1_im); + + /* prepare denominator real and imaginary parts */ + + D_re = sub(sub(shl_pos(y_0_re, 1), y_m1_re), y_p1_re); + D_im = sub(sub(shl_pos(y_0_im, 1), y_m1_im), y_p1_im); + + /* REAL part of complex division */ + L_numer = L_mac0(L_mult0(N_re, D_re), N_im, D_im); + L_denom = L_mac0(L_mult0(D_re, D_re), D_im, D_im); + L_sign = L_xor(L_numer, L_denom); /* Preserve the sign since div_s() only takes positive arguments. */ + + L_numer = L_abs(L_numer); + L_denom = L_abs(L_denom); + + test(); + IF(L_numer != 0 && L_denom != 0) + { + + man = plc_phEcu_ratio_fx(L_numer, L_denom, &expo); /* The mantissa is considered in Q15 */ + + man = mult_r(man, C_JACOB_Q14); + posi = shr_sat( man, sub(expo, 2)); + /* to Q15 (and due to saturation, it is automatically bound inside [-1.0,1.0].) */ + + if (L_sign < 0) /* Restore the sign. */ + { + posi = negate(posi); + } + } + ELSE + { + posi = 0; move16(); /* flat top, division is not possible choose center freq */ + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return posi; /* Q15. The position either left or right relative to the index of the middle of the 3 given + data points. */ + } + + /* Convert 32 Bit FFT into 16 bit fft domain */ + static void intlvW32_2_flippedW16( + Word32 * L_x, /* i : interleaved coeffs DC, Fs/2, Re(1),Im(1), Re(2),Im(2), ... ] */ + const Word16 numPairs, /* i: typically (fft-size/2 -1), re/im coeffs to copy */ + const Word16 Lprot, /* i: fft size , including DC+fs/2 */ + Word16 * x /* o : flipped coeffs , [DC, Re(1),.. Re(N-1/2) , Fs/2, Im(N-1/2) ... Im(1) ] */ + ) + { + + /* reorder real and imag components, and apply fractional scale for 24/48Khz */ + Counter m; + Counter numPairsLocal; + Word32 *pX_L = &L_x[2]; /*ptr init*/ + Word16 *pX_Re = &x[1]; /*ptr init*/ + Word16 *pX_Im = &x[Lprot - 1]; /*ptr init*/ + +#define FHG_FFT_UPSHIFT 2 + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::intlvW32_2_flippedW16"); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("intlvW32_2_flippedW16", sizeof(struct { + Counter m; + Counter numPairsLocal; + Word32 *pX_L; + Word16 *pX_Re; + Word16 *pX_Im; + })); +#endif + + /* make the scaling of 8/3= 4*0.666 here for 24 kHz and 48 kHz using 16x16 instead or 32x16 ops + a limited loss of SNR */ + + test(); + IF(sub(numPairs, 383) == 0 || sub(numPairs, 191) == 0) + { /* 24,48 kHz , 16 ms , scale by 8/3 = .666*4 */ + numPairsLocal = s_min(numPairs, 383 - 63); /* do not copy bins above 20 kHz */ + /* for 48 kHz is to only go up to 40 kHz pairs , */ + FOR(m = 0; m < numPairsLocal; m++) + { + /* multiply by (8/3)*(2.^FHG_FFT_UPSHIFT) */ + /* note: multiplication by 2/3 need to preceed upshift , due to FFT scaling being very close to the 48/24 3 + * split kHz bit margin */ + *pX_Re++ = extract_h(L_shl_pos(Mpy_32_16_lc3plus(*pX_L++, FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); + move16(); + *pX_Im-- = extract_h(L_shl_pos(Mpy_32_16_lc3plus(*pX_L++, FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); + move16(); + } + /* Place the two real only components */ + x[0] = extract_h(L_shl_pos(Mpy_32_16_lc3plus(L_x[0], FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); /* DC */ + move16(); + m = shr_pos_pos(Lprot, 1); + x[m] = extract_h(L_shl_pos(Mpy_32_16_lc3plus(L_x[1], FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); /* fs/2 */ + move16(); + } + ELSE + { /* 8,16,32 kHz 16 ms no additional scaling by 8/3 */ + + FOR(m = 0; m < numPairs; m++) + { + *pX_Re++ = extract_h(L_shl_pos(*pX_L++, FHG_FFT_UPSHIFT)); + move16(); + *pX_Im-- = extract_h(L_shl_pos(*pX_L++, FHG_FFT_UPSHIFT)); + move16(); + } + + /* Place the two real only components */ + x[0] = extract_h(L_shl_pos(L_x[0], FHG_FFT_UPSHIFT)); /* DC */ move16(); + m = shr_pos_pos(Lprot, 1); + x[m] = extract_h(L_shl_pos(L_x[1], FHG_FFT_UPSHIFT)); /* fs/2 */ move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + } + + static void flippedW16_2_intlvW32( + Word16 * x, /* i : flipped coeffs , [DC, Re(1),.. Re(N-1/2) , Fs/2, Im(N-1/2) ... Im(1) ] */ + const Word16 numPairs, /* i: typically (fft-size/2 -1), re/im coeffs to copy */ + const Word16 Lprot, /* i: fft size , including DC+fs/2 */ + Word32 * L_x /* o : interleaved coeffs DC, Fs/2, Re(1),Im(1), Re(2),Im(2), ... ] */ + ) + { + Counter i; + Counter numPairsLocal; + Word32 *pX_L; + Word16 *pX_re, *pX_im; +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::flippedW16_2_intlvW32"); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("flippedW16_2_intlvW32", sizeof(struct { + Counter i; + Counter numPairsLocal; + Word32 *pX_L; + Word16 *pX_re, *pX_im; + })); +#endif + + /* Convert stored 16 bit into 32bit for fft */ + /* Note during save FFT output was left shifted FHG_FFT_UPSHIFT */ + /* this needs to be restored before one calls ifft to avoid overflow */ + + pX_L = &L_x[2]; /*ptr init*/ + pX_re = &x[1]; /*ptr init*/ + pX_im = &x[Lprot - 1]; /*ptr init*/ + + numPairsLocal = s_min(320, numPairs); /* 48kHz optimization */ + FOR(i = 0; i < numPairsLocal; i++) + { + *pX_L++ = L_shr_pos(L_deposit_h(*pX_re++), FHG_FFT_UPSHIFT); move32(); + *pX_L++ = L_shr_pos(L_deposit_h(*pX_im--), FHG_FFT_UPSHIFT); move32(); + } + /* at 48KHz zero tail 2x63= 126 bins for Word32 IFFT input */ + basop_memset(pX_L, 0, sizeof(Word32) * shl_pos(sub(numPairs, numPairsLocal), 1)); + + /* Place the two real only components */ + L_x[0] = L_shr_pos(L_deposit_h(x[0]), FHG_FFT_UPSHIFT); move32(); + L_x[1] = L_shr_pos(L_deposit_h(x[Lprot / 2]), FHG_FFT_UPSHIFT); move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + } + + void get_sin_cosQ10opt(Word16 phase, /* Q10 0..1023 i.e. 1024=2*pi */ + Word16 * ptrSin, /* Q15 */ + Word16 * ptrCos /* Q15 */ + ) + { + Word16 sign_val, idx, idx2, idx3; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("get_sin_cosQ10", sizeof(struct { Word16 sign_val, idx, idx2, idx3; })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::get_sin_cosQ10opt"); +#endif + + /* sin table has a range up to pi/2 (256+1)=257 coeffs*/ + + sign_val = shr_pos_pos(phase, 9); /* highest bit is the sinus sign */ + idx = s_and(phase, 0x1ff); /* mask away sign */ + + idx2 = sub(idx, 256); + if (idx2 < 0) + { /*rising sine part */ + *ptrSin = sin_quarterQ15_fx[idx]; move16(); + } + + idx3 = sub(512, idx); + if (idx2 >= 0) + { /* decaying part, reverse idx */ + *ptrSin = sin_quarterQ15_fx[idx3]; move16(); + } + + if (sign_val != 0) + { + *ptrSin = negate(*ptrSin); /*no move when inlined , no sat as max in table is 32767 */ + } + + /*cos*/ + idx = add(phase, 256); /* +pi/2, i.e. move to cos phase */ + idx = s_and(idx, 0x3ff); /* wrap on 10 bits limit */ + + sign_val = shr_pos_pos(idx, 9); /* highest bit is the sign */ + idx = s_and(idx, 0x1ff); /* mask away sign */ + + idx2 = sub(idx, 256); + if (idx2 < 0) + { /*rising sine part */ + *ptrCos = sin_quarterQ15_fx[idx]; move16(); + } + + idx3 = sub(512, idx); + if (idx2 >= 0) + { /* decaying part, reverse idx*/ + *ptrCos = sin_quarterQ15_fx[idx3]; move16(); + } + + if (sign_val != 0) + { + *ptrCos = negate(*ptrCos); /* no move when inlined , no sat as max in table is 32767 */ + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + static Word16 plc_phEcu_nonpure_tone_ana_fx(const Word16* plocs, + const Word16 n_plocs, + const Word16* X, /*i: { DC, Re1,Re2 ,.....ReN , Fs/2, ImN... , Im2, Im1} */ + const Word32 *L_Xavg, /* i : Frequency group amp averages for tonal tilt analysis Max upshifted */ + const Word16 Lprot, + const Word16 fs_idx) + { +#ifdef DYNMEM_COUNT + Dyn_Mem_In("PhECU::nonpure_tone_ana", sizeof(struct { + Word16 nonpure_tone_detect; + Word16 n_ind, tone_ind, low_ind, high_ind; + Word16 peak_amp, peak_amp2, valley_amp, x_abs[(1 + 2 * ONE_SIDED_SINE_WIDTH + 2 * 1)]; + Word16 sineband_ind_low, sineband_ind_high; + Word16 i, N_grp; + Word16 tmp, tmp_dB; + Word32 L_tot_inc_HF, L_tot_inc_LF; + Word16* pRe; + Word16* pIm; + Word16* gwlpr_fxPlus1; + Word32 L_nf; + Word32 L_XavgL2_fx[MAX_LGW + 1]; + Word32 L_XavgUp_fx[MAX_LGW + 1]; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhEcu::nonpure_tone_ana_fx"); +#endif + + Word16 nonpure_tone_detect; /* output variable */ + Word16 n_ind, tone_ind, low_ind, high_ind; + Word16 peak_amp, peak_amp2, valley_amp, x_abs[(1 + 2 * ONE_SIDED_SINE_WIDTH + 2 * 1)]; + + Word16 sineband_ind_low, sineband_ind_high; + Word16 i, N_grp; + Word16 tmp; + + Word32 L_Ltot_inc_HF, L_Ltot_inc_LF; + Word32 L_tmp_dB; + + const Word16* pRe; + const Word16* pIm; + const Word16* gwlpr_fxPlus1; + Word32 L_nf; + Word32 L_XavgL2_fx[MAX_LGW + 1], L_tmp ; + Word32 L_XavgUp_fx[MAX_LGW + 1]; /* upscaled values , excluding peak band(s) */ + + /* use of a compressed hearing sensitivity curve allowing more energy deviation in highest and lowest bands */ + /* ROM table Word16 scATHFx[MAX_LGW - 1] */ + + /* init */ + nonpure_tone_detect = 0; move16(); /* Word16 register with decisions */ + + peak_amp = 0; move16(); + peak_amp2 = 0; move16(); + + /* limit single sine optimization to when 2 peaks are close enough to represent a single sinusoid */ + test(); + if ((sub(n_plocs, 2) == 0) && + (sub(sub(plocs[1], plocs[0]), ONE_SIDED_SINE_WIDTH) >= 0) + ) /* NB, plocs is an ordered vector */ + { + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x01); + } + + /* local bin wise dynamics analysis, for 1 or 2 initial local maxima peaks , + if 2 peaks , we do the analysis based on the location of the largest abs peak */ + { + tone_ind = 0; move16(); /* one peak only , use position plocs[tone_ind], tone_ind==0 */ + + peak_amp = shr(abs_s(X[0]), 1); /* plocs[0]=0, simply multiply DC*0.5 to match scaling in function sqrtMagnApprox_fx */ + test(); + IF(plocs[0] != 0) + { + peak_amp = sqrtMagnApprox_fx(X[plocs[0]], X[sub(Lprot, plocs[0])]); + } + + IF(sub(n_plocs, 2) == 0) /* locate abs max peak */ + { + peak_amp2 = sqrtMagnApprox_fx(X[plocs[1]], X[sub(Lprot, plocs[1])]); /* Re-part and Im-part in different ends of array X */ + + tmp = sub(peak_amp, peak_amp2); + tone_ind = lshr(tmp, 15); /* mask out sign bit 0(for peak_amp0), 1( for peak_amp2), lshr --> no sign extension in shift */ + peak_amp = s_max(peak_amp, peak_amp2); + } + + low_ind = s_max(1, sub(plocs[tone_ind], (ONE_SIDED_SINE_WIDTH + 1))); /* DC is not allowed in the range */ + high_ind = s_min(sub(shr(Lprot, 1), 2), add(plocs[tone_ind], (ONE_SIDED_SINE_WIDTH + 1))); /* Fs/2 is not allowed in the range */ + + n_ind = add(sub(high_ind, low_ind), 1); + /* find lowest amplitude around the assumed main lobe center location */ + + pRe = &(X[low_ind]); /* ptr init */ + pIm = &(X[Lprot - low_ind]); /* ptr init*/ + FOR(i = 0; i < n_ind; i++) + { + x_abs[i] = sqrtMagnApprox_fx(*pRe++, *pIm--); move16(); /* x_abs is downscaled by 0.5 in abs(complex) approximation */ + } + + valley_amp = peak_amp; move16(); + FOR(i = 0; i < n_ind; i++) + { + valley_amp = s_min(x_abs[i], valley_amp); + } + + /* at least a localized amplitude ratio of 16 (24 dB) required to declare a pure noise-free sinusoid */ + if (sub(shr(peak_amp, 4), valley_amp) < 0) /* 1/16 */ + { + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x02); /* not a pure tone due to too low local SNR P2V */ + } + } + + + /* analyze LF/ HF bands energy dynamics vs the assumed single tone band ( for one or two peaks found cases ) */ + { + /* Xavg , is a vector of rather rough MDCT based band amplitude estimates in perceptually motivated bands. from approx the last 26 ms of synthesis */ + + /* eval amplitude relations for assumed tonal band vs lower and higher bands */ + /*N_grp = xavg_N_grp[fs_idx];*/ /* { 4 NB , 5 WB , 6 SSWB , 7 SWB, 8 FB }; */ + N_grp = add(fs_idx, 4); + assert(fs_idx < 5); + + + /* establish band(s) with assumed sinusoid tone */ + /* if tone freq location is below first MDCT-band definition, use first band as band location anyway */ + + /* band 0 , 1 , 2 , 3 , ...*/ + /* dct-inds "c" "0"...11, 12...19, 20...35, 36 ... */ + /* gwplr_fx= [ 1 , 12(750Hz), 20(1250Hz) , 36 , ... */ /* lowest lim+1 in gwplr */ + + /* for-loop BASOP version */ + tmp = 0; move16(); + gwlpr_fxPlus1 = &(gwlpr_fx[1]); /* ptr init */ + FOR(i = 0; i < N_grp; i++) + { + if (sub(plocs[tone_ind], gwlpr_fxPlus1[i]) >= 0) + { + tmp = add(i, 1); + } + } + + sineband_ind_low = tmp; move16(); + sineband_ind_high = tmp; move16(); /* typically in the same band as low */ + + /* a single tone may end up on a band border + , handle case when assumed tone is more or less right in-between two perceptual bands +/- 4*62.5 Hz */ + + test(); logic16(); + if ((sineband_ind_high > 0) && + (sub(sub(plocs[tone_ind], ONE_SIDED_SINE_WIDTH), gwlpr_fx[add(sineband_ind_high, 1)]) >= 0) + ) + { + sineband_ind_low = sub(sineband_ind_high, 1); + } + + logic16(); + if ((sub(sineband_ind_low, sub(N_grp, 1)) < 0) && + (sub(add(plocs[tone_ind], ONE_SIDED_SINE_WIDTH), gwlpr_fx[add(sineband_ind_low, 1)]) >= 0) + ) + { + sineband_ind_high = add(sineband_ind_low, 1); + } + } + + /* intraframe(26 ms), weighted LB and HB envelope dynamics/variation analysis */ + /* envelope analysis , + require at least two HF or two LF bands in the envelope taper/roll-off analysis , otherwise skip this condition */ + + logic16(); + test(); logic16(); + IF( (nonpure_tone_detect == 0) && + ( (sub( add(sineband_ind_high, 2), N_grp) < 0 ) || + (sub(sineband_ind_low, 2+1 ) >= 0) + ) + ) + { + + /* delta taper-off analysis solution, less sensitive to input bandwidth limitation and levels */ + + /* test Xavg Word16 result above vs a high resolution Word32 L_Xavg */ + /* strong spectral tilt causes HF to be truncated in Word16 */ + + basop_memcpy(L_XavgUp_fx, L_Xavg, N_grp * sizeof(Word32) ) ; + + /* first remove all energy from the assumed tonal peak band(s) */ + L_XavgUp_fx[sineband_ind_low] = L_min(L_XavgUp_fx[sineband_ind_low], 1); move32(); + L_XavgUp_fx[sineband_ind_high] = L_min(L_XavgUp_fx[sineband_ind_high], 1); move32(); + + tmp = getScaleFactor32_0(L_XavgUp_fx, N_grp); /* o: measured headroom in range [0..32], 32 if all L_x[i] == 0 */ + if (sub(tmp, 32) == 0) + { + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x100); /* also set a flag for an all zero L_Xavg coarse spectrum estimate signal */ + } + + + /* add noise floor to L_Xavg before log2 function call */ + L_nf = L_shl(1L, sub(tmp, 1)); + L_nf = L_max(L_nf, 1L); + for (i = 0; i < N_grp; i++) + { + L_XavgUp_fx[i] = L_shl_sat(L_XavgUp_fx[i], tmp); move32(); /* maximize precision before actual log2_fx(Word32) calc call */ + + L_tmp = L_XavgUp_fx[i]; move32(); + test(); + if (L_tmp <= 0) + { + L_tmp = L_nf; move32(); + } + + /* log2(Upshifted Word32) */ + /* maximize precision in BASOP Log2 function */ + L_XavgL2_fx[i] = BASOP_Util_Log2_lc3plus(L_tmp); /* L_input 1.0 or lower --> output always negative */ + /* add 31.0 to store as fractional bits of an upscaled positive Word32 integer input ) */ + L_XavgL2_fx[i] = L_add(31L << 25, L_XavgL2_fx[i]); /* only diffs added so 31.0 is cancelled out later , in total only values between +/- 2^6 = [-64 ... -64[ are possible */ + } /* band i for L_Xavg calc*/ + /* verify that an assumed clean sine does not have any odd HF content indications by thresholding the accumulated delta rise in LF/HF side lobes */ + L_Ltot_inc_HF = 0; move32(); + for (i = (sineband_ind_high + 1); i < (N_grp - 1); i++) + { + L_tmp_dB = 0; move32(); + if (L_sub(L_Xavg[i], L_Xavg[i + 1]) < 0) /* only increases are accumulated */ + { + L_tmp_dB = L_sub(L_XavgL2_fx[i + 1], L_XavgL2_fx[i]); /* obtain ratio in log2 domain */ + } + L_tmp = Mpy_32_16_lc3plus(L_tmp_dB, scATHFx[i]); /* scATHFx[i] is the ATH weight for band i and band i+1 */ + L_tmp = L_shr_pos(L_tmp, 1); /* Q25 -> Q24 */ + + L_Ltot_inc_HF = L_add(L_Ltot_inc_HF, L_tmp); /* Q24 */ + } + + /* verify that an assumed clean sine does not have any odd LF content by thresholding the accumulated LF reverse up tilt */ + + L_Ltot_inc_LF = 0; move32(); + tmp = s_max(0, sub(sineband_ind_low, 1)); /* could also be pointer init */ + for (i = tmp; i > 0; i--) + { + L_tmp_dB = 0; move32(); + if (L_sub(L_Xavg[i - 1], L_Xavg[i]) > 0) /* only increases are accumulated */ + { + L_tmp_dB = L_sub(L_XavgL2_fx[i - 1], L_XavgL2_fx[i]); /* obtain ratio in log2 domain */ + } + L_tmp = Mpy_32_16_lc3plus(L_tmp_dB, scATHFx[i-1]); /* scATHFx[i-1] is the ATH weight in between band i-1 and band i */ + L_tmp = L_shr_pos(L_tmp, 1); /* Q25 -> Q24 */ + L_Ltot_inc_LF = L_add(L_Ltot_inc_LF, L_tmp); /* Q24 */ + } + + if (L_sub(L_Ltot_inc_HF, SIDE_LIM) > 0) /* side_lim=round(Q24x*0.7474) */ + { + /* 4.5 dB in log2 is 0.7474 */ + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x10); /* still not a pure tone, too great HF side increase */ + } + + if (L_sub(L_Ltot_inc_LF, SIDE_LIM) > 0) /* side_lim=round(Q24x*0.7474) */ + { + /* 4.5 dB in log2 is 0.7474 */ + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x20); /* still not a pure tone, too great HF side increase */ + } + + /* verify that an assumed clean sine does not have any odd LF+HF content by thresholding the accumulated LF+HF unexpected tilt */ + if (L_sub(L_add_sat(L_Ltot_inc_LF, L_Ltot_inc_HF), LFHF_LIM) > 0) /* side_lim=round(Q24x*0.7474) */ + { + /* 6.0 dB in log2 is 0.996578428 */ + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x40); /* still not a pure tone, too great LF+HF side increase */ + } + + } /* bands available*/ + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + + return nonpure_tone_detect; + } +#endif /* CR8_A_PLC_FADEOUT_TUNING plc_phecu_non_pure_ana_fx */ + + + + diff --git a/lib_lc3plus/plc_phecu_hq_ecu.c b/lib_lc3plus/plc_phecu_hq_ecu.c deleted file mode 100644 index 577a56e83..000000000 --- a/lib_lc3plus/plc_phecu_hq_ecu.c +++ /dev/null @@ -1,143 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - - -void plc_phEcu_hq_ecu( - LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, LC3_FLOAT *xfp, - LC3_INT16 prev_bfi, LC3_INT32 *short_flag_prev, LC3_INT32 fs, - LC3_INT32 *time_offs, Complex *X_sav_m, LC3_INT32 *n_plocs, LC3_INT32 *plocs, LC3_FLOAT *f0est, - const LC3_FLOAT *mdctWin, LC3_FLOAT *env_stabPtr, LC3_INT32 delta_corr, LC3_FLOAT *pfind_sensPtr, - LC3_INT32 PhECU_LA, LC3_INT32 t_adv, const LC3_FLOAT *winWhr, - LC3_FLOAT *oold_grp_shape, LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_grp_shape, LC3_FLOAT *old_EwPtr, - LC3_FLOAT *st_beta_mute, LC3_FLOAT *st_mag_chg_1st, LC3_FLOAT *st_Xavg, LC3_INT32 LA_ZEROS, LC3_FLOAT *x_tda, - LC3_FLOAT *xsubst_dbg, Complex *X_out_m_dbg, - LC3_INT32 *seed_dbg, LC3_FLOAT *mag_chg_dbg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg, - LC3_FLOAT *corr_phase_dbg, - Fft *PhEcu_Fft, Fft *PhEcu_Ifft -#ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type, LC3_INT16 *nonpure_tone_flag_ptr /* nonpure tone flag */ -#endif - - ) -{ - LC3_INT32 i; - LC3_INT32 fs_idx, L, Lprot, n_grp, Lecu, LXsav, Lxfp_inuse; - LC3_FLOAT alpha[8]; - LC3_FLOAT beta[8]; - LC3_FLOAT mag_chg[8]; - LC3_FLOAT xfp_local_rnd[2*MAX_LEN]; - Complex X_out_m[2*MAX_LEN]; - LC3_INT32 seed; - LC3_INT32 burst_len; - - - fs_idx = (LC3_INT32)floor(fs / 10000.0); - L = (LC3_INT32)floor(0.01 * fs); - Lprot = (LC3_INT32)(1.6 * L); - n_grp = xavg_N_grp[fs_idx]; - Lecu = 2 * L; - LXsav = Lprot / 2 + 1; /* 48 kHz may be optimized , to save only up to 20 kHz as in BASOP */ - Lxfp_inuse = Lprot ; - if (prev_bfi == 1){ - Lxfp_inuse = (LC3_INT32)(L*(3.75/10.0)); - } - - - - UNUSED(env_stabPtr); - UNUSED(xsubst_dbg); - UNUSED(X_out_m_dbg); - UNUSED(seed_dbg); - UNUSED(mag_chg_dbg); - UNUSED(tr_dec_dbg); - UNUSED(gpc_dbg); - UNUSED(X_i_new_re_dbg); - UNUSED(X_i_new_im_dbg); - UNUSED(corr_phase_dbg); - - - if (prev_bfi != 1) - { - for (i = (Lprot-Lxfp_inuse); i < Lprot; i++) { - xfp_local_rnd[i] = xfp[i]; - /* hysteresis of low level input aligns float fft analysis and peak picking to BASOP performance for low level noisy signals */ - if (xfp[i] >= -0.5 && xfp[i] <= 0.5) { - xfp_local_rnd[i] = 0.0; - } - } -#ifdef CR8_A_PLC_FADEOUT_TUNING - *nonpure_tone_flag_ptr = -1; /* set nonpure tone flag for new analysis */ -#endif - - - *time_offs = 0; - burst_len = (*time_offs / L + 1); - plc_phEcu_trans_burst_ana_sub(fs_idx, burst_len, n_grp, oold_grp_shape, oold_EwPtr , old_grp_shape, old_EwPtr, st_beta_mute, - st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL - -#ifdef CR8_A_PLC_FADEOUT_TUNING - ,plc_fadeout_type -#endif - ); - - plc_phEcu_spec_ana(xfp_local_rnd, Lprot, winWhr, pfind_sensPtr, plocs, n_plocs, f0est, X_sav_m, &LXsav, f0binPtr, f0ltpGainPtr, fs_idx, PhEcu_Fft); - } - else - { - *time_offs = *time_offs + L; - *time_offs = imin(32767 ,*time_offs); /* limit to Word16 range as in BASOP ~= 70 10ms frames@48kHz */ - burst_len = ((*time_offs / L) + 1); - - plc_phEcu_trans_burst_ana_sub(fs_idx, burst_len, n_grp, oold_grp_shape, oold_EwPtr, old_grp_shape, old_EwPtr, st_beta_mute, - st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL -#ifdef CR8_A_PLC_FADEOUT_TUNING - ,plc_fadeout_type -#endif - ); - - } - - seed = *time_offs; - - if (*short_flag_prev != 0) - { - *n_plocs = 0; - } - - move_cmplx( X_out_m, X_sav_m, LXsav); - - /* inplace X_out_m update */ - plc_phEcu_subst_spec(plocs, *n_plocs, f0est, *time_offs, X_out_m, LXsav, mag_chg, &seed, alpha, beta, st_Xavg, t_adv, Lprot, delta_corr, -#ifdef CR8_A_PLC_FADEOUT_TUNING - plc_fadeout_type, - nonpure_tone_flag_ptr, /* nonpure_tone_flag , a state updated here */ -#endif - - - NULL, NULL, NULL); - - - - - plc_phEcu_rec_frame(X_out_m, L, Lecu, winWhr, mdctWin, Lprot, - xfp, /* last 3.75ms of non-rounded xfp used here */ - *time_offs, - x_tda /* output */, - NULL, NULL, NULL, - LA_ZEROS, PhECU_LA, PhEcu_Ifft); - -} - diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis.c b/lib_lc3plus/plc_phecu_lf_peak_analysis.c deleted file mode 100644 index 53c10410c..000000000 --- a/lib_lc3plus/plc_phecu_lf_peak_analysis.c +++ /dev/null @@ -1,113 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - -void plc_phEcu_LF_peak_analysis(LC3_INT32 *plocs, /* i/o 0 ... Lprot/2 +1*/ - LC3_INT32 *n_plocs, /* i/o 0.. MAX_PLOCS */ - LC3_FLOAT *f0est, /* i/o Q16*/ - const LC3_FLOAT *Xabs, - LC3_FLOAT *f0binPtr, - LC3_FLOAT *f0gainPtr, - const LC3_INT32 nSubm -) -{ - LC3_INT32 i, j, fin, f_ind, prel_low, prel_high, start; - LC3_FLOAT f0est_prel[3]; - LC3_INT32 plocs_prel[3]; - LC3_INT32 n_prel; - LC3_FLOAT f0est_old[MAX_PLC_NPLOCS]; - LC3_INT32 plocs_old[MAX_PLC_NPLOCS]; - LC3_FLOAT peakLF_Xval, f; - LC3_FLOAT f0bin ; - LC3_FLOAT f0gain ; - - f0bin = *f0binPtr; - f0gain = *f0gainPtr; - - if (*n_plocs > 0 && f0gain > 0.25 && f0bin < 2.75) { - - /* Assumes sorted plocs */ - if (plocs[0] < 3) { - fin = MIN(3, *n_plocs); - peakLF_Xval = Xabs[plocs[0]]; - for (i = 1; i < fin; i++) { - peakLF_Xval = MAX(peakLF_Xval, Xabs[plocs[i]]); - } - - n_prel = 0; - for (i = 0; i < nSubm; i++) { - f = (i+1)*f0bin; - f_ind = (LC3_INT32)LC3_ROUND(f); - if (f*PHECU_FRES <= 400 && Xabs[f_ind] > peakLF_Xval*0.375) { - f0est_prel[n_prel] = f; - plocs_prel[n_prel] = f_ind; - n_prel++; - } - } - - if (n_prel > 0) { - prel_low = plocs_prel[0]; - prel_high = plocs_prel[n_prel-1]; - - /* initial assumption:: all original peaks (1 or 2 of them) are positioned below prel_low */ - start = (*n_plocs); /* at this point 'start' is the location_c where to add any harmonics peaks */ - for (i = (*n_plocs)-1; i >= 0; i--) { - if (plocs[i] >= prel_low) { - start = i; - } - } - - /* found position_c where to start adding */ - start = (start-1 ); /* one step lower, now start is of original LF peaks to keep */ - start = MAX(start, -1); /* limit for loop */ - - if (prel_high < plocs[0]) { - fin = 0; - } else { - fin = (*n_plocs)+1; - for (i = 0; i < *n_plocs; i++) { - if (plocs[i] <= prel_high) { - fin = i; - } - } - fin++; - } - - move_int(plocs_old, plocs, *n_plocs); - move_float(f0est_old, f0est, *n_plocs); - - j = (start+1); /* [0..(j-1)] of original LF peaks will be kept */ - /* j now points to first location_c where to add peaks */ - - for (i = 0; i < n_prel; i++) { - plocs[j] = plocs_prel[i]; - f0est[j] = f0est_prel[i]; - j++; - } - for (i = fin; i < *n_plocs; i++) { - plocs[j] = plocs_old[i]; - f0est[j] = f0est_old[i]; - j++; - } - - *n_plocs = j; - - } - } - } - - return; -} - diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c b/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c new file mode 100644 index 000000000..50b694e5c --- /dev/null +++ b/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c @@ -0,0 +1,202 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +void plc_phEcu_LF_peak_analysis_fx(Word16 * plocs, /* i/o 0 ... Lprot/2 +1*/ + Word16 * n_plocs, /* i/o 0.. MAX_PLOCS */ + Word32 * L_f0estQ16, /* i/o Q16*/ + const Word16 *mag, /* i: Qx */ + const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15, + const Word16 nSubm, Word16 maxPlocs, + Word8 *scratchBuffer /* Size = 6 * MAX_PLOCS + 42 */ +) + +{ + Counter i, j; + Word16 n_plocs_ana, peakLF_Xval, tmp, f_abs_ind, plocsIntersectFlag; + + Word32 L_fQ7, *L_f0est_prelQ16; + Word16 num_prel = 0, *plocs_prel; + Word16 prel_low, prel_high, start, fin; + Word16 *plocs_old; + Word32 *L_plocsi_old; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_phEcu_LF_peak_analysis_fx", sizeof(struct { + Counter i, j; + Word16 n_plocs_ana, peakLF_Xval, tmp, f_abs_ind, plocsIntersectFlag; + Word32 L_fQ7, *L_f0est_prelQ16; + Word16 num_prel, *plocs_prel; + Word16 prel_low, prel_high, start, fin; + Word16 *plocs_old; + Word32 *L_plocsi_old; + })); +#endif + + + + L_f0est_prelQ16 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 7 */ + plocs_prel = (Word16 *)scratchAlign(L_f0est_prelQ16, sizeof(*L_f0est_prelQ16) * 7); /* Size = 2 * 7 */ + plocs_old = (Word16 *)scratchAlign(plocs_prel, sizeof(*plocs_prel) * 7); /* Size = 2 * MAX_PLOCS */ + L_plocsi_old = (Word32 *)scratchAlign(plocs_old, sizeof(*plocs_old) * maxPlocs); /* Size = 4 * MAX_PLOCS */ + + test(); test(); + IF ((*n_plocs > 0) && sub(stPhECU_f0gainLtpQ15, ((Word16)(0.25 * 32768.0))) > 0 && + sub(stPhECU_f0hzLtpBinQ7, (Word16)(2.75 * 128.0)) < 0) + { + + /* % analyze/apply f0Ltp to avoid intermodulation effects below f0 of ~180 Hz + % we only do the f0Ltp-replacement(s) if there is already an established + % fft peak in the region ~fRes to 2.5*fres + fft_peak_eval_plocs = 1:3; + plocsIntersectFlag = intersect(plocs, fft_peak_eval_plocs ); % check for 1,2,3 in plocs */ + + plocsIntersectFlag = 0; move16(); + peakLF_Xval = 0; move16(); + n_plocs_ana = s_min(*n_plocs, 3); + FOR (i = 0; i < n_plocs_ana; i++) + { + tmp = plocs[i]; move16(); + if (sub(tmp, 2) <= 0) /* C index 0, 1,2 checked , [DC, 62.5 Hz, 125Hz ] */ + { + plocsIntersectFlag = add(i, 1); + } + peakLF_Xval = s_max(mag[tmp], peakLF_Xval); + } + + num_prel = 0; move16(); + IF (plocsIntersectFlag != 0) + { /* fft-peak at 0, 62 or 125 Hz */ + /* analyze if ltp-based f0 need to be added or not */ + peakLF_Xval = mult_r(peakLF_Xval, (Word16)(.375 * 32768.0)); /* now as a limit */ + + FOR (i = 1; i <= nSubm; i++) + { + L_fQ7 = L_mult0(i, stPhECU_f0hzLtpBinQ7); /* fractional index stored in L_plocsi */ + f_abs_ind = L_shr_pos(L_add(L_fQ7, 64), 7); /* integer bin index stored in plocs */ + + test(); + IF ((L_sub(L_fQ7, 819) <= 0) && /* % only apply up to ~400hz , 819 = 400/62.5*128 */ + (sub(mag[f_abs_ind], peakLF_Xval) > + 0)) /* % only set as preliminary if relative peak strength is signficant*/ + { + L_f0est_prelQ16[num_prel] = L_shl_pos(L_fQ7, 9); move32(); + plocs_prel[num_prel] = f_abs_ind; move16(); + num_prel = add(num_prel, 1); + } + } + } /*intersectFlag*/ + + /* now replace/ merge new preliminary added peaks with existing plocs and L_f0estQ16 */ + /* note that a previous fake/merged magnitude-determined peak may be replaced by two separated side peaks */ + + /* a general non-optimized list-merging solution below */ + test(); + IF ((num_prel > 0) && (sub(add(num_prel, *n_plocs), MAX_PLOCS) <= 0) /* skip in case plocs list is too large */ + ) + { + prel_low = plocs_prel[0]; move16(); + prel_high = plocs_prel[sub(num_prel, 1)]; move16(); + + /* initial assumption:: all original peaks (1 or 2 of them) are positioned below prel_low */ + start = (*n_plocs); /* at this point 'start' is the location_c where to add any harmonics peaks */ + + FOR (i = sub(*n_plocs, 1); i >= 0; i--) + { + if (sub(plocs[i], prel_low) >= 0) + { + start = i; move16(); + } + } + start = sub(start, 1); /* end of old section to copy before the added/merged section */ + start = s_max(start, -1); /* limit for loop later */ + /*% dbg check low part for a sucessful replace/merge */ + if (start >= 0 && start < *n_plocs) + { + ASSERT(plocs[start] < plocs_prel[0]); + } + + sub(0, 0); + IF (prel_high < plocs[0]) + { + fin = 0; move16(); /*% keep all plocs , just concat */ + } + ELSE + { + fin = *n_plocs; + FOR (i = 0; i < *n_plocs; i++) + { + sub(0, 0); + if (plocs[i] <= prel_high) + { + fin = i; move16(); + } + } + fin = add(fin, 1); /* first element in high part of old plocs to be copied */ + } + + /*% dbg check high part for a sucessful replace/merge */ + if (fin >= 0 && fin < *n_plocs) + { + ASSERT(plocs_prel[sub(num_prel, 1)] < plocs[fin]); + } + + /* + % actual replace/merge of added integer locations and fractional freqs. into plocs/f0list list ; + % three loops in BASOP + plocs = [ plocs(1:(start)) ; plocs_prel ; plocs((fin):end) ]; + f0est = [ f0est(1:(start)) ; f0est_prel; f0est((fin):end) ]; + */ + + FOR (i = 0; i < *n_plocs; i++) + { + plocs_old[i] = plocs[i]; move16(); + L_plocsi_old[i] = L_f0estQ16[i]; move32(); + } + + /* + j=0; + FOR(i=0; i <= start; i++) + { + plocs[i] = plocs_old[i]; move16(); + L_f0estQ16[i] = L_plocsi_old[i]; move32(); + j++; + } + */ + + j = add(start, 1); + + ASSERT(j>=0); + + FOR (i = 0; i < num_prel; i++) /* NB this section may both insert or overwrite old plocs */ + { + plocs[j] = plocs_prel[i]; move16(); + L_f0estQ16[j] = L_f0est_prelQ16[i]; move32(); + j++; + } + FOR (i = fin; i < *n_plocs; i++) /* copy the tail of the list */ + { + plocs[j] = plocs_old[i]; move16(); + L_f0estQ16[j] = L_plocsi_old[i]; move32(); + j++; + } + + *n_plocs = j; move16(); /* update total length */ + } /* num_prel >0*/ +} /* gain/hz Limits */ + +#ifdef DYNMEM_COUNT +Dyn_Mem_Out(); +#endif + +} + + diff --git a/lib_lc3plus/plc_phecu_peak_locator_fx.c b/lib_lc3plus/plc_phecu_peak_locator_fx.c new file mode 100644 index 000000000..531ee8f6f --- /dev/null +++ b/lib_lc3plus/plc_phecu_peak_locator_fx.c @@ -0,0 +1,385 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +#define RES_fx 1 /* fixed point resolution */ + +/*----------------------------------------------------------------------------- + * peak_locator_fx() + *----------------------------------------------------------------------------*/ +void plc_phEcu_peak_locator_fx(const Word16 *inp, /* i: vector with values >=0 ,Qx */ + const Word16 inp_len, /* i: length of inp */ + Word16 * int_plocs, /* o: array of filtered integer plocs Q0 */ + Word16 * n_fsc, /* o: total_ number of filtered located highs Q0 */ + const Word16 sens, /* i sensitivity, Qx */ + const Word16 inp_high, /* i global high , Qx */ + const Word16 inp_low, /* i: global low, Qx */ + Word16 maxLprot_Red, /* i: optional size for wc memory alloc of scratch buffer */ + Word8 *scratchBuffer /* i: : scratch buffer 2* 3*(1+1+(maxLprot_Red/2)+1) */ +) +{ + Counter j, k, n, idx_high, idx_low; + Word16 inp_len_minus1 ; + Word16 pairs_start, pairs_end; + Word16 *p_tmp; + Word16 prev_delta, curr_delta; + Word16 delta_predc, delta_fin; + Word16 add_dc_flag, add_fin_flag; + Word16 low_val_cand_pairs, val_range; + Word16 num_pairs, n_tail_values; + Word16 cand_phase_start, cand_idx, prev_low_plus_sens, tmp; + + Word16 cand_high, prev_low; + Word16 *sc_idx; /* 1+ 128/2+1, or 1+ 256/2+1 ... 1+ 640/2+1 or 1+ 768/2+1*/ + Word16 *cand_pairs_buf ; /* actually lowVal + [DC ] + (368/2)pairs + [FS/2] */ + Word16 *cand_pairs; /* actually [DC ] + pairs + [FS/2] */ + Word16 * fsc_idx; /* list of high locations in sc__idx 1+368/2+1 */ + + + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("peak_locator_fx", sizeof(struct { + Counter j, k, n, idx_high, idx_low; + Word16 inp_len_minus1; + Word16 pairs_start, pairs_end; + Word16 *p_tmp; + Word16 prev_delta, curr_delta; + Word16 delta_predc, delta_fin; + Word16 add_dc_flag, add_fin_flag; + Word16 low_val_cand_pairs, val_range; + Word16 num_pairs, n_tail_values; + Word16 cand_phase_start, cand_idx, prev_low_plus_sens, tmp; + Word16 cand_high, prev_low; + Word16 *sc_idx; + Word16 *cand_pairs_buf; + Word16 *cand_pairs; + Word16 *fsc_idx; + })); +#endif +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::peak_locator_fx(1st)"); +#endif + sc_idx = (Word16 *)scratchAlign(scratchBuffer, 0); /* ByteSize = 2 * (1+ inp_len+1) */ + cand_pairs_buf = (Word16 *)scratchAlign(sc_idx, sizeof(*sc_idx) * (1+inp_len+1)); /* ByteSize = 2 * (1+ 1+ inp_len+1 ) */ + fsc_idx = (Word16 *)scratchAlign(cand_pairs_buf , sizeof(*cand_pairs_buf) * (1+ 1+ inp_len+1)); /* ByteSize = 2 * ( 1+ inp_len + 1) */ + ASSERT((4 * maxLprot_Red) >= 3 * (1 + 1 + inp_len + 1)); /* basic buffer check */ + UNUSED(maxLprot_Red); + + inp_len_minus1 = sub(inp_len, 1); /* size of delta=derivative array ,and last index in inp */ + + cand_pairs = &cand_pairs_buf[1]; /* ptr init , make space for storing a lowest amplitude value in location -1 */ + pairs_start = 1; move16(); /* adjusted to zero or 1 or 2 when/if, DC is injected as sc_idx[0], or initial plateau skipped */ + + p_tmp = &(sc_idx[pairs_start]); /* ptr init */ + + + /* xor high/low pairs of delta_inp and save sign changes */ + prev_delta = sub(inp[1], inp[0]); /* precompute very first delta */ + + FOR(n = 1; n < inp_len_minus1; n++) + { /* sign change analysis */ + curr_delta = sub(inp[n + 1], inp[n]); /* n+1 ,n , are loop ptrs */ + if (s_xor(prev_delta, curr_delta) < 0) /* a "0" delta treated as a positive sign */ + { + *p_tmp++ = n; move16(); /* store sign change bin locations , location n in the inp[] signal */ + } + prev_delta = curr_delta; move16(); + } + + L_sub(0, 0); /* account for length calculaton */ + k = (Word16)(p_tmp - &(sc_idx[pairs_start])); + + + /* copy sign change location values to a pairs array */ + /* leave one initial sc_idx location open for a potential initial DC value */ + + ASSERT(pairs_start >= 0 && ((k - 1) + pairs_start) < (inp_len +2)); + FOR(j = 0; j < k; j++) + { + cand_pairs[j + pairs_start] = inp[sc_idx[j + pairs_start]]; move16(); move16(); /* the indirect should be calculated */ + } + + + /* filter away a potential single initial/trailing plateau + to enable correct analysis for adding DC or fs/2 bins */ + + logic16(); + IF((sub(k, 2) >= 0) && + (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) == 0)) + { + pairs_start = add(pairs_start, 1); + k = sub(k, 1); + } + + /* filter away potential single trailing plateu */ + pairs_end = sub(add(pairs_start,k), 1); /* point to last established sign change element */ + logic16(); + if ((sub(k, 2) >= 0) && + (sub(cand_pairs[sub(pairs_end,1)], cand_pairs[pairs_end]) == 0)) + { + k = sub(k, 1); + } + pairs_end = sub(add(pairs_start,k), 1); /* recalc ptr to last element */ + + + /* conditionally add high/lows on both sides of input (pre_dc or fin) as candidates */ + add_dc_flag = 0; move16(); + add_fin_flag = 0; move16(); + + + IF(sub(k, 1) == 0) /* one single sign change found special case */ + { + if (sub(inp[0], cand_pairs[pairs_start]) != 0) + { + add_dc_flag = 1; move16(); /* not plateau */ + } + + if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) != 0) + { + add_fin_flag = 1; move16(); /* not plateau */ + } + } + + IF(sub(k, 2) >= 0) + { + delta_predc = sub(cand_pairs[pairs_start + 1], cand_pairs[pairs_start]); + delta_fin = sub(cand_pairs[pairs_end], cand_pairs[pairs_end - 1]); + + /* plateaus are allowed to be detected by xor sign change, + but still not allowed at the start nor at the end */ + + add_dc_flag = 1; move16(); + if (sub(inp[0], cand_pairs[pairs_start]) == 0) + { + add_dc_flag = 0; move16(); /* plateau down or , plateus up., --> do not add DC */ + } + + logic16(); + if ((sub(inp[0], cand_pairs[pairs_start]) < 0) && (delta_predc > 0)) + { + add_dc_flag = -1; move16(); /*UP - up ... replace */ + } + logic16(); + if ((sub(inp[0], cand_pairs[pairs_start]) > 0) && (delta_predc < 0)) + { + add_dc_flag = -1; move16(); /* DOWN - down ... % replace */ + } + + add_fin_flag = 1; move16(); + if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) == 0) + { + add_fin_flag = 0; move16(); /* up - plateau ... */ + } + logic16(); + if ((delta_fin > 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) < 0)) + { + add_fin_flag = -1; move16(); /* up - UP ... % replace , hard to hit */ + } + logic16(); + if ((delta_fin < 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) > 0)) + { + add_fin_flag = -1; move16(); /*down - DOWN ... % replace */ + } + + } + + IF(add_dc_flag > 0) + { /* add DC */ + pairs_start = sub(pairs_start, 1); + cand_pairs[pairs_start] = inp[0]; move16(); + sc_idx[pairs_start] = 0; move16(); + ASSERT(pairs_start >= 0 && pairs_start <= 2); + k = add(k, 1); + } + IF(add_dc_flag < 0) + { /* -1 --> replace with DC*/ + cand_pairs[pairs_start] = inp[0]; move16(); + sc_idx[pairs_start] = 0; move16(); + ASSERT(pairs_start >=0 && pairs_start <= 2); + } + + IF(add_fin_flag > 0) + { /* add FS/2 */ + pairs_end = add(pairs_end, 1); + cand_pairs[pairs_end] = inp[inp_len_minus1]; move16(); + sc_idx[pairs_end] = inp_len_minus1; move16(); + k = add(k, 1); + } + IF(add_fin_flag < 0) + { /* -1, replace tail with FS/2*/ + cand_pairs[pairs_end] = inp[inp_len_minus1]; move16(); + sc_idx[pairs_end] = inp_len_minus1; move16(); + } + /* preliminary cand_pairs now only have highs , lows , no initial/trailing plateaus */ + + + /* we allow the DC/FsBy2 lows to be used as the candidatelLow */ + low_val_cand_pairs = inp_low; move16(); + val_range = sub( inp_high, low_val_cand_pairs); /* used to determine if search is useful at all */ + + logic16(); + if ((sub(val_range, RES_fx) < 0) || + (sub( inp_high, sens) < 0)) + { + k = 0; move16(); + } + + logic16(); + if ((k == 0) && (sub(val_range, sens) >= 0)) + { + k = 1; move16(); + } + + + IF(sub(k, 2) > 0) + { + /* low, high, low, ... or + high, low, high, ...*/ + + cand_phase_start = pairs_start; move16(); /*assume first candidate is a high */ + if (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) < 0) + { + cand_phase_start = add(pairs_start, 1); /* first is a low, --> skip to next higher cand */ + } + + /* high, low, high, ... */ + tmp = k; move16(); + if (sub(cand_phase_start, pairs_start) != 0) + { + tmp = sub(tmp, 1); + } + num_pairs = shr(tmp, 1); + n_tail_values = sub(tmp, shl(num_pairs, 1)); + + /* filter preliminary sign changes into sensitivity filtered sign changes */ + + *n_fsc = 0; move16(); /* counter of filtered fsc_idx */ + cand_high = low_val_cand_pairs; move16(); + cand_idx = -1; move16(); /* sentinel location for no high cand found yet. */ + cand_pairs[-1] = low_val_cand_pairs; move16(); + + prev_low = low_val_cand_pairs; move16(); + prev_low_plus_sens = add(prev_low, sens); + + /* filter loop for high - low sign change pairs */ + /* idx_high, idx_low are raw pointers into the cand_pairs and sc_idx arrays */ + + FOR( idx_high = cand_phase_start; idx_high < (cand_phase_start + 2 * num_pairs); idx_high += 2) + { + idx_low = idx_high+1; /* loop ptr increase */ + + /* new high candidate larger than previous candidate and */ + /* sensitivity still larger than the the previous low */ + tmp = s_max(cand_high, prev_low_plus_sens); + if(sub(cand_pairs[idx_high], tmp) > 0) + { + cand_idx = idx_high; move16(); /* enable or shift candidate position fwd */ + } + cand_high = cand_pairs[cand_idx]; move16(); /* NB, cand_pairs[-1] , has the low_val_cand_pairs value stored */ + + /* now check the fwd idx_low of the current {high,low} pair */ + prev_low = s_min(cand_pairs[idx_low], prev_low); + + tmp = sub(cand_high, sens); + IF(sub(tmp, cand_pairs[idx_low]) > 0) + { + /* this low point is now low enough to fix a previous high candidate */ + + fsc_idx[*n_fsc] = cand_idx; move16(); /*% add cand high idx -> output idx list*/ + *n_fsc = add(*n_fsc, 1); + + prev_low = cand_pairs[idx_low]; move16(); /* use this value as new low estimate */ + cand_idx = -1; move16(); /* no candidate until next pair or tail bin, and pt to lowVal */ + cand_high = low_val_cand_pairs; move16(); /* enable next candidate to be selected immediately */ + } + prev_low_plus_sens = add(prev_low, sens); + } /* { high, low} FOR loop */ + + logic16(); + IF((n_tail_values == 0) && (cand_idx >= 0)) + { + /* no tail low or high value to analyze + still may need to lock a non-locked but qualified candidate */ + fsc_idx[*n_fsc] = cand_idx; move16(); + *n_fsc = add(*n_fsc, 1); + } + + + /* cand_pairs vector may have a last orphan value */ + IF(n_tail_values > 0) + { + /* cand_pairs vector may have a last orphan tail value */ + /* + logic boils down to if (nTailValues > 0) && (cand_pairs(n_end) > tmp) + there is a last one trailing high to process + + a) the last high, may be a new high Peak if we have not yet + locked the current candidate + b) if we have locked the last candidate, the last high may also be + a highpeak if it is high enough from the(newly set previous) valley floor. + + tmp=a||b + */ + + tmp = s_max(cand_high, prev_low_plus_sens); + tmp = sub(cand_pairs[pairs_end], tmp); + IF(tmp > 0) + { + fsc_idx[*n_fsc] = pairs_end; move16(); + *n_fsc = add(*n_fsc, 1); + } + ELSE + { + IF(cand_idx >= 0) + { /* we have a previously established high candidate */ + fsc_idx[*n_fsc] = cand_idx; move16(); + *n_fsc = add(*n_fsc, 1); + } + + } + } + /* move high locations info from fsc_idx , to output */ + FOR(j = 0; j < *n_fsc; j++) + { + ASSERT(fsc_idx[j] >= 0 && fsc_idx[j] < (inp_len+2)); + int_plocs[j] = sc_idx[fsc_idx[j]]; move16(); move16(); /* the indirect moves are calculated */ + } + + } /* end of pairs + [tail] section filtering */ + ELSE + { + /* constant/single rise or constant decay or very low overall values, cases */ + *n_fsc = 0; move16(); + + logic16(); + tmp = sub(inp_high, sens); + IF((k != 0) && (sub(tmp, low_val_cand_pairs) > 0)) + { + /* low,high */ + /* high,low */ + tmp = plc_phEcu_find_ind_fx(inp, inp_len, inp_high); move16(); + int_plocs[0] = tmp; move16(); /* simply locate the high peak*/ + *n_fsc = 1; move16(); + if (tmp < 0) + { /*safety in case max value index was not found */ + *n_fsc = 0; move16(); + } + } + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +} + diff --git a/lib_lc3plus/plc_phecu_rec_frame.c b/lib_lc3plus/plc_phecu_rec_frame.c deleted file mode 100644 index 4586e1d62..000000000 --- a/lib_lc3plus/plc_phecu_rec_frame.c +++ /dev/null @@ -1,153 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - -void plc_phEcu_rec_frame(Complex *X_in, - LC3_INT32 L, - LC3_INT32 Lecu, - const LC3_FLOAT *whr, - const LC3_FLOAT *winMDCT, - LC3_INT32 Lprot, - LC3_FLOAT *xfp, - LC3_INT32 time_offs, - LC3_FLOAT *x_out, - Complex *full_spec_dbg, - LC3_FLOAT* ifft_out_dbg, - LC3_FLOAT* xsubst_dbg, - LC3_INT32 LA_ZEROS, - LC3_INT32 LA, - Fft* PhEcu_ifft -) -{ - - LC3_INT32 i; - - LC3_FLOAT xrec[2*MAX_LEN]; - LC3_FLOAT xsubst[2*MAX_LEN]; - LC3_FLOAT xsubst_LL[2*MAX_LEN]; - LC3_FLOAT *pXsubst_LL; - - LC3_INT32 fs_idx; - - LC3_FLOAT *pXfp, *pOlaXsubst, *pXOut; - LC3_INT32 work_part, copy_part, ola_part; - - const LC3_FLOAT *hannOla; - const LC3_FLOAT *pHannOla; - - UNUSED(time_offs); - UNUSED(full_spec_dbg); - UNUSED(ifft_out_dbg); - UNUSED(xsubst_dbg); - UNUSED(xsubst_LL); - -#ifdef CR8_A_PLC_FADEOUT_TUNING - fs_idx = FRAME2FS_IDX_10MS(L); -#else - fs_idx = FRAME2FS_IDX(L); -#endif - hannOla = hannOla_wins[fs_idx]; - - X_in[0].i = X_in[Lprot / 2].r; /* move fs/2 real to imag part of X_in[0]*/ - - real_fft_apply(PhEcu_ifft, (LC3_FLOAT*)X_in, xrec); - - move_float(xsubst, xrec, Lprot); - - - - - { - for (i = 0; i < Lprot; i++) { - - if (whr[i] != 0) { - xsubst[i] = xsubst[i] / whr[i]; /* inverse stored in BASOP */ - } - - } - - assert(xsubst_LL != NULL); - zero_float(xsubst_LL, (Lecu-Lprot)/2); /* initial 2ms */ - zero_float(&(xsubst_LL[ Lecu- (Lecu-Lprot)/2]), (Lecu-Lprot)/2); /* tail 2ms */ - { - /* position reconstruction properly */ - /* pXsubst_LL = &xsubst_LL[Lecu - Lprot - (Lecu - Lprot) / 2]; */ - pXsubst_LL = &xsubst_LL[(Lecu - Lprot) / 2]; - for (i = 0; i < Lprot ; i++) { - *pXsubst_LL++ = xsubst[i]; /* copy required 14.25 ms into center */ - } - } - - } - - - - work_part = LA_ZEROS + LA; - copy_part = (Lecu - Lprot) / 2; - ola_part = work_part - copy_part; - - pXfp = &xfp[Lprot - work_part]; - for (i = 0; i < copy_part; i++) { - xsubst_LL[i] = *pXfp++; - } - - assert(xsubst_LL != NULL); - pOlaXsubst = &(xsubst_LL[copy_part]); - pHannOla = hannOla; - for (i = 0; i < ola_part; i++) { - *pOlaXsubst = *pOlaXsubst * *pHannOla++; - pOlaXsubst++; - } - - pOlaXsubst = &(xsubst_LL[copy_part]); - for (i = 0; i < ola_part; i++) { - *pOlaXsubst = *pOlaXsubst + *pXfp++ * *pHannOla--; - pOlaXsubst++; - } - - - /* clear x_out to start with */ - assert(x_out != NULL); - zero_float(x_out, L); - - - for (i = 0; i < (Lecu - LA_ZEROS); i++) { - - xsubst_LL[i] = xsubst_LL[i] * winMDCT[i]; /* xsubstLL windowing up to 16.25 ms i.e not last 3.75 ms */ - - } - zero_float(&(xsubst_LL[Lecu - LA_ZEROS]), LA_ZEROS); /* tail 3.75ms always zero */ - - /* perform tda */ - - /* first half */ - pXsubst_LL = &xsubst_LL[3 * Lecu / 4]; - pXfp = &xsubst_LL[(3 * Lecu / 4) - 1]; - - pXOut = x_out; - for (i = 0; i < Lecu / 4; i++) { - *pXOut++ = -*pXsubst_LL++ - *pXfp--; /* 3.75 ms mults with 0 . may be skipped, see BASOP */ - } - - /* second half */ - /* */ - - pXsubst_LL = &(xsubst_LL[0]); - pXfp = &xsubst_LL[(Lecu / 2) - 1]; - for (i = 0; i < Lecu / 4; i++) { - *pXOut++ = *pXsubst_LL++ - *pXfp--; - } -} - diff --git a/lib_lc3plus/plc_phecu_setf0hz_fx.c b/lib_lc3plus/plc_phecu_setf0hz_fx.c new file mode 100644 index 000000000..6fffe632c --- /dev/null +++ b/lib_lc3plus/plc_phecu_setf0hz_fx.c @@ -0,0 +1,60 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +/* +st_PhECU_f0minLtp=55; % 55.4 Hz +st_PhECU_f0maxLtp=376; % 376.4706 Hz + +*/ + + +Word16 +plc_phEcuSetF0Hz_fx(/* output Q7 bin frequency [0.. 255.xxxx] "1 sign, 8 bits mantissa, 7 binomial" [0-255.9999] */ + Word16 fs_idx, Word16 old_pitch_int, Word16 old_pitch_fr) +{ + Word16 pitch_lagQ2, result, expo; + Word32 L_result, L_tmp; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_phEcuSetF0Hz_fx", sizeof(struct { + Word16 pitch_lagQ2, result, expo; + Word32 L_result, L_tmp; + Word16 num_FsByResQ0[5]; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::plc_phEcuSetF0Hz_fx"); +#endif + + result = 0; move16(); + IF (old_pitch_int != 0) + { + pitch_lagQ2 = add( + old_pitch_fr, + shl(old_pitch_int, 2)); /* lag at the current fs_idx , max lag_value is is 228(+.75)*48/12.8 = 858 in Q0 */ + + L_result = plc_phEcu_ratio_fx(L_deposit_h(num_FsByResQ0[fs_idx]), L_deposit_h(pitch_lagQ2), &expo); + L_tmp = L_shl_sat(L_result, sub(11, expo)); /* move to Q7, in high word to allow round*/ + result = round_fx(L_tmp); + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + + return result; /*Q7*/ +} + + diff --git a/lib_lc3plus/plc_phecu_spec_ana.c b/lib_lc3plus/plc_phecu_spec_ana.c deleted file mode 100644 index 463d3d1ae..000000000 --- a/lib_lc3plus/plc_phecu_spec_ana.c +++ /dev/null @@ -1,600 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - -#define PEAK_LOCATOR_RES_FX 1 /* fixed point resolution minimum value */ - - -static LC3_INT16 plc_phEcu_find_ind_fx( /* o : output maximum indx 0.. len-1 */ - const LC3_INT16 *inp, /* i : vector */ - const LC3_INT16 len, /* i : length */ - const LC3_INT16 val /* i : value to find */ -); - -static void plc_phEcu_peak_locator_fxlike(const LC3_INT16 *inp, /* i: vector with values >=0 ,Qx */ - const LC3_INT16 inp_len, /* i: length of inp */ - LC3_INT16 * int_plocs, /* o: array of filtered integer plocs Q0 */ - LC3_INT16 * n_fsc, /* o: total_ number of filtered located highs Q0 */ - const LC3_INT16 sens, /* i sensitivity, Qx */ - const LC3_INT16 inp_high, /* i global high , Qx */ - const LC3_INT16 inp_low /* i: global low, Qx */ -); - - -void plc_phEcu_spec_ana(LC3_FLOAT* xfp, - LC3_INT32 xfp_len, - const LC3_FLOAT* whr, - LC3_FLOAT *pfind_sensPtr, - LC3_INT32* plocs, - LC3_INT32* n_plocs, - LC3_FLOAT* f0est, - Complex* x, - LC3_INT32* x_len, - LC3_FLOAT * f0hzLtpBinPtr, - LC3_FLOAT * f0gainLtpPtr, - LC3_INT32 bw_idx, - Fft* PhEcu_fft -) -{ - - - LC3_INT32 i, peak_range_1, curr; - LC3_FLOAT xfp_w[MAX_PLC_LPROT]; - - LC3_FLOAT Xabs[MAX_LEN] = {0}; - LC3_FLOAT inp_high, inp_low, sens; - LC3_FLOAT interPos; - Complex Xana_p[3]; - LC3_INT32 P_in_plocs; - LC3_INT32 nSubs; - LC3_INT32 n_plocs_in; - LC3_FLOAT phEcu_c_jacob[1]; - - LC3_FLOAT fx_fft_scale; - LC3_FLOAT fft_fs_scale; - - LC3_FLOAT max_xfp_abs; - LC3_FLOAT PLC2_Q_flt; - LC3_FLOAT Q_scale_flt; - - LC3_INT16 Xabs_fx[MAX_LEN]; - LC3_INT16 plocs_fx[MAX_LEN]; - - LC3_INT16 sens_fx; - LC3_INT16 inp_high_fx; - LC3_INT16 inp_low_fx; - LC3_INT16 n_plocs_fx; - - LC3_FLOAT pfind_sens ; - LC3_FLOAT f0hzLtpBin ; - LC3_FLOAT f0gainLtp ; - - pfind_sens = *pfind_sensPtr; - f0hzLtpBin = *f0hzLtpBinPtr; - f0gainLtp = *f0gainLtpPtr; - - for (i = 0; i < xfp_len; i++) - { - xfp_w[i] = xfp[i] * whr[i]; /* whr windowing may be split into three segments , two loops, and possibly inplace */ - } - real_fft_apply(PhEcu_fft, xfp_w, (LC3_FLOAT *)x); - - x[xfp_len/2].r = x[0].i; /* move the real Fs/2 value to end */ - x[xfp_len/2].i = 0; /* safety clear imaginary Fs/2 value at end */ - x[0].i = 0.0; /* safety, make DC value only real */ - - - *x_len = xfp_len/2 + 1; - - i =(LC3_INT32) LC3_FLOOR(20000.0/PHECU_FRES)+1; - zero_cmplx( &(x[i]), *x_len - i); - - peak_range_1 = (LC3_INT32) MIN(*x_len, (40000.0 / 100 * 1.6) / 2 + 1); - - plc_phEcu_fft_spec2_sqrt_approx(x, peak_range_1, Xabs); - - zero_float(&(Xabs[peak_range_1]), *x_len - peak_range_1); - - inp_high = Xabs[0]; - inp_low = Xabs[0]; - - for (i = 1; i < peak_range_1; i++) { - inp_high = MAX(inp_high, Xabs[i]); - inp_low = MIN(inp_low, Xabs[i]); - } - - sens = (inp_high-inp_low)*(1-pfind_sens); - - if (inp_high > ((LC3_FLOAT) PEAK_LOCATOR_RES_FX)/2.0) - { - { - /* from ROM constants.c */ - LC3_FLOAT fx_fft_scales[5] = { 6, 7, 7, 8, 8 }; /*NB,WB, sSWB, SWB, FB*/ - fx_fft_scale = LC3_POW(2.0, fx_fft_scales[bw_idx]); /*% scaling due to up / dn pre shifts in fx FFT */ - } - { /* from ROM constants.c */ - LC3_FLOAT fx_fs_scales[5] = { 1.0, 1.0, 1.5, 1.0, 1.5 }; /*NB,WB, sSWB, SWB, FB*/ - fft_fs_scale = fx_fs_scales[bw_idx]; - } - - - max_xfp_abs = (LC3_FLOAT) LC3_FABS(xfp[0]); - for (i = 1; i < xfp_len; i++) { - max_xfp_abs = (LC3_FLOAT) MAX(max_xfp_abs, LC3_FABS(xfp[i])); - } - - if (max_xfp_abs >= 0.5) - { - PLC2_Q_flt = (LC3_FLOAT)LC3_FLOOR(LC3_LOGTWO(32768 / 2 / 2 / max_xfp_abs)); - Q_scale_flt = LC3_POW(2.0, PLC2_Q_flt) / fx_fft_scale / fft_fs_scale; /* basop way using xfp scale */ - - /* C-Float additional safety limit/verification of the integer xfp based scaling using the available C-float Xabs max value inp_high as well */ - { - LC3_FLOAT tmp_scale; - tmp_scale = LC3_POW(2.0, LC3_FLOOR(LC3_LOGTWO(32768 / 2 / 2 / inp_high))); - if (Q_scale_flt > tmp_scale) { - Q_scale_flt = tmp_scale; - } - } - /* Round sens, inp_high, inp_low according to BASOP fix-point scaling */ - - for (i = 0; i < peak_range_1; i++) { - Xabs_fx[i] = (LC3_INT16) LC3_ROUND(Xabs[i] * Q_scale_flt) ; - } - sens_fx = (LC3_INT16) LC3_ROUND(sens * Q_scale_flt) ; - inp_high_fx = (LC3_INT16) LC3_ROUND(inp_high * Q_scale_flt) ; - inp_low_fx = (LC3_INT16) LC3_ROUND(inp_low * Q_scale_flt) ; - plc_phEcu_peak_locator_fxlike(Xabs_fx, peak_range_1, plocs_fx, &n_plocs_fx, sens_fx, inp_high_fx, inp_low_fx); - - *n_plocs = (LC3_INT32)n_plocs_fx; - for (i = 0; i < *n_plocs; i++) { - plocs[i] = (LC3_INT32)plocs_fx[i]; /* short Word16 values now stored/saved as Word32 */ - } - } - else - { - *n_plocs = 0; /* time domain xfp level near zero */ - } - } - else - { - *n_plocs = 0; /* Freq domain Xabs max level near zero */ - } - - for (i = 0; i < *n_plocs; i++) { - curr = plocs[i]; - if (curr == 0) { - interPos = plc_phEcu_interp_max(Xabs, 3); /* returns 0.0 ... 2.0 */ - if (interPos == 2) { - /* integer peak was at DC, restrict to one of coeffs at [DC or DC+1] */ - interPos = plc_phEcu_interp_max(Xabs, 2); /* returns 0.0 or 1.0 */ - } - interPos += plocs[i]; - } else if (curr == 1) { - interPos = plc_phEcu_interp_max(Xabs, 3); - interPos += plocs[i] - 1; - } else if (curr == *x_len - 2) { - interPos = plc_phEcu_interp_max(&Xabs[*x_len - 3], 3); - interPos += plocs[i] - 1; - } else if (curr == *x_len - 1) { - /* integer curr at Fs/2, a real coeff */ - interPos = plc_phEcu_interp_max(&Xabs[*x_len - 3], 3); /* returns 0.0 ... 2.0 */ - interPos += plocs[i] - 2; /* valid for range ]... 1.0 ... 2.0] , where 1 is fs/2-1 and 2.0 is Fs/2 */ - if (interPos == 0) { - /* restrict to one of coeffs at [fs/2-1, fs/2 ] */ - interPos = plc_phEcu_interp_max(&Xabs[*x_len - 2], 2); /* returns 0.0 or 1.0 */ - interPos += plocs[i] - 1; - } - - if (interPos > (*x_len - 1) ) { /* interPos only defined up to Fs/2 */ - interPos = (LC3_FLOAT)(*x_len - 1); - } - } else { - Xana_p[0] = x[plocs[i]-1]; - Xana_p[1] = x[plocs[i]]; - Xana_p[2] = x[plocs[i]+1]; - phEcu_c_jacob[0] = (LC3_FLOAT)PHECU_C_JACOB; - interPos = plc_phEcu_imax2_jacobsen_mag(Xana_p, phEcu_c_jacob ); - interPos += (LC3_FLOAT) plocs[i]; - } - f0est[i] = interPos; - } - - if (*n_plocs >= 2 && plocs[0] == 0 && - f0est[0] > f0est[1] && plocs[1] <= 2 && Xabs[0] < Xabs[plocs[1]+1]) - { - f0est[0] = f0est[1]; - } - - P_in_plocs = plc_phEcu_pitch_in_plocs(plocs, *n_plocs); - - if (f0hzLtpBin > 0.0 && P_in_plocs > 0) { - nSubs = 2; - n_plocs_in = *n_plocs; - plc_phEcu_LF_peak_analysis(plocs, n_plocs, f0est, Xabs, &f0hzLtpBin, &f0gainLtp, nSubs); - - if (n_plocs_in == *n_plocs) { - nSubs = 3; - plc_phEcu_F0_refine_first(plocs, *n_plocs, f0est, *x_len, &f0hzLtpBin, &f0gainLtp, nSubs); - } - } - - if (f0gainLtp > 0.0 && f0gainLtp < 0.5 && *n_plocs > 14) { - if (P_in_plocs > 0) { - *n_plocs = 0; - } - } - - return; -} - - -#define sub(a,b) (a - b) -#define add(a,b) (a + b) -#define s_xor(a,b) (a ^ b) - -/* in case a value (e.g max or min) is already known , find the first corresponding array index */ -static LC3_INT16 plc_phEcu_find_ind_fx( /* o : output maximum indx 0.. len-1 */ - const LC3_INT16 *inp, /* i : vector */ - const LC3_INT16 len, /* i : length */ - const LC3_INT16 val /* i : value to find */ -) -{ - LC3_INT16 val_ind; - LC3_INT16 pos; - - val_ind = -1; - - for(pos = 0; pos < len; pos++) - { - if (sub(inp[pos], val) == 0) - { - val_ind = pos; - } - } - - return val_ind; -} - - - -/* BASOP function adapted to compile in float/integer environment */ -/*----------------------------------------------------------------------------- - * plc_phEcu_peak_locator_fxlike() - *----------------------------------------------------------------------------*/ -static void plc_phEcu_peak_locator_fxlike(const LC3_INT16 *inp, /* i: vector with values >=0 ,Qx */ - const LC3_INT16 inp_len, /* i: length of inp */ - LC3_INT16 * int_plocs, /* o: array of filtered integer plocs Q0 */ - LC3_INT16 * n_fsc, /* o: total_ number of filtered located highs Q0 */ - const LC3_INT16 sens, /* i sensitivity, Qx */ - const LC3_INT16 inp_high, /* i global high , Qx */ - const LC3_INT16 inp_low /* i: global low, Qx */ -) -{ - - LC3_INT16 j, k, n, idx_high, idx_low; - LC3_INT16 inp_len_minus1; - LC3_INT16 pairs_start, pairs_end; - LC3_INT16 *p_tmp; - LC3_INT16 prev_delta, curr_delta; - LC3_INT16 delta_predc, delta_fin; - LC3_INT16 add_dc_flag, add_fin_flag; - LC3_INT16 low_val_cand_pairs, val_range; - LC3_INT16 num_pairs, n_tail_values; - LC3_INT16 cand_phase_start, cand_idx, prev_low_plus_sens, tmp; - LC3_INT16 cand_high, prev_low; - LC3_INT16 *cand_pairs; /* actually [DC ] + pairs + [FS/2] */ - - LC3_INT16 sc_idx[1 + 368 + 1]; - LC3_INT16 cand_pairs_buf[1 + 1 + 368 + 1]; - LC3_INT16 fsc_idx[1 + 368 / 2 + 1]; - - - inp_len_minus1 = sub(inp_len, 1); /* size of delta=derivative array ,and last index in inp */ - - cand_pairs = &cand_pairs_buf[1]; /* ptr init , make space for storing a lowest amplitude value in location -1 */ - pairs_start = 1; /* adjusted to zero or 1 or 2 when/if, DC is injected as sc_idx[0], or initial plateau skipped */ - - p_tmp = &(sc_idx[pairs_start]); /* ptr init */ - - - /* xor high/low pairs of delta_inp and save sign changes */ - prev_delta = sub(inp[1], inp[0]); /* precompute very first delta */ - - for(n = 1; n < inp_len_minus1; n++) - { /* sign change analysis */ - curr_delta = sub(inp[n + 1], inp[n]); /* n+1 ,n , are loop ptrs */ - if (s_xor(prev_delta, curr_delta) < 0) /* a "0" delta treated as a positive sign */ - { - *p_tmp++ = n; /* store sign change bin locations , location n in the inp[] signal */ - } - prev_delta = curr_delta; - } - - k = (LC3_INT16)(p_tmp - &(sc_idx[pairs_start])); - - /* copy sign change location values to a pairs array */ - /* leave one initial sc_idx location open for a potential initial DC value */ - - for(j = 0; j < k; j++){ - cand_pairs[j + pairs_start] = inp[sc_idx[j + pairs_start]]; - } - - /* filter away a potential single initial/trailing plateau - to enable correct analysis for adding DC or fs/2 bins */ - - - if((sub(k, 2) >= 0) && - (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) == 0)){ - pairs_start = add(pairs_start, 1); - k = sub(k, 1); - } - - /* filter away potential single trailing plateu */ - pairs_end = sub(add(pairs_start, k), 1); /* point to last established sign change element */ - - if ((sub(k, 2) >= 0) && - (sub(cand_pairs[sub(pairs_end, 1)], cand_pairs[pairs_end]) == 0)){ - k = sub(k, 1); - } - pairs_end = sub(add(pairs_start, k), 1); /* recalc ptr to last element */ - - - /* conditionally add high/lows on both sides of input (pre_dc or fin) as candidates */ - add_dc_flag = 0; - add_fin_flag = 0; - - - if(sub(k, 1) == 0) /* one single sign change found special case */ - { - if (sub(inp[0], cand_pairs[pairs_start]) != 0) - { - add_dc_flag = 1; /* not plateau */ - } - - if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) != 0) - { - add_fin_flag = 1; /* not plateau */ - } - } - - if(sub(k, 2) >= 0) - { - delta_predc = sub(cand_pairs[pairs_start + 1], cand_pairs[pairs_start]); - delta_fin = sub(cand_pairs[pairs_end], cand_pairs[pairs_end - 1]); - - /* plateaus are allowed to be detected by xor sign change, - but still not allowed at the start nor at the end */ - - add_dc_flag = 1; - if (sub(inp[0], cand_pairs[pairs_start]) == 0) - { - add_dc_flag = 0; /* plateau down or , plateaus up., --> do not add DC */ - } - - - if ((sub(inp[0], cand_pairs[pairs_start]) < 0) && (delta_predc > 0)) - { - add_dc_flag = -1; /*UP - up ... replace */ - } - - if ((sub(inp[0], cand_pairs[pairs_start]) > 0) && (delta_predc < 0)) - { - add_dc_flag = -1; /* DOWN - down ... % replace */ - } - - add_fin_flag = 1; - if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) == 0) - { - add_fin_flag = 0; /* up - plateau ... */ - } - - if ((delta_fin > 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) < 0)) - { - add_fin_flag = -1; /* up - UP ... % replace , hard to hit */ - } - - if ((delta_fin < 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) > 0)) - { - add_fin_flag = -1; /*down - DOWN ... % replace */ - } - - } - - if(add_dc_flag > 0) - { /* add DC */ - pairs_start = sub(pairs_start, 1); - cand_pairs[pairs_start] = inp[0]; - sc_idx[pairs_start] = 0; - k = add(k, 1); - } - if(add_dc_flag < 0) - { /* -1 --> replace with DC*/ - cand_pairs[pairs_start] = inp[0]; - sc_idx[pairs_start] = 0; - } - - if(add_fin_flag > 0) - { /* add FS/2 */ - pairs_end = add(pairs_end, 1); - cand_pairs[pairs_end] = inp[inp_len_minus1]; - sc_idx[pairs_end] = inp_len_minus1; - k = add(k, 1); - } - if(add_fin_flag < 0) - { /* -1, replace tail with FS/2*/ - cand_pairs[pairs_end] = inp[inp_len_minus1]; - sc_idx[pairs_end] = inp_len_minus1; - } - /* preliminary cand_pairs now only have highs , lows , no initial/trailing plateaus */ - - - /* we allow the DC/FsBy2 lows to be used as the candidatelLow */ - low_val_cand_pairs = inp_low; - val_range = sub(inp_high, low_val_cand_pairs); /* used to determine if search is useful at all */ - - - if ((sub(val_range, PEAK_LOCATOR_RES_FX) < 0) || - (sub(inp_high, sens) < 0)) - { - k = 0; - } - - - if ((k == 0) && (sub(val_range, sens) >= 0)) - { - k = 1; - } - - - if(sub(k, 2) > 0) - { - /* low, high, low, ... or - high, low, high, ...*/ - - cand_phase_start = pairs_start; /*assume first candidate is a high */ - if (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) < 0) - { - cand_phase_start = add(pairs_start, 1); /* first is a low, --> skip to next higher cand */ - } - - /* high, low, high, ... */ - tmp = k; - if (sub(cand_phase_start, pairs_start) != 0) - { - tmp = sub(tmp, 1); - } - num_pairs = tmp / 2; // shr(tmp, 1); - n_tail_values = sub(tmp, num_pairs * 2); // shl(num_pairs, 1)); - - /* filter preliminary sign changes into sensitivity filtered sign changes */ - - *n_fsc = 0; /* counter of filtered fsc_idx */ - cand_high = low_val_cand_pairs; - cand_idx = -1; /* sentinel location for no high cand found yet. */ - cand_pairs[-1] = low_val_cand_pairs; - - prev_low = low_val_cand_pairs; - prev_low_plus_sens = add(prev_low, sens); - - /* filter loop for high - low sign change pairs */ - /* idx_high, idx_low are raw pointers into the cand_pairs and sc_idx arrays */ - - for(idx_high = cand_phase_start; idx_high < (cand_phase_start + 2 * num_pairs); idx_high += 2) - { - idx_low = idx_high + 1; /* loop ptr increase */ - - /* new high candidate larger than previous candidate and */ - /* sensitivity still larger than the the previous low */ - tmp = MAX(cand_high, prev_low_plus_sens); - if (sub(cand_pairs[idx_high], tmp) > 0) - { - cand_idx = idx_high; /* enable or shift candidate position fwd */ - } - cand_high = cand_pairs[cand_idx]; /* NB, cand_pairs[-1] , has the low_val_cand_pairs value stored */ - - /* now check the fwd idx_low of the current {high,low} pair */ - prev_low = MIN(cand_pairs[idx_low], prev_low); - - tmp = sub(cand_high, sens); - if(sub(tmp, cand_pairs[idx_low]) > 0) - { - /* this low point is now low enough to fix a previous high candidate */ - - fsc_idx[*n_fsc] = cand_idx; /*% add cand high idx -> output idx list*/ - *n_fsc = add(*n_fsc, 1); - - prev_low = cand_pairs[idx_low]; /* use this value as new low estimate */ - cand_idx = -1; /* no candidate until next pair or tail bin, and pt to lowVal */ - cand_high = low_val_cand_pairs; /* enable next candidate to be selected immediately */ - } - prev_low_plus_sens = add(prev_low, sens); - } /* { high, low} for loop */ - - - if((n_tail_values == 0) && (cand_idx >= 0)) - { - /* no tail low or high value to analyze - still may need to lock a non-locked but qualified candidate */ - fsc_idx[*n_fsc] = cand_idx; - *n_fsc = add(*n_fsc, 1); - } - - - /* cand_pairs vector may have a last orphan value */ - if(n_tail_values > 0) - { - /* cand_pairs vector may have a last orphan tail value */ - /* - logic boils down to if (nTailValues > 0) && (cand_pairs(n_end) > tmp) - there is a last one trailing high to process - - a) the last high, may be a new high Peak if we have not yet - locked the current candidate - b) if we have locked the last candidate, the last high may also be - a highpeak if it is high enough from the(newly set previous) valley floor. - - tmp=a||b - */ - - tmp = MAX(cand_high, prev_low_plus_sens); - tmp = sub(cand_pairs[pairs_end], tmp); - if(tmp > 0) - { - fsc_idx[*n_fsc] = pairs_end; - *n_fsc = add(*n_fsc, 1); - } - else - { - if(cand_idx >= 0) - { /* we have a previously established high candidate */ - fsc_idx[*n_fsc] = cand_idx; - *n_fsc = add(*n_fsc, 1); - } - - } - } - - /* move high locations info from fsc_idx , to output */ - for(j = 0; j < *n_fsc; j++) - { - int_plocs[j] = sc_idx[fsc_idx[j]]; - - } - - } /* end of pairs + [tail] section filtering */ - else - { - /* constant/single rise or constant decay or very low overall values, cases */ - *n_fsc = 0; - - tmp = sub(inp_high, sens); - if((k != 0) && (sub(tmp, low_val_cand_pairs) > 0)) - { - /* low,high */ - /* high,low */ - tmp = plc_phEcu_find_ind_fx(inp, inp_len, inp_high); - int_plocs[0] = tmp; /* simply locate the high peak*/ - *n_fsc = 1; - if (tmp < 0) - { /*safety in case max value index was not found */ - *n_fsc = 0; - } - } - } - - return; -} - diff --git a/lib_lc3plus/plc_phecu_subst_spec.c b/lib_lc3plus/plc_phecu_subst_spec.c deleted file mode 100644 index 388ae3cb8..000000000 --- a/lib_lc3plus/plc_phecu_subst_spec.c +++ /dev/null @@ -1,456 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" -#include "constants.h" - -static LC3_INT32 own_rand(LC3_INT32 seed); -static Complex valley_magnitude_adj(Complex X_i_in, LC3_INT32 uni_seed, LC3_FLOAT cos_F); -static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F); - -#ifdef CR8_A_PLC_FADEOUT_TUNING - -#define ONE_SIDED_SINE_WIDTH (4) /* expected pure sine main lobe maximum width (4+1+4) bins *62.5 hz/bin => approx 560 Hz total width */ - -static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_INT32 n_plocs, const Complex* X, const LC3_FLOAT* Xavg, const LC3_INT32 Lprot); -#endif - -void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_INT32 time_offs, Complex* X, LC3_INT32 X_len, - LC3_FLOAT* mag_chg_gr, LC3_INT32 *seed, LC3_FLOAT* alpha, LC3_FLOAT* beta, LC3_FLOAT* Xavg, - LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, -#ifdef CR8_A_PLC_FADEOUT_TUNING - LC3_INT16 fadeout, /* need for DC muting */ - LC3_INT16* nonpure_tone_flag_ptr, -#endif - LC3_FLOAT *corr_phase_dbg, - LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg) { - - LC3_INT32 i, i2, lprotBy2Minus1, one_peak_flag_mask, noise_mag_scale; - LC3_INT32 t_adv; - LC3_FLOAT corr_phase[MAX_PLC_NPLOCS] = {0}; - LC3_FLOAT cos_F, mag_chg_local, alpha_local, beta_local, tmp; - Complex X_i, X_i_new; - LC3_INT32 segmentLen, e; - LC3_FLOAT Xph; - LC3_FLOAT seed_local; - LC3_INT32 binCounter = 1, subInd = 0; -#ifdef CR8_A_PLC_FADEOUT_TUNING - LC3_INT16 fs_idx; -#endif - - UNUSED(corr_phase_dbg); - UNUSED(X_i_new_re_dbg); - UNUSED(X_i_new_im_dbg); - - seed_local = (LC3_FLOAT) *seed; - - lprotBy2Minus1 = imin(320, Lprot/2 - 1); /* limit to 20 KHz */ - - t_adv = t_adv_in + time_offs; - - for (i = 0; i < n_plocs; i++) { - corr_phase[i] = (LC3_FLOAT)2.0 * (LC3_FLOAT)M_PI * (f0est[i]/Lprot)*(LC3_FLOAT)t_adv; - } - - // EVOLVE PHASE ----------------- - - one_peak_flag_mask = -1; -#ifdef CR8_A_PLC_FADEOUT_TUNING - fs_idx = (LC3_INT16)LC3_FLOOR((LC3_FLOAT)Lprot / 160.0); /* aquire, fs_idx for 10 ms frame sizes */ - if (n_plocs < 3 && n_plocs > 0) - { - one_peak_flag_mask = 0; /* initial crude single tone detection, only using n_plocs as a result from peak_locator() dynamics as input */ - - if ( (*nonpure_tone_flag_ptr < 0 ) - && ( (fs_idx == 2) /*SemiSWB 24 kHz */ || (fs_idx >= 4) /* FB 48 kHz */ ) - ) - { - /* in the first lost frame analyze spectra to possibly reverse initial pure sine assumption */ - *nonpure_tone_flag_ptr = plc_phEcu_nonpure_tone_ana(plocs, n_plocs, X, Xavg, Lprot ); - } - - if ( *nonpure_tone_flag_ptr > 0 ) { - one_peak_flag_mask = -1; /* actually revert single pure tone detection */ /* 0-> mute all surrounding valley bins in evolution , 0xff -> generate noise in all valleys */ - } - - } -#else - if (n_plocs < 3 && n_plocs > 0) { - one_peak_flag_mask = 0; - } -#endif - - noise_mag_scale = 0; - if (n_plocs == 0 || time_offs != 0) { - noise_mag_scale = 1; - } - - if (n_plocs == 0) { - X[0] = realtoc(0); - X[X_len-1] = realtoc(0); - } - -#ifdef CR8_A_PLC_FADEOUT_TUNING - /* binary selection of fadeout scheme */ - assert(PLC2_FADEOUT_LONG_IN_MS >= PLC2_FADEOUT_IN_MS_MIN && PLC2_FADEOUT_IN_MS >= PLC2_FADEOUT_IN_MS_MIN); - assert(PLC2_FADEOUT_LONG_IN_MS <= PLC2_FADEOUT_IN_MS_MAX && PLC2_FADEOUT_IN_MS <= PLC2_FADEOUT_IN_MS_MAX); - i = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; - - if (fadeout != 0) - { - i = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; - } - - /* calculate local burst_len for securing DC and fs/2 muting */ - i2 = (time_offs / ((Lprot * 100) / 160)) + 1; /* burst_len */ - - if (i2 > (fade_scheme_tab[i][1] + 1)) - { - /* start DC scaling attenuation */ - X[0].r = alpha[0] * X[0].r; - - /* start fs/by2 attenuation */ - X[X_len - 1].r = alpha[(xavg_N_grp[fs_idx] - 1)] * X[X_len - 1].r; - } -#endif - - if (n_plocs != 0) { - for (i = 0; i < n_plocs; i++) { - LC3_INT32 delta_corr_dn = delta_corr; - LC3_INT32 delta_corr_up = delta_corr; - - if (i > 0) { - delta_corr_dn = imin( ((plocs[i] - plocs[i - 1] - 1) / 2), delta_corr_dn); - } - - if (i < n_plocs - 1) { - delta_corr_up = imin( ((plocs[i + 1] - plocs[i] - 1) / 2), delta_corr_up); - } - - segmentLen = (plocs[i] - delta_corr_dn) - binCounter; - - for (i2 = 0; i2 < segmentLen; i2++) { - seed_local = (LC3_FLOAT)rand_phase((LC3_INT32)seed_local, &cos_F); - - X_i = X[binCounter]; - X_i_new = cmul(X_i, cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0)); - - - seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); - - if (noise_mag_scale != 0) { - X_i = valley_magnitude_adj(X_i_new,(LC3_INT32) seed_local, cos_F); - X_i_new = X_i; - } - - mag_chg_local = mag_chg_gr[subInd]; - alpha_local = alpha[subInd]; - - if (beta[subInd] != 0) { - tmp = beta[subInd] * Xavg[subInd]; - if (one_peak_flag_mask == 0) { - tmp = 0; - X_i_new = realtoc(0); - } - X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0))); - } - else { - if (one_peak_flag_mask == 0) { - X_i_new = realtoc(0); - } - - X[binCounter] = cmul(realtoc(mag_chg_local), X_i_new); - } - - binCounter++; - - if (binCounter >= gwlpr[subInd + 1]) { - subInd++; - } - } - - e = plocs[i] + delta_corr_up; - if (e > lprotBy2Minus1) { - e = lprotBy2Minus1; - } - - Xph = corr_phase[i]; - - segmentLen = e - (binCounter - 1); - - for (i2 = 0; i2 < segmentLen; i2++) - { - seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); - X_i = X[binCounter]; - - { - LC3_INT32 nrep =(LC3_INT32) LC3_FLOOR(Xph / (2.0f*(LC3_FLOAT)M_PI)); - - X_i_new = cmul(X_i, cexpi(Xph - (2.0f*(LC3_FLOAT)M_PI*(LC3_FLOAT)nrep))); - } - - - seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); - - mag_chg_local = mag_chg_gr[subInd]; - alpha_local = alpha[subInd]; - beta_local = beta[subInd]; - if (beta_local != 0) { - - assert(alpha_local == mag_chg_local); - tmp = beta_local * Xavg[subInd]; - - X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0))); - } - else - { - X[binCounter] = cmul(realtoc(mag_chg_local), X_i_new); - } - - binCounter++; - - if (binCounter >= gwlpr[subInd + 1]) { - subInd++; - } - } - } - } - - segmentLen = lprotBy2Minus1 - (binCounter - 1); - - for (i = 0; i < segmentLen; i++) { - seed_local = (LC3_FLOAT)rand_phase((LC3_INT32)seed_local, &cos_F); - - X_i = X[binCounter]; - X_i_new = cmul(X_i, cexpi((LC3_FLOAT)M_PI*seed_local/(LC3_FLOAT)32768.0)); - - seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); - - if (noise_mag_scale != 0) { - X_i = valley_magnitude_adj(X_i_new, (LC3_INT32)seed_local, cos_F); - X_i_new = X_i; - } - - if (one_peak_flag_mask == 0) { - X_i_new = realtoc(0); - } - - alpha_local = alpha[subInd]; - mag_chg_local = mag_chg_gr[subInd]; - - if (beta[subInd] != 0) { - assert(alpha_local == mag_chg_local); - tmp = beta[subInd]*Xavg[subInd]; - - if (one_peak_flag_mask == 0) { - tmp = 0; - } - - X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local/(LC3_FLOAT)32768.0))); - } - else - { - X[binCounter] = cmul(realtoc(mag_chg_local), X_i_new); - } - - binCounter++; - - if (binCounter >= gwlpr[subInd + 1]) { - subInd++; - } - } - - - *seed = (LC3_INT32)seed_local; -} - -static LC3_INT32 own_rand(LC3_INT32 seed) { - LC3_INT32 retSeed; - assert(seed <= 32767 && seed >= -32768); - retSeed = (13849 + (seed + 32768) * 31821) & 65535; - retSeed -= 32768; - assert(retSeed <= 32767 && retSeed >= -32768); - return retSeed; -} - -static Complex valley_magnitude_adj(Complex X_i_in, LC3_INT32 uni_seed, LC3_FLOAT cos_F) { - LC3_FLOAT scale = ((LC3_FLOAT)0.5*(LC3_FLOAT)uni_seed/(LC3_FLOAT)32768.0) + (LC3_FLOAT)0.5*cos_F; - scale = (LC3_FLOAT)1.0 + (LC3_FLOAT)0.25*scale; - - assert(scale <= (LC3_FLOAT)1.25); - assert(scale >= (LC3_FLOAT)0.75); - - return cmul(X_i_in, realtoc(scale)); -} - -static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F) { - LC3_FLOAT seed = (LC3_FLOAT)own_rand(seed_in); - *cos_F = LC3_COS((LC3_FLOAT)M_PI*seed/(LC3_FLOAT)32768.0); - return (LC3_INT32) seed; -} - - -#ifdef CR8_A_PLC_FADEOUT_TUNING - -static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_INT32 n_plocs, const Complex* X, const LC3_FLOAT* Xavg, const LC3_INT32 Lprot) -{ - - LC3_INT16 nonpure_tone_detect; - LC3_INT16 n_ind, tone_ind, low_ind, high_ind; - LC3_FLOAT peak_amp, peak_amp2, valley_amp, x_abs[(1 + 2 * ONE_SIDED_SINE_WIDTH + 2 * 1)]; - LC3_INT16 sineband_ind_low, sineband_ind_high; - LC3_INT16 i, fs_idx, N_grp; - LC3_FLOAT tmp, tmp_dB, tot_inc_HF, tot_inc_LF; - - - - /* use compressed hearing sensitivity curve to allow more deviation in highest and lowest bands */ - /* ROM table LC3_FLOAT scATHFx[MAX_LGW - 1] */ - - /* init */ - nonpure_tone_detect = 0; - tot_inc_HF = 0.0; - tot_inc_LF = 0.0; - - /* limit single sine optimization to when 2 peaks are close enough to represent a single sinusoid */ - if (n_plocs == 2 && (plocs[1] - plocs[0]) >= ONE_SIDED_SINE_WIDTH) /* NB, plocs is an ordered vector */ - { - nonpure_tone_detect |= 0x1; - } - - /* local bin wise dynamics analysis, if 2 peaks, we do the analysis based on the location of the largest peak */ - { - tone_ind = 0; - plc_phEcu_fft_spec2_sqrt_approx(&(X[plocs[0]]), 1, &peak_amp); /* get 1st peak amplitude = approx_sqrt(Re^2+Im^2) */ - - - if ((n_plocs - 2) == 0) - { - plc_phEcu_fft_spec2_sqrt_approx(&(X[plocs[1]]), 1, &peak_amp2); /* get 2nd peak amplitude */ - if (peak_amp2 > peak_amp) - { - tone_ind = 1; - peak_amp = peak_amp2; - } - } - - low_ind = MAX(1, plocs[tone_ind] - (ONE_SIDED_SINE_WIDTH + 1)); /* DC is not allowed as valley */ - high_ind = MIN((Lprot >> 1) - 2, plocs[tone_ind] + (ONE_SIDED_SINE_WIDTH + 1)); /* Fs/2 is not allowed as valley */ - - n_ind = high_ind - low_ind + 1; - - /* find lowest amplitudes around the assumed main lobe center location */ - plc_phEcu_fft_spec2_sqrt_approx(&(X[low_ind]), n_ind, x_abs); - valley_amp = peak_amp; - for (i = 0; i < n_ind; i++) { - valley_amp = MIN(x_abs[i], valley_amp); - } - - /* at least a localized amplitude ratio of 16 (24 dB) required to declare a pure sinusoid */ - if (peak_amp < 16 * valley_amp) /* 1/16 easily implemented in BASOP */ - { - - nonpure_tone_detect |= 0x2;/* not a pure tone due to too low local SNR */ - - } - } - - /* analyze LF/ HF bands energy dynamics vs the assumed single tone band ( one or two peaks found) */ - { - fs_idx = (LC3_INT16)floor(Lprot / 160); /* fs_idx */ - assert(fs_idx < 5); - - /* Xavg , is a vector of rather rough MDCT based band energy estimates in perceptually motivated bands. from approx the last 26 ms of synthesis */ - - /* eval amplitude relations for assumed tonal band vs lower and higher bands */ - N_grp = xavg_N_grp[fs_idx]; /* { 4 NB , 5 WB , 6 SSWB , 7 SWB, 8 FB }; */ - - /* establish band(s) with assumed sinusoid tone */ - /* if tone freq location is below first MDCT-band definition, use first band as location anyway */ - i = 0; /* band 0 , 1 , 2 , 3 , ...*/ - while (plocs[tone_ind] >= gwlpr[i + 1]) { /* gwplr= [ 1, 12(750Hz), 20(1250Hz) , 36 , .. */ - /* dct-inds "0"...11, 12...19, 20...35, 36 ... */ - i++; - } - sineband_ind_low = i; - sineband_ind_high = i; /* typically in the same band as low */ - - /* a single tone may end up on a band border - , handle case when assumed tone is more or less right in between two perceptual bands +/-4 62.5 Hz */ - if ((sineband_ind_high > 0) && - (plocs[tone_ind] - ONE_SIDED_SINE_WIDTH) >= gwlpr[sineband_ind_high + 1] - ) { - sineband_ind_low = sineband_ind_high - 1; - } - - if ( (sineband_ind_low < (N_grp - 1)) && - (plocs[tone_ind] + ONE_SIDED_SINE_WIDTH) >= gwlpr[sineband_ind_low + 1] - ) { - sineband_ind_high = sineband_ind_low + 1; - } - } - - - - /* intraframe(26 ms), weighted LB and HB envelope dynamics/variation analysis */ - /* envelope analysis , - require at least two HF or two LF bands in the envelope taper/roll-off analysis , otherwise skip this condition */ - - - if (nonpure_tone_detect == 0 && - (((sineband_ind_high + 2) < N_grp) || - ((sineband_ind_low - 2) >= 1) - ) - ) - { - /* delta taper-off analysis solution, less sensitive to input bandwidth limitation and levels */ - - /* verify that an assumed clean sine does not have any odd HF content indications by thresholding the accumulated delta rise in LF/HF side lobes */ - for (i = (sineband_ind_high + 1); i < (N_grp - 1); i++) { - tmp = (Xavg[i + 1] + LC3_EPS) / (Xavg[i] + LC3_EPS); - tmp_dB = 20.0*LC3_LOGTEN(tmp); - if ((Xavg[i] + LC3_EPS) > (Xavg[i + 1] + LC3_EPS)) { - tmp_dB = 0; - } - tot_inc_HF += scATHFx[i] * tmp_dB; /* i is ATH factor between band i, i+1 based on Hearing sensitivity */ - } - - /* verify that an assumed clean sine does not have any odd LF content by thresholding the accumulated LF reverse up tilt */ - for (i = MAX(0, (sineband_ind_low - 1)); i > 0; i--) { - tmp = (Xavg[i - 1] + LC3_EPS) / (Xavg[i] + LC3_EPS); - tmp_dB = 20.0*LC3_LOGTEN(tmp); /* switch to log2() to simplify BASOP */ - - if ((Xavg[i - 1] + LC3_EPS) < (Xavg[i] + LC3_EPS)) { - tmp_dB = 0; - } - tot_inc_LF += scATHFx[i - 1] * tmp_dB; /* "psycho" scale using i-1 is ATH factor between band i-1, i , based on Hearing sensitivity */ - } - - if (tot_inc_HF > 4.5){ /* 4.5 dB in log2 is 0.7474 */ - nonpure_tone_detect |= 0x10; /* still not a pure tone, too great HF side increase */ - } - - if (tot_inc_LF > 4.5) { /* 4.5 dB limit in 4.5 = 20log10(x) corresponds to limit value 0.7474 in log2(x) */ - nonpure_tone_detect |= 0x20; /* still not a pure tone, too great accumulated LF side increase */ - } - - /* verify that an assumed clean sine does not have any odd LF+HF content by thresholding the accumulated LF+HF unexpected tilt */ - if ((tot_inc_LF + tot_inc_HF) > 6.0) { /* 6 dB limit in 20log10(x) corresponds to limit value 1.0 in log2(x) */ - nonpure_tone_detect |= 0x40; /* still not a pure tone, to great LF+HF side variation/increase */ - } - } /* bands available*/ - - return nonpure_tone_detect; -} -#endif /* CR8_A_PLC_FADEOUT_TUNING */ - diff --git a/lib_lc3plus/plc_phecu_tba_per_band_gain.c b/lib_lc3plus/plc_phecu_tba_per_band_gain.c deleted file mode 100644 index 10aef9234..000000000 --- a/lib_lc3plus/plc_phecu_tba_per_band_gain.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - -void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) -{ - LC3_INT32 i; - - /* per band gain */ - for (i = 0; i < n_grp; i++) { - if (gr_pow_left[i] > 0) - { - trans[i] = gr_pow_right[i] / gr_pow_left[i]; - } - else - { - /* handle division by zero case */ - if (gr_pow_right[i] > 0) - { - trans[i] = 10.0; /* positive/0 transient */ - } - else - { - trans[i] = 1.0; /* 0/0 no transient , no power change */ - } - } - grp_pow_change[i] = (LC3_FLOAT) 10.0 * LC3_LOGTEN(trans[i]); - - } - - return; -} diff --git a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c deleted file mode 100644 index 20baf4e79..000000000 --- a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - -void plc_phEcu_tba_spect_Xavg(LC3_INT32 fs_idx, LC3_INT32 n_grp, LC3_FLOAT *oold_spec_shape, - LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spec_shape, - LC3_FLOAT *old_EwPtr, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *Xavg) -{ - LC3_INT32 i; - LC3_FLOAT XavgEn[MAX_LGW]; - LC3_FLOAT xfp_w_scale, oold_Escale, old_Escale; - - /* 8k 16k 24k 32k 48k */ - LC3_FLOAT flt_xfp_wE_MDCT2FFT_target[5] = { (LC3_FLOAT) 1.9906, (LC3_FLOAT) 4.0445, (LC3_FLOAT) 6.0980, (LC3_FLOAT) 8.1533, (LC3_FLOAT) 12.2603 }; - LC3_INT32 gw_0[10] = { 1, 3, 5, 9, 17, 33, 49, 65, 81, 97 }; - - /* prepare scale factor */ - - xfp_w_scale = LC3_ROUND(flt_xfp_wE_MDCT2FFT_target[fs_idx]/(LC3_FLOAT)16.0*(LC3_FLOAT) 32768.0) / (LC3_FLOAT) LC3_POW(2,11); - - /* prepare left and right subband energies */ - oold_Escale = (*oold_EwPtr) * xfp_w_scale; - old_Escale = (*old_EwPtr) * xfp_w_scale; - for (i = 0;i < n_grp;i++) { - gr_pow_left[i] = oold_spec_shape[i] * oold_Escale; - gr_pow_right[i] = old_spec_shape[i] * old_Escale; - - XavgEn[i] = ((LC3_FLOAT) 0.5) * (gr_pow_left[i] + gr_pow_right[i]) / (gw_0[i + 1] - gw_0[i]); - Xavg[i] = LC3_SQRT(XavgEn[i]); - } - - return; -} - diff --git a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c deleted file mode 100644 index 69d6bf396..000000000 --- a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c +++ /dev/null @@ -1,387 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - -#define BETA_MUTE_FAC 0.5 /* % attenuation factor per additional bad frame, FX uses 0.5 (shift right with 1 bit) */ -#define BETA_MUTE_FAC_INI 0.5 - - -#define OFF_FRAMES_LIMIT 30 /* 300 ms for LC3 10 ms */ - - - -#define LGW32k 7 -#define LGW16k 5 - - -/* Tables for attentuation of mag_chg, copied from FX */ -/* Tables are in Q15 */ -/* 0.3 dB attenuation per frame for 16 frames, then 6 dB attenuation per frame */ -const LC3_INT32 POW_ATT_TABLE1[OFF_FRAMES_LIMIT + 1] = { 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, - 23198, 22410, 21650, 20915, 20205, 19519, 9759, 4880, 2440, 1220, - 610, 305, 152, 76, 38, 19, 10, 5, 2, 1, - 0 }; -/* % 0.4 dB attenuation per frame for 16 frames, then 6 dB attenuation per frame */ -const LC3_INT32 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = { 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, - 20675, 19745, 18856, 18007, 17197, 16423, 8211, 4106, 2053, 1026, - 513, 257, 128, 64, 32, 16, 8, 4, 2, 1, - 0 }; - -#ifdef PLC2_FADEOUT_IN_MS -#if PLC2_FADEOUT_IN_MS == 0 -#ifndef CR8_A_PLC_FADEOUT_TUNING -/* default setting only requires two tables */ -const Word16* const POW_ATT_TABLES[1 + 2] = -{ NULL, POW_ATT_TABLE1/*1 0.3dB steps */ , POW_ATT_TABLE0/*2 0.4 dB steps*/, -}; -#endif -#else - -#ifdef CR8_A_PLC_FADEOUT_TUNING -const LC3_INT32 POW_ATT_TABLE_p3x9_14_7[OFF_FRAMES_LIMIT + 1] = { - 32767, - 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, /* 9 times .3dB steps , 14 6 dB steps, 7 muted steps */ - 12007, 6003, 3002, 1501, 750, 375, 188, 94, 47, 23, 12, 6, 3, 1, - 0, 0, 0, 0, 0, 0, 0 }; - -const LC3_INT32 POW_ATT_TABLE_p4x9_14_7[OFF_FRAMES_LIMIT + 1] = -{ 32767, - 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, /* 9 times .4dB steps , 14 6 dB steps, 7 muted steps */ - 10825, 5413, 2706, 1353, 677, 338, 169, 85, 42, 21, 11, 5, 3, 1, - 0, 0,0,0,0,0,0 }; -#endif - - -const LC3_INT32 POW_ATT_TABLE_p3x8_6[] = { - 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 12865, 6433, - 3216, 1608, 804, 402, 201, 101, 50, 25, 13, 6, - 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; -const LC3_INT32 POW_ATT_TABLE_p4x8_6[OFF_FRAMES_LIMIT + 1] = { - 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 11869, 5935, - 2967, 1484, 742, 371, 185, 93, 46, 23, 12, 6, - 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; - -const LC3_INT32 POW_ATT_TABLE_p3x4_6[OFF_FRAMES_LIMIT + 1] = { - 32767, 31656, 30581, 29543, 14772, 7386, 3693, 1847, 923, 462, - 231, 115, 58, 29, 14, 7, 4, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const LC3_INT32 POW_ATT_TABLE_p4x4_6[OFF_FRAMES_LIMIT + 1] = { - 32767, 31293, 29885, 28540, 14270, 7135, 3568, 1784, 892, 446, - 223, 111, 56, 28, 14, 7, 3, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -const LC3_INT32 POW_ATT_TABLE_p3x2_6[OFF_FRAMES_LIMIT + 1] = { - 32767, 31656, 15828, 7914, 3957, 1979, 989, 495, 247, 124, - 62, 31, 15, 8, 4, 2, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const LC3_INT32 POW_ATT_TABLE_p4x2_6[OFF_FRAMES_LIMIT + 1] = { - 32767, 31293, 15647, 7823, 3912, 1956, 978, 489, 244, 122, - 61, 31, 15, 8, 4, 2, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -const LC3_INT32 POW_ATT_TABLE_p3x1_6[OFF_FRAMES_LIMIT + 1] = { - 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, - 32, 16, 8, 4, 2, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const LC3_INT32 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = { - 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, - 32, 16, 8, 4, 2, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -#ifdef CR8_A_PLC_FADEOUT_TUNING -const LC3_INT32 *const POW_ATT_TABLES[1 + 12] = -{ NULL, -/*0.3dB col , 0.4dB col */ -/* 1*/POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6, /* 0 0.3dB, 16 6dB, 14mute */ /* 0.4dB version */ /* old short mute tabs */ -/* 3*/POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6, /* 1 0.3dB, 15 6dB ,14mute */ /* 0.4dB version */ -/* 5*/POW_ATT_TABLE_p3x4_6, POW_ATT_TABLE_p4x4_6, /* 3 0.3dB, 15 6dB , 12 mute */ /* 0.4dB version */ -/* 7*/POW_ATT_TABLE_p3x8_6, POW_ATT_TABLE_p4x8_6, /* 7 0.3dB, 15 6dB , 8 mute */ /* 0.4dB version */ -/* 9*/POW_ATT_TABLE_p3x9_14_7, POW_ATT_TABLE_p4x9_14_7, /* 9 0.3dB, 14 6dB , 7 mute */ /* 0.4dB version */ /* opt 120 ms */ -/*11*/POW_ATT_TABLE1, POW_ATT_TABLE0, /* 15 0.3dB, 14 6dB , 1 mute */ /* 0.4dB version */ /* original curves */ -}; - -#else - -const LC3_INT32* const POW_ATT_TABLES[1 + 10] = -{ NULL, - POW_ATT_TABLE1 , POW_ATT_TABLE0, /* .3dB x16,16 6dB steps */ /* .4dB x16, 16 6dB steps */ /*original/default */ - POW_ATT_TABLE_p3x8_6, POW_ATT_TABLE_p4x8_6, /* .3dB x8, 24 6dB steps */ /* .4dB x8, 24 6dB steps */ - POW_ATT_TABLE_p3x4_6, POW_ATT_TABLE_p4x4_6, /* .3dB x4, 28 6dB steps */ /* .4dB x4, 28 6dB steps */ - POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6, /* .3dB x2, 30 6dB steps */ /* .4dB x2, 30 6dB steps */ - POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6 /* .3dB x1, 30 6dB steps */ /* .4dB x1, 30 6dB steps */ -}; -#endif -#endif -#endif - -void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *grp_pow_change, - LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, - LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec, - LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames_dbg, LC3_FLOAT *thresh_dbg -#ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type -#endif - ) -{ - - LC3_INT32 i; - LC3_FLOAT thresh_tr_dB, max_increase_grp_pow; - LC3_FLOAT max_increase_grp_pow_lin; - LC3_FLOAT grp_pow_change_lin[MAX_LGW]; - LC3_FLOAT XavgFadeinFactor; - - LC3_INT32 burst_att_thresh; - LC3_INT32 att_per_frame_idx; - LC3_INT32 att_always, attDegreeFrames; -#ifndef CR8_A_PLC_FADEOUT_TUNING - LC3_INT32 FADEOUT_IN_MS, PLC_P800_SPEECH_FADEOUT_IN_FRAMES, - PLC2_FADEOUT_IN_FRAMES, BURST_ATT_THRESH_PRE; -#endif - const LC3_INT32 *TABLEQ15; -#ifdef CR8_A_PLC_FADEOUT_TUNING - LC3_INT32 beta_mute_thr; /* time threshold in 10 ms frames to start beta - noise attenuation */ -#endif -#ifndef CR8_A_PLC_FADEOUT_TUNING - LC3_INT32 BURST_ATT_THRESH; /* start attenuate with losses in a row, also starts FADE2AVG actions */ - LC3_INT32 ATT_PER_FRAME; /* initial msuic attenuation table ptr, actually implemented in table lookup! */ - LC3_INT32 BETA_MUTE_THR; /* time threshold in 10 ms frames to start beta - noise attenuation */ -#endif - UNUSED(attDegreeFrames_dbg); - - /* constants setup */ - att_always = 0; - - XavgFadeinFactor = -1.0; - -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (PLC2_FADEOUT_IN_MS < 0) - { - FADEOUT_IN_MS = PLC_FADEOUT_IN_MS; /* % use TDC - SETTING as basic input */ - } - else - { - FADEOUT_IN_MS = PLC2_FADEOUT_IN_MS; /* % use a PLC2 individual settings */ - } -#endif - -#ifndef CR8_A_PLC_FADEOUT_TUNING - PLC_P800_SPEECH_FADEOUT_IN_FRAMES = (LC3_INT32)LC3_FLOOR((LC3_FLOAT)FADEOUT_IN_MS / (LC3_FLOAT)10.0); /* % nominal value for speech */ - - PLC2_FADEOUT_IN_FRAMES = MIN(OFF_FRAMES_LIMIT, MAX(6, 3 * PLC_P800_SPEECH_FADEOUT_IN_FRAMES)); /* for PLC2 we typically maintain energy 3x longer */ - - BURST_ATT_THRESH_PRE = MIN(5, MAX(1, (1 * PLC2_FADEOUT_IN_FRAMES) / 6)); /* nominal 20-40 ms to start actual muting, will be thresh +1 */ - ATT_PER_FRAME = MIN(10, MAX(2, 2 * (6 - BURST_ATT_THRESH_PRE))); /* % we let the BURST_ATT_thresh control the initial table selection */ - BURST_ATT_THRESH = MIN(BURST_ATT_THRESH_PRE, 4); - BETA_MUTE_THR = MIN(4 + (OFF_FRAMES_LIMIT / 2) + 1, MAX(4, BURST_ATT_THRESH + 1 + (LC3_INT32)LC3_POW((LC3_FLOAT)2.0, BURST_ATT_THRESH_PRE - (LC3_FLOAT)1))); /* nominal time to start mandatory decrease of Xavg */ - -/* Initialize in the same way as done in trans_burst_ana_fx(), even though this is not really needed */ - burst_att_thresh = BURST_ATT_THRESH; - att_per_frame_idx = ATT_PER_FRAME; -#endif - - - /* 10ms constants */ - thresh_tr_dB = 10.0; /* dB threshold kept same as for 20ms, even though transient analysis frame size was shortened */ - max_increase_grp_pow = 0; /* maximum amplification(dB) in case of onset transients, offset always deacy */ - - max_increase_grp_pow_lin = (LC3_FLOAT)1.0*LC3_POW((LC3_FLOAT)10.0, max_increase_grp_pow / (LC3_FLOAT)10.0)*(LC3_FLOAT)(32767.0 / 32768.0); - - -#ifndef CR8_A_PLC_FADEOUT_TUNING - /* envelope setting */ - burst_att_thresh = BURST_ATT_THRESH + 1; - att_per_frame_idx = ATT_PER_FRAME - 1; -#endif - -#ifdef CR8_A_PLC_FADEOUT_TUNING - if (plc_fadeout_type != 0) - { - i = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; /*a long fading table entry in fade_scheme_tab */ - } else { - i = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; /* a shorter fading entry in fade_scheme_tab */ - } - assert(i >= 0 && i <= ((PLC2_FADEOUT_IN_MS_MAX - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES) && "fade_scheme_tab index error"); - - att_per_frame_idx = fade_scheme_tab[i][0]; - burst_att_thresh = fade_scheme_tab[i][1]; /* number of 1.0 frames before muting/mixing phase */ - /* band gain muting may can take place earlier due to a band transient */ - beta_mute_thr = fade_scheme_tab[i][2]; /* muting of Xavg contribution start when slow fadeout is over */ -#endif - - attDegreeFrames = 0; - if (burst_len > burst_att_thresh) - { - att_always = 1; - - /* Added to be able to able to use tables to be aligned with FX */ - /* Limit attDegreeFrames to OFF_FRAMES_LIMIT */ - attDegreeFrames = burst_len - burst_att_thresh; - - if (attDegreeFrames > OFF_FRAMES_LIMIT) - { - attDegreeFrames = OFF_FRAMES_LIMIT; - } - } - - - set_vec(1.0 * (32767.0/32768.0), mag_chg, n_grp); - set_vec(0.0, ph_dith, n_grp); - - set_vec(1.0 * (32767.0/32768.0), alpha, n_grp); - set_vec(0.0, beta, n_grp); - set_vec_int(0, tr_dec, n_grp); - - set_vec(1.0 * (32767.0/32768.0), att_val, n_grp); - - - - /* transient detection per band */ - for (i = 0;i < n_grp; i++) { - if(burst_len == 1) - { - /* first bad frame */ - grp_pow_change_lin[i] = LC3_POW((LC3_FLOAT)10.0, grp_pow_change[i]/(LC3_FLOAT)10.0); - - *stPhECU_beta_mute = BETA_MUTE_FAC_INI; - *stPhECU_beta_mute = *stPhECU_beta_mute / (LC3_FLOAT)2.0; - - /* transient processing */ - /* transients may be both rise and decay transients !! */ - - if(LC3_FABS(grp_pow_change[i]) >= thresh_tr_dB) - { - - tr_dec[i] = 1; - } - - - /* magnitude modification */ - att_val[i] = 0.0f; - if(tr_dec[i] || att_always) { - - att_val[i] = MIN(max_increase_grp_pow_lin, grp_pow_change_lin[i]); /* % linear values !! */ - att_val[i] = LC3_SQRT(att_val[i]); - mag_chg[i] = att_val[i]; - stPhECU_mag_chg_1st[i] = att_val[i]; - } - else - { - mag_chg[i] = 1.0 * (LC3_FLOAT)(32767.0/32768.0); - stPhECU_mag_chg_1st[i] = (LC3_FLOAT)1.0; - } - } - else - { - /* burst handling based on states */ - - assert(burst_len >= 2); /* states used here */ - tr_dec[i] = 0; - -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (PLC_FADEOUT_IN_MS > 0) -#endif - { -#ifdef CR8_A_PLC_FADEOUT_TUNING - assert(att_per_frame_idx >= 1 && att_per_frame_idx <= (10+2)); -#else - assert(att_per_frame_idx >= 1 && att_per_frame_idx <= 10); -#endif - TABLEQ15 = POW_ATT_TABLES[att_per_frame_idx]; - att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT) TABLEQ15[MIN(OFF_FRAMES_LIMIT, attDegreeFrames )] / (LC3_FLOAT)32768.0); /* Table idx 0...N-1 therefore no + 1 */ - att_val[i] = att_val[i]; - } -#ifndef CR8_A_PLC_FADEOUT_TUNING - else - { - - if (att_per_frame_idx == ATT_PER_FRAME) - { - att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT)POW_ATT_TABLE0[MIN(OFF_FRAMES_LIMIT, attDegreeFrames)] / (LC3_FLOAT)32768.0); - } - else - { - att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT)POW_ATT_TABLE1[MIN(OFF_FRAMES_LIMIT, attDegreeFrames)] / (LC3_FLOAT)32768.0); - } - } -#endif - - if ( (att_val[i] != 0) && (att_val[i] * (LC3_FLOAT)32768.0 < (LC3_FLOAT)0.5) ) - { - att_val[i] = 0.0; /* for SNR measurments match in float lowest possible level to BASOP representation */ - } - - /* Apply attenuation */ - mag_chg[i] = stPhECU_mag_chg_1st[i]; - - mag_chg[i] = mag_chg[i] * att_val[i]; /* add additional attenuation from burst attenation logic */ - - if ((mag_chg[i] != 0) && (mag_chg[i] * (LC3_FLOAT)32768.0 < (LC3_FLOAT)0.5)) - { - mag_chg[i] = 0; /* for SNR measurments match in float lowest possible level to BASOP representation */ - } - - -#ifdef CR8_A_PLC_FADEOUT_TUNING - /* note beta_mute decreased once per frame, not once per band */ - if (i == 0 && burst_len > beta_mute_thr) -#else - if(burst_len > BETA_MUTE_THR) -#endif - { - *stPhECU_beta_mute = *stPhECU_beta_mute * (LC3_FLOAT)BETA_MUTE_FAC; - } - - alpha[i] = mag_chg[i]; - - if (alpha[i] >= (LC3_FLOAT)(32766.0 / 32768.0)) - { - beta[i] = 0; /* align to BASOP more efficent use of beta */ - } - else - { - beta[i] = LC3_SQRT((LC3_FLOAT)1.0 - alpha[i]* alpha[i]) * *stPhECU_beta_mute; - } - - if ( i >= LGW32k-1) { - beta[i] = beta[i] * (LC3_FLOAT)0.1; - } - else if( i >= LGW16k-1) - { - beta[i] = beta[i] * (LC3_FLOAT)0.5; - } - - - /* limit Xavg noise contribution further in case of offset / tr_decay */ - - if ((burst_len <= burst_att_thresh) && (stPhECU_mag_chg_1st[i] < (LC3_FLOAT)(32767.0 / 32768.0))) - { - XavgFadeinFactor = (LC3_FLOAT)(burst_len - (LC3_FLOAT)1.0) / burst_att_thresh; - - XavgFadeinFactor = MIN((LC3_FLOAT)1.0, XavgFadeinFactor); - - beta[i] = beta[i] * XavgFadeinFactor; - - } - } - } - - if (thresh_dbg != NULL) - { - *thresh_dbg = XavgFadeinFactor; - } - - return; -} - diff --git a/lib_lc3plus/plc_phecu_tools_fx.c b/lib_lc3plus/plc_phecu_tools_fx.c new file mode 100644 index 000000000..13e90fa49 --- /dev/null +++ b/lib_lc3plus/plc_phecu_tools_fx.c @@ -0,0 +1,247 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +/* initilize a short vector */ +void plc_phEcu_initWord16(Word16 * vec, /*i/o : short vector pointer */ + const Word16 value, /*i : short initialization value */ + const Word16 len) /*i : number of elements */ +{ + Counter n; + + FOR (n = 0; n < len; n++) + { + vec[n] = value; move16(); + } +} + +/* scale inplace with allowed saturation in upscaling , function not available in basop_util */ +void Scale_sig_sat(Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Counter i; + Word16 tmp; + IF (exp0 > 0) + { + FOR (i = 0; i < lg; i++) + { + x[i] = shl_sat(x[i], exp0); move16(); /* no saturation warnings triggered here */ + } + return; + } + IF (exp0 < 0) + { + tmp = shl(-32768, s_max(exp0, -15)); /* we use negative to correctly represent 1.0 */ + FOR (i = 0; i < lg; i++) + { + x[i] = msu_r(0, x[i], tmp); move16(); /* msu instead of mac because factor is negative */ + } + return; + } +} + +void plc_phEcu_minval_fx(const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + Word16 *minvalPtr /* o : min value Ptr */ +) +{ + Word16 minTmp; + Counter pos; + + minTmp = inp[0]; move16(); + assert(len>1); + FOR (pos = 1; pos < len; pos++) + { + minTmp = s_min(inp[pos], minTmp); + } + + *minvalPtr = minTmp; move16(); +} + +void plc_phEcu_maxval_fx(const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + Word16 *maxvalPtr /* o : *maxvalPtr */ +) +{ + Word16 maxTmp; + Counter pos; + + maxTmp = inp[0]; move16(); + + assert(len>1); + FOR (pos = 1; pos < len; pos++) + { + maxTmp = s_max(inp[pos], maxTmp); + } + *maxvalPtr = maxTmp; move16(); +} + +/* in case a value (e.g max or min) is already known , find the first corresponding array index */ +Word16 plc_phEcu_find_ind_fx( /* o : output maximum indx 0.. len-1 */ + const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + const Word16 val /* i : value to find */ +) +{ + Word16 val_ind; + Counter pos; + + val_ind = -1; move16(); + + FOR(pos = 0; pos < len; pos++) + { + if (sub(inp[pos], val) == 0) + { + val_ind = pos; move16(); + } + } + return val_ind; +} + +/*----------------------------------------------------------------------------- + * ratio_fx() + * + * Divide the numerator by the denominator. + *----------------------------------------------------------------------------*/ +Word16 plc_phEcu_ratio_fx( /* o : quotient in Q14 */ + const Word32 numer, /* i : numerator */ + const Word32 denom, /* i : denominator */ + Word16 *expo) /* o : req shift of quotient */ +{ + Word16 expNumer, expDenom; + Word16 manNumer, manDenom; + Word16 quotient; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_phEcu_ratio_fx", sizeof(struct { + Word16 expNumer, expDenom; + Word16 manNumer, manDenom; + Word16 quotient; + })); +#endif + + expDenom = norm_l(denom); /* exponent */ + manDenom = extract_h(L_shl(denom, expDenom)); /* mantissa */ + expNumer = norm_l(numer); /* exponent */ + manNumer = extract_h(L_shl(numer, expNumer)); /* mantissa */ + manNumer = shr_pos(manNumer, 1); /* Ensure the numerator < the denominator */ + quotient = div_s(manNumer, manDenom); /* in Q14 */ + + *expo = sub(expNumer, expDenom); +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return quotient; /* Q14 */ +} + +Word32 winEnCalc( /* o: output summed energy Ltot */ + const Word16 *x, /* i: Input signal */ + const Word16 headroom_shift, /* i: headroom_shift */ + const Word16 *win, /* i: left side Window coefficients */ + const Word16 rectLength, /* i: Offset in between the 1st and 2nd symmetric halves of the Hamming window */ + const Word16 halfLength, /* i: Half of the total length of a complete Hamming window. */ + Word16 *exp /* i/o : i exp of Word16 variable x , o:Lexp of output Word32 sum */ + ) +{ + Counter i; + Word32 L_tot; + const Word16 *pX, *pW; + Word16 tmp, tmp_RL; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("PhEcu::GF::winEnCalc", sizeof(struct { + Counter i; + Word32 L_tot; + const Word16 *pX, *pW; + Word16 tmp, tmp_RL; + })); +#endif + + +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::winEnCalc"); +#endif + + L_tot = INT32_MAX; move32(); /*acc is on negative side , but as all accumulation is positive, we make use of one extra bit */ + pX = x; + pW = win; + + + assert( headroom_shift>=0 ); + FOR (i = 0; i < halfLength; i++) /* 1st symmetric half of the Hamming window */ + { + tmp = mult(*pX++, *pW++); + tmp = shr_pos(tmp, headroom_shift); /* shr may/create bias on the negative side , costly options are shr_r or use msu_r */ + L_tot = L_msu0(L_tot, tmp, tmp); /* acc on negative energy side */ + } + + /* Periodic filter - one more rect sample before end tapering */ + tmp_RL = add(rectLength, 1); + ASSERT(rectLength != 0); + + FOR (i = 0; i < tmp_RL; i++) /* If rectLength is zero, it's a pure Hamming window; otherwise Hamming-Rectangular. */ + { + tmp = shr_pos( *pX++, headroom_shift); + L_tot = L_msu0(L_tot, tmp, tmp); /* acc on negative side */ + } + + tmp_RL = sub(halfLength, 1); + ASSERT(rectLength != 0); + + FOR (i = 0; i < tmp_RL; i++) /* 2nd symmetric half of the Hamming window. */ + { + tmp = mult(*pX++, *(--pW)); + tmp = shr_pos(tmp, headroom_shift); + L_tot = L_msu0(L_tot, tmp, tmp); + } + + /* Lexp = 2*(incoming_exp + dnshift) + 1 , 2x for square + 1(for msu0 DSP dn shift)*/ + *exp = add(shl_pos(add(*exp, headroom_shift),1),1); + + /* handle wrap on zero point */ + IF( L_tot >= 0 ) + { /* L_tot positive --> less than 32 bits needed, */ + L_tot = L_add(L_tot,(INT32_MIN+1)); + if( L_tot == 0 ) + { + *exp = LTOT_MIN_EXP; /* WC is actually (-(15+4)*2 + 1 +1 -31) */ ; move16(); + } + L_tot = L_min(L_tot, -1); /* make sure there is energy for future ratio calculations */ + } + ELSE + { /* L_tot negative --> more than 31 bits needed for sum , scale 32 bit sum within 31 bits and adjust exp */ + + L_tot = L_shr_pos(L_add(L_tot,1),1); /* rnd by adding 1, then use 50% contribution from negative side */ + L_tot = L_add(L_tot, INT32_MIN>>1); /* add 50% contribution from positive side */ + + *exp = add(*exp, 1); move16(); + } + + L_tot = L_max( -(INT32_MAX), L_tot); /* guard against max accumulation on the negative side , should only occur for rectangle windows */ + L_tot = L_negate(L_tot); /* no saturation here */ + + /* activate when xfp_exp is not used any longer */ + /* pre-maximize the mantissa for the following steps in burst_ana_dx */ + tmp = norm_l(L_tot); + L_tot = L_shl(L_tot,tmp); + *exp = sub(*exp, tmp); move16(); + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + return L_tot; +} + diff --git a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c deleted file mode 100644 index a25947a18..000000000 --- a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "functions.h" - - - - -void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, - LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, - LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, - LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg -#ifdef CR8_A_PLC_FADEOUT_TUNING - , LC3_UINT8 plc_fadeout_type -#endif -) -{ - LC3_FLOAT gr_pow_left[MAX_LGW]; - LC3_FLOAT gr_pow_right[MAX_LGW]; - LC3_FLOAT trans[MAX_LGW]; - LC3_FLOAT grp_pow_change[MAX_LGW]; - LC3_FLOAT ph_dith[MAX_LGW]; - LC3_FLOAT att_val[MAX_LGW]; - LC3_INT32 tr_dec[MAX_LGW]; - - LC3_INT32 attDegreeFrames; - LC3_FLOAT thresh_dbg; - - UNUSED(tr_dec_dbg); - UNUSED(gpc_dbg); - - if (burst_len <= 1) - { - plc_phEcu_tba_spect_Xavg(fs_idx, n_grp, oold_spect_shape, oold_EwPtr, old_spect_shape, old_EwPtr, gr_pow_left, gr_pow_right, stPhECU_Xavg); - - plc_phEcu_tba_per_band_gain(n_grp, gr_pow_left, gr_pow_right, trans, grp_pow_change); - - } - - plc_phEcu_tba_trans_dect_gains(burst_len, n_grp, grp_pow_change, stPhECU_beta_mute, stPhECU_mag_chg_1st, alpha, beta, mag_chg, ph_dith, tr_dec, att_val, &attDegreeFrames, &thresh_dbg -#ifdef CR8_A_PLC_FADEOUT_TUNING - , plc_fadeout_type -#endif - ); - - - - return; -} - diff --git a/lib_lc3plus/plc_tdac_fx.c b/lib_lc3plus/plc_tdac_fx.c new file mode 100644 index 000000000..c27cc9e7a --- /dev/null +++ b/lib_lc3plus/plc_tdac_fx.c @@ -0,0 +1,217 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +/* + * processTdac_fx + * + * Parameters: + * ola_mem o: pointer of output signal Q0 + * ola_mem_exp o: exponent of output signal Q0 + * synth i: pointer of input signal Q0 + * synth_exp i: exponent of input signal Q0 + * win i: pointer of analysis and synthesis window Q0 + * la_zeroes i: number of zeroes Q0 + * frame_len i: frame length Q0 + * + * Function: + * + * + * Returns: + * void + */ +void processTdac_fx(Word16 *ola_mem, Word16 *ola_mem_exp, const Word16 *synth_inp, const Word16 synth_exp_inp, +#ifdef ENABLE_HR_MODE + const Word32 *win, +#else + const Word16 *win, +#endif + const Word16 la_zeroes, const Word16 frame_len, Word8 *scratchBuffer) +{ + Counter i; + Word16 s; + Word16 L; + Word16 N; + Word16 NZ; + Word16 LD2; + Word32 sz; + Word16 INV_NORM; + Word16 INV_NORM_E; + Word16 smax; + Word16 * synth; + Word16 synth_len; + Word16 synth_exp; +#ifdef ENABLE_HR_MODE + const Word32 *win1, *win2, *win3, *win4; +#else + const Word16 *win1, *win2, *win3, *win4; +#endif + const Word16 *synth1; + const Word16 *synth2; + Word16 * ola_mem1; + Word16 * ola_mem2; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processTdac_fx", sizeof(struct { + Counter i; + Word16 s; + Word16 L; + Word16 N; + Word16 NZ; + Word16 LD2; + Word32 sz; + Word16 INV_NORM; + Word16 INV_NORM_E; + Word16 smax; + Word16 * synth; + Word16 synth_len; + Word16 synth_exp; + const Word16 *win1; + const Word16 *win2; + const Word16 *win3; + const Word16 *win4; + const Word16 *synth1; + const Word16 *synth2; + Word16 * ola_mem1; + Word16 * ola_mem2; + })); +#endif + + synth = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */ + + ASSERT(la_zeroes <= frame_len / 2); + + L = frame_len; move16(); + LD2 = shr_pos(L, 1); + NZ = sub(LD2, la_zeroes); + + /* inverse normalization of sqrt(2/N) inside window */ +#ifdef ENABLE_HR_MODE + IF ((sub(frame_len, 960) == 0) || (sub(frame_len, 720) == 0)) + { + INV_NORM = negate(shl_pos(frame_len, (15 - 10))); + INV_NORM_E = 3; move16(); + } + ELSE +#endif + { + INV_NORM = negate(shl_pos(frame_len, (15 - 9))); + INV_NORM_E = 2; move16(); + if (norm_s(INV_NORM) > 0) + { + INV_NORM = shl_pos(INV_NORM, 1); + INV_NORM_E = 1; move16(); + } + if (sub(frame_len, 120) <= 0) + { + INV_NORM_E = add(INV_NORM_E, 2); + } + if (sub(frame_len, 20) <= 0) + { + INV_NORM_E = add(INV_NORM_E, 2); + } + } + + /* Scale input */ + synth_len = sub(shl_pos(L, 1), la_zeroes); + s = getScaleFactor16(synth_inp, synth_len); + + FOR (i = 0; i < synth_len; i++) + { + synth[i] = shl(synth_inp[i], s); move16(); + } + synth_exp = sub(synth_exp_inp, s); + + /* calculate x_ov[L+la_zeroes] ... x_ov[2*L-1] */ + + win1 = &win[L + LD2 - 1]; + win2 = &win[L + LD2]; + + win3 = &win[LD2 - 1]; + win4 = &win[LD2]; + + synth1 = &synth[L + LD2 - 1 - la_zeroes]; + synth2 = &synth[L + LD2 - la_zeroes]; + + ola_mem1 = &ola_mem[LD2 - la_zeroes]; + ola_mem2 = &ola_mem[LD2 - la_zeroes - 1]; + + smax = 15; move16(); + + FOR (i = 0; i < NZ; i++) + { + /* analysis windowing + 2N -> N */ + sz = L_mac_sat(L_mult(*synth1, extractW16(*win1)), *synth2, extractW16(*win2)); + + /* N -> 2N + synthesis windowing */ + *ola_mem1 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win3))); move16(); + *ola_mem2 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win4))); move16(); + + /* determine headroom */ + s = norm_s(*ola_mem1); + if (*ola_mem1 != 0) + smax = s_min(smax, s); + s = norm_s(*ola_mem2); + if (*ola_mem2 != 0) + smax = s_min(smax, s); + + /* pointer update */ + win1--; + win2++; + win3--; + win4++; + synth1--; + synth2++; + ola_mem1++; + ola_mem2--; + } + + N = LD2; move16(); + + FOR (; i < N; i++) + { + /* analysis windowing + 2N -> N */ + sz = L_mult(*synth1, extractW16(*win1)); + + /* N -> 2N + synthesis windowing */ + *ola_mem1 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win3))); move16(); + + /* determin headroom */ + s = norm_s(*ola_mem1); + if (*ola_mem1 != 0) + smax = s_min(smax, s); + + /* pointer update */ + win1--; + win2++; + win3--; + synth1--; + synth2++; + ola_mem1++; + } + + smax = s_min(smax, 15); + + N = add(N, NZ); + + FOR (i = 0; i < N; i++) + { + ola_mem[i] = round_fx(L_mult(shl(ola_mem[i], smax), INV_NORM)); move16(); + } + + *ola_mem_exp = sub(add(synth_exp, INV_NORM_E), smax); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_tdc.c b/lib_lc3plus/plc_tdc.c deleted file mode 100644 index 25c4aa064..000000000 --- a/lib_lc3plus/plc_tdc.c +++ /dev/null @@ -1,803 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -/***************************************************************************\ - * contents/description: Main function for Time domain concealment -\***************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" -#include -#include "functions.h" - - -static LC3_INT16 TDC_random_short(LC3_INT16 *seed); -static LC3_FLOAT TDC_get_gainp(const LC3_FLOAT x[], const LC3_FLOAT y[], LC3_INT32 n); -static LC3_FLOAT TDC_get_gainc(const LC3_FLOAT x[], const LC3_FLOAT y[], const LC3_FLOAT *gain_p, const LC3_INT32 n, const LC3_INT32 frame_dms); -static void TDC_LPC_synthesis(const LC3_FLOAT a[], LC3_FLOAT x[], LC3_FLOAT y[], LC3_INT32 l, const LC3_FLOAT mem[], LC3_INT32 lpcorder, LC3_FLOAT *buf); -static void TDC_LPC_residu(const LC3_FLOAT *a, LC3_FLOAT *x, LC3_FLOAT *y, LC3_INT32 l, LC3_INT32 lpcorder); -static void TDC_highPassFiltering(const LC3_INT32 L_buffer, LC3_FLOAT exc2[], const LC3_FLOAT hp_filt[], const LC3_INT32 l_fir_fer); -static void TDC_f_preemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, LC3_FLOAT *mem); -static void TDC_deemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, const LC3_FLOAT *mem); -const LC3_FLOAT TDC_high_16[TDC_L_FIR_HP] = { 0.f, -0.0205f, -0.0651f, -0.1256f, -0.1792f, 0.8028f, -0.1792f, -0.1256f, -0.0651f, -0.0205f, 0.f }; -const LC3_FLOAT TDC_high_32[TDC_L_FIR_HP] = {-0.0517f, -0.0587f, -0.0820f, -0.1024f, -0.1164f, 0.8786f, -0.1164f, -0.1024f, -0.0820f, -0.0587f, -0.0517f}; -const LC3_FLOAT TDC_high_16_harm[TDC_L_FIR_HP] = { 0.0053f, 0.0000f, -0.0440f, 0.0000f, 0.2637f, 0.5500f, 0.2637f, 0.0000f, -0.0440f, 0.0000f, 0.0053f}; -const LC3_FLOAT TDC_high_32_harm[TDC_L_FIR_HP] = {-0.0053f, -0.0037f, -0.0140f, 0.0180f, 0.2668f, 0.4991f, 0.2668f, 0.0180f, -0.0140f, -0.0037f, -0.0053f}; -static void TDC_levinson(LC3_FLOAT *acf, LC3_INT32 len, LC3_FLOAT *out); -static void TDC_copyFLOAT(const LC3_FLOAT * X, LC3_FLOAT * Z, LC3_INT32 n); -static LC3_FLOAT TDC_dotFLOAT(const LC3_FLOAT * X, const LC3_FLOAT * Y, LC3_INT32 n); - -const LC3_INT32 beforeNextIncArray[4][4] = {{0,0,0,1}, - {0,1,0,1}, - {0,1,1,1}, - {1,1,1,1}}; -const LC3_INT32 nextIncArray[4][4] = {{1,0,0,0}, - {1,0,1,0}, - {1,0,1,1}, - {1,1,1,1}}; - -void processTdcApply_fl(const LC3_INT32 pitch_int, - const LC3_FLOAT *preemphFac, - const LC3_FLOAT* A, - const LC3_INT32 lpc_order, - const LC3_FLOAT* pcmbufHist, - const LC3_INT32 max_len_pcm_plc, - const LC3_INT32 N, - const LC3_INT32 frame_dms, - const LC3_INT32 SampRate, - const LC3_INT32 nbLostFramesInRow, - const LC3_INT32 overlap, - const LC3_FLOAT *stabFac, - LC3_FLOAT harmonicBuf[MAX_PITCH], - LC3_FLOAT synthHist[M], - LC3_INT32* fract, - LC3_INT16* seed, - LC3_FLOAT* gain_c, - LC3_FLOAT* alpha, - LC3_FLOAT* synth -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - ,LC3_UINT8 plc_fadeout_type -#endif - ) -{ - LC3_FLOAT step, step_n; - LC3_INT32 i, len, Tc, nbLostCmpt_loc, nextInc, beforeNextInc; - LC3_FLOAT gain_h, tmp, gain_p; - LC3_FLOAT *exc2, *exc_buf, *exc, *x_pre, *buf, *pt_exc, *pt1_exc, *synthMemPtr; - LC3_FLOAT *harmonicBufPtr; - LC3_FLOAT synth_mem[M]; - const LC3_FLOAT *hp_filt, *high_harm; - LC3_FLOAT gainInov; - LC3_FLOAT hpBlendFac; - char *scratchSpace1st, *scratchSpaceTmp; - char scratchSpace[(MAX_LEN_PCM_PLC + MDCT_MEM_LEN_MAX + MAX_LEN_PCM_PLC + 1 + M) * sizeof(LC3_FLOAT)]; - LC3_FLOAT alphaPrev; - LC3_FLOAT throttle; - LC3_INT32 frame_dms_idx, nbLostFramesInRow_mod; -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - LC3_INT32 plc_fadeout_len = 0; -#endif - - memset(synth_mem, 0, M * sizeof(LC3_FLOAT)); - memset(scratchSpace, 0, (MAX_LEN_PCM_PLC + MDCT_MEM_LEN_MAX + MAX_LEN_PCM_PLC + 1 + M) * sizeof(LC3_FLOAT)); - - /* len of synthesized signal */ - len = N + overlap; - - nbLostCmpt_loc = floor(frame_dms/100.0 * (nbLostFramesInRow - 1) + 1); - frame_dms_idx = frame_dms / 25 - 1; /* 0,1,2,3 */ - nbLostFramesInRow_mod = (nbLostFramesInRow - 1) % 4; - - beforeNextInc = beforeNextIncArray[frame_dms_idx][nbLostFramesInRow_mod]; - nextInc = nextIncArray [frame_dms_idx][nbLostFramesInRow_mod]; - -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - if (plc_fadeout_type == 1){ - plc_fadeout_len = PLC_FADEOUT_TYPE_1_IN_MS; - } - else{ - plc_fadeout_len = PLC_FADEOUT_IN_MS; - } -#endif - -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - if (nbLostCmpt_loc > plc_fadeout_len/10) -#else - if (nbLostCmpt_loc > PLC_FADEOUT_IN_MS/10) -#endif - { - gain_p = 0; - *gain_c = 0; - *alpha = 0; - memset(synth, 0, len * sizeof(LC3_FLOAT)); - return; - } - - Tc = pitch_int; - if (*fract > 0) { - Tc++; - } - - /*---------------------------------------------------------------- - * Buffer Initialization for timeDomainConcealment_Apply - * - * 1st - * |--exc_buf--|--x_pre--| - * | |--exc2--| - * | |--buf (LPC Syn)--| - * - *---------------------------------------------------------------*/ - - scratchSpace1st = scratchSpace; - exc_buf = (LC3_FLOAT*)scratchSpace1st; scratchSpace1st += (LC3_INT32)sizeof(LC3_FLOAT) * (Tc + N/2 + len); - exc = exc_buf + (Tc + N/2); - - scratchSpaceTmp = scratchSpace1st; - x_pre = (LC3_FLOAT*)scratchSpaceTmp; scratchSpaceTmp += (LC3_INT32)sizeof(LC3_FLOAT) * (lpc_order + Tc + N/2 + 1); - - /*---------------------------------------------------------------* - * LPC Residual * - *---------------------------------------------------------------*/ - if (nbLostFramesInRow == 1) - { - /* copy buffer to pre-emphasis buffer */ - TDC_copyFLOAT(&(pcmbufHist[max_len_pcm_plc-(lpc_order+Tc+N/2+1)]), &(x_pre[0]), lpc_order+Tc+N/2+1); - - /* apply pre-emphasis to the signal */ - TDC_f_preemph(&(x_pre[1]), preemphFac, lpc_order+Tc+N/2, &x_pre[0]); - - /* copy memory for LPC synth */ - TDC_copyFLOAT(&(x_pre[Tc+N/2+1]), synth_mem, lpc_order); - - /* LPC Residual */ - TDC_LPC_residu(A, &(x_pre[lpc_order+1]), &(exc[-(Tc+N/2)]), Tc+N/2, lpc_order); - } - - /*---------------------------------------------------------------* - * Calculate gains * - *---------------------------------------------------------------*/ - if (nbLostFramesInRow == 1) - { - if (pitch_int == Tc) - { - gain_p = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+1]), N/2 ); - } - else - { - tmp = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+2]), N/2 ); - gain_p = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+1]), N/2 ); - - if (tmp > gain_p) { - Tc = pitch_int; - gain_p = tmp; - *fract = 0; - } - } - - if(gain_p < 0.0f) - { - gain_p = 0.0f; - } - - if(gain_p > 1.0f) - { - gain_p = 1.0f; - } - - *gain_c = 0.0f; - - if (pitch_int == Tc) - { - *gain_c = TDC_get_gainc( &(exc[-1]), &(exc[-1-Tc]), &gain_p, N/2, frame_dms ); - } - else - { - tmp = TDC_get_gainc( &(exc[-1]), &(exc[-1-pitch_int]), &gain_p, N/2, frame_dms ); - *gain_c = TDC_get_gainc( &(exc[-1]), &(exc[-1-Tc]) , &gain_p, N/2, frame_dms ); - *gain_c = MIN(*gain_c, tmp); - } - } - else - { - gain_p = *alpha; - } - - /*---------------------------------------------------------------* - * Damping factor * - *---------------------------------------------------------------*/ - - alphaPrev = 1; - if (nbLostFramesInRow > 1) - { - alphaPrev = *alpha; - } - -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - if (plc_fadeout_type == 2){ - *alpha = LC3_POW(0.5,(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0); - } - else{ -#endif - - if (nextInc != 0) - { - switch (nbLostCmpt_loc) - { - case 1: - *alpha = (LC3_FLOAT)sqrt(gain_p); - if ( *alpha > 0.98f ) - { - *alpha = 0.98f; - } - else if ( *alpha < 0.925f ) - { - *alpha = 0.925f; - } - break; - case 2: - *alpha = (0.63f + 0.35f * (*stabFac)) * gain_p; - if ( *alpha < 0.919f ) - { - *alpha = 0.919f; - } - break; - default: - *alpha = (0.652f + 0.328f * (*stabFac)) * gain_p; - } - } - - if (nbLostCmpt_loc > 3) - { - switch (frame_dms) - { - case 25: *alpha *= PLC34_ATTEN_FAC_025; break; -#ifdef CR9_J_SLOW_TDC_FADEOUT - case 50: *alpha *= PLC34_ATTEN_FAC_025; break; -#else - case 50: *alpha *= PLC34_ATTEN_FAC_050; break; -#endif -#ifdef CR8_G_ADD_75MS - case 75: *alpha *= PLC34_ATTEN_FAC_075; break; -#endif - case 100: *alpha *= PLC34_ATTEN_FAC_100; break; - } - } - - if (nbLostCmpt_loc > 5) - { - gain_p = *alpha; - } -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - } -#endif - /*---------------------------------------------------------------* - * Construct the harmonic part * - * Last pitch cycle of the previous frame is repeatedly copied. * - *---------------------------------------------------------------*/ - - pt_exc = harmonicBuf; - pt1_exc = exc - Tc; - - if( nbLostFramesInRow == 1 ) - { - if (*stabFac >= 1) - { - TDC_copyFLOAT(pt1_exc, pt_exc, Tc); - } - else - { - /* These values are necessary for the last five filtered samples */ - TDC_copyFLOAT(&exc[-Tc], exc, (TDC_L_FIR_HP-1)/2); - - high_harm = TDC_high_32_harm; - if (SampRate <= 16000) - { - high_harm = TDC_high_16_harm; - } - - for( i = 0; i < Tc; i++ ) - { - pt_exc[i] = TDC_dotFLOAT(&pt1_exc[i-(TDC_L_FIR_HP-1)/2], high_harm, TDC_L_FIR_HP); - } - } - } - - /*---------------------------------------------------------------* - * Construct the random part of excitation * - *---------------------------------------------------------------*/ - scratchSpaceTmp = scratchSpace1st; - exc2 = (LC3_FLOAT*)scratchSpaceTmp; scratchSpaceTmp += (LC3_INT32)sizeof(LC3_FLOAT) * (len + TDC_L_FIR_HP - 1); - - for (i = 0; i < len + TDC_L_FIR_HP - 1; i++) { - exc2[i] = (LC3_FLOAT)TDC_random_short(seed); - } - - /* high pass noise */ - if (SampRate <= 16000 ) - { - hp_filt = TDC_high_16; - } else { - hp_filt = TDC_high_32; - } - - if ( nbLostFramesInRow == 1 ) - { - TDC_highPassFiltering(len, exc2, hp_filt, TDC_L_FIR_HP); - } - else - { - /* moves from 0 to 1, speed is defined by PLC3_HPBLENDTHROTTLE */ - throttle = (LC3_FLOAT)nbLostCmpt_loc / (nbLostCmpt_loc + PLC3_HPBLENDTHROTTLE); - hpBlendFac = (1 - *alpha) * throttle; - - for (i = 0; i < len; i++) - { - exc2[i] = hpBlendFac * exc2[i+TDC_L_FIR_HP/2] + (1 - hpBlendFac) * TDC_dotFLOAT(&exc2[i], hp_filt, TDC_L_FIR_HP ); - } - } - - /* normalize energy */ - gainInov = 1.0f / (LC3_FLOAT)sqrt(TDC_dotFLOAT( exc2, exc2, N ) / (LC3_FLOAT)N + 0.01f ); - gainInov *= (1.1f - 0.75* gain_p); - - /* gains */ - gain_h = alphaPrev; - tmp = *gain_c * *alpha / alphaPrev; - - /* update steps */ - step = (1.0f/(LC3_FLOAT)N) * (gain_h - *alpha); - step_n = (1.0f/(LC3_FLOAT)N) * (*gain_c - tmp); - - /*---------------------------------------------------------------* - * Construct the total excitation * - *---------------------------------------------------------------*/ - harmonicBufPtr = harmonicBuf + ((nbLostFramesInRow - 1) * N) % Tc; - - for ( i = 0; i < len; i++ ) { - /* harmonic */ - if (harmonicBufPtr - harmonicBuf >= Tc) { - harmonicBufPtr = harmonicBuf; - } - exc[i] = *harmonicBufPtr++; - exc[i] *= gain_h; - - /* random */ - exc2[i] *= *gain_c * gainInov; - - /* total */ - exc[i] = exc[i] + exc2[i]; - - /* update */ - gain_h -= step; - gain_h = MAX(gain_h, 0); - *gain_c -= step_n; - *gain_c = MAX(*gain_c, 0); - } - - *gain_c = tmp; - - /*----------------------------------------------------------* - * Compute the synthesis speech * - *----------------------------------------------------------*/ - buf = (LC3_FLOAT*)scratchSpace1st; scratchSpace1st += (LC3_INT32)sizeof(LC3_FLOAT) * (len + lpc_order); - synthMemPtr = synth_mem; - if (nbLostFramesInRow != 1) - { - synthMemPtr = synthHist; - } - - TDC_LPC_synthesis(A, - &exc[0], - synth, - len, - synthMemPtr, - lpc_order, - buf); - - TDC_copyFLOAT(&synth[N-lpc_order], synthHist, lpc_order); - - /*----------------------------------------------------------* - * Deemphasis * - *----------------------------------------------------------*/ - TDC_deemph( synth, preemphFac, len, &pcmbufHist[max_len_pcm_plc-1] ); - - /*----------------------------------------------------------* - * Fade to zero * - *----------------------------------------------------------*/ - if (beforeNextInc != 0) - { -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - if (nbLostCmpt_loc == plc_fadeout_len/10) -#else - if (nbLostCmpt_loc == PLC_FADEOUT_IN_MS/10) -#endif - { - gain_h = 1; - step = 1.0f/(LC3_FLOAT)N; - for ( i = 0; i < N; i++ ) { - synth[i] *= gain_h; - gain_h -= step; - } - memset(&synth[N], 0, overlap * sizeof(LC3_FLOAT)); - } - } -} - -/* Take only real part */ -void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, LC3_INT32 lpc_order) -{ - LC3_INT32 i, j, k; - LC3_FLOAT buf[2*MAX_BANDS_NUMBER_PLC]; - Complex sum; - Complex res; - - /* Buffer for ifft */ - j = 0; - for (i = 0; i < n_bands - 1; i += 2) - { - buf[j] = in[i]; - j++; - } - - for (i = n_bands - 1; i > 0; i -= 2) - { - buf[j] = in[i]; - j++; - } - - for (i = 0; i < n_bands; i++) - { - buf[j] = in[i]; - j++; - } - - /* ifft */ - for (j = 0; j < n_bands; j++) - { - sum.r = 0, sum.i = 0; - res.r = 0, res.i = 0; - for (k = 0; k < n_bands; k++) - { - res = cexpi((2 * M_PI * (LC3_FLOAT) (j * k)) / (LC3_FLOAT) n_bands); - res.r = res.r * buf[k]; - res.i = res.i * buf[k]; - sum = cadd(sum, res); - } - - res = cexpi((LC3_FLOAT) j * M_PI / (2.0 * (LC3_FLOAT) n_bands)); - out[j] = (sum.r * res.r - sum.i * res.i); - } - - out[0] = out[0] * 1.0001; - if (out[0] == 0) - { - out[0] = 1; - zero_float(&out[1], lpc_order); - } -} - -void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands) -{ - LC3_INT32 i; - - for (i = 0; i < n_bands; i++) - { - in[i] = in[i] * (1.0 - 2.0 * (*pre_emph_factor) * LC3_COS(2.0 * M_PI * (0.5 + (LC3_FLOAT) i) / (2.0 * (LC3_FLOAT) n_bands)) + (*pre_emph_factor) * (*pre_emph_factor)); - } -} - -void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3_INT32 frame_dms) -{ - LC3_INT32 i; - const LC3_FLOAT *lpc_array; - - lpc_array = plc_tdc_lpc_all[fs_idx]; - - if (fs_idx == 0 && frame_dms == 25) - { - lpc_array = plc_tdc_lpc_8_25ms; - } - - /* r[0] = r[0] * 1 */ - for (i = 1; i < len; i++) - { - r[i] = r[i] * lpc_array[i]; - } - - TDC_levinson(r, len - 1, A); -} - -/** random - * - * Parameters: - * seed I/O: seed for random number - * - * Function: - * Signed 16 bits random generator. - * - * Returns: - * random number - */ -static LC3_INT16 TDC_random_short(LC3_INT16 *seed) -{ - *seed = (LC3_INT16) (*seed * 12821L + 16831L); - return(*seed); -} - -static LC3_FLOAT TDC_get_gainp( /* output: gain of pitch */ - const LC3_FLOAT x[], /* input : input signal */ - const LC3_FLOAT y[], /* input : shifted input signal */ - LC3_INT32 n /* input : vector length */ -) -{ - LC3_FLOAT corr, ener; - LC3_INT16 i; - - corr = 0; ener = 1e-6f; - - for (i = 0; i < n; i++) - { - corr += x[i]*y[i]; - ener += y[i]*y[i]; - } - - return(corr/ener); -} - -static LC3_FLOAT TDC_get_gainc( /* output: gain of code */ - const LC3_FLOAT x[], /* input : input signal */ - const LC3_FLOAT y[], /* input : shifted input signal */ - const LC3_FLOAT *gain_p, /* input : gain of pitch */ - const LC3_INT32 n, /* input : vector length */ - const LC3_INT32 frame_dms /* input : frame length in dms */ -) -{ - LC3_FLOAT gain_c; - LC3_FLOAT gain_c_max; - LC3_INT16 i; - - gain_c = 0; gain_c_max = 0; - - for (i = 0; i < n; i++) - { - gain_c += ( x[-i] - *gain_p * y[-i] ) * ( x[-i] - *gain_p * y[-i] ); - } - - if (frame_dms < 100) - { - for (i = 0; i < n; i++) - { - gain_c_max += (x[-i] * x[-i]); - } - gain_c = MIN(gain_c, gain_c_max); - } - - gain_c = (LC3_FLOAT)sqrt(gain_c / n ); - - return gain_c; -} - -static void TDC_highPassFiltering(const LC3_INT32 L_buffer, /* i: buffer length */ - LC3_FLOAT exc2[], /* i/o: unvoiced excitation before the high pass filtering */ - const LC3_FLOAT hp_filt[], /* i: high pass filter coefficients */ - const LC3_INT32 l_fir_fer) /* i: high pass filter length */ -{ - LC3_INT32 i; - - for( i=0 ; i< L_buffer; i++ ) { - exc2[i] = TDC_dotFLOAT(&exc2[i], hp_filt, l_fir_fer); - } -} - -static void TDC_LPC_synthesis( - const LC3_FLOAT a[], - LC3_FLOAT x[], - LC3_FLOAT y[], - LC3_INT32 l, - const LC3_FLOAT mem[], - LC3_INT32 lpcorder, - LC3_FLOAT *buf - ) -{ - LC3_FLOAT s, *yy; - LC3_INT32 i, j; - - /* copy initial filter states into synthesis buffer */ - for (i=0; i < lpcorder; i++) - { - buf[i] = mem[i]; - } - yy = &buf[i]; - - for (i = 0; i < l; i++) - { - s = x[i]; - for (j = 1; j <= lpcorder; j++) - { - s -= a[j] * yy[i- j]; - } - y[i] = s; - yy[i] = y[i]; - } - - return; -} - - -/** TDC_LPC_residu - * - * Parameters: - * a I: LP filter coefficients (Q12) - * x I: input signal (usually speech) - * y O: output signal (usually residual) - * l I: size of filtering - * lpcorder I: Order of LP filter - * - * Function: - * Compute the LP residual by filtering the input speech through A(z). - * - * Returns: - * void - */ -static void TDC_LPC_residu(const LC3_FLOAT *a, LC3_FLOAT *x, LC3_FLOAT *y, LC3_INT32 l, LC3_INT32 lpcorder) -{ - LC3_FLOAT s; - LC3_INT32 i, j; - - for (i = 0; i < l; i++) - { - s = x[i]; - for (j = 1; j <= lpcorder; j++) - { - s += a[j] * x[i - j]; - } - y[i] = s; - } - - return; -} - - -/** TDC_f_preemph - * - * Parameters: - * signal I/O: signal - * mu I: preemphasis factor - * L I: vector size - * mem I: memory (x[-1]) - * - * Function: - * Filtering through 1 - mu z^-1 - * - * - * Returns: - * void - */ - -static void TDC_f_preemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, LC3_FLOAT *mem) -{ - LC3_INT32 i; - - for (i = L - 1; i > 0; i--) - { - signal[i] = signal[i] - *mu * signal[i - 1]; - } - - signal[0] -= *mu * (*mem); - - return; -} - -/* - * TDC_deemph - * - * Parameters: - * signal I/O: signal - * mu I: deemphasis factor - * L I: vector size - * mem I: memory (signal[-1]) - * - * Function: - * Filtering through 1/(1-mu z^-1) - * Signal is divided by 2. - * - * Returns: - * void - */ -static void TDC_deemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, const LC3_FLOAT *mem) -{ - LC3_INT32 i; - - signal[0] = signal[0] + *mu * (*mem); - - for (i = 1; i < L; i++) - { - signal[i] = signal[i] + *mu * signal[i - 1]; - } - - return; -} - -static void TDC_copyFLOAT(const LC3_FLOAT * X, LC3_FLOAT * Z, LC3_INT32 n) -{ - /* no values to copy */ - if ( (n < 1) || (X == Z) ){ - return; - } - /* If overlapping */ - if ( ( (Z > X) && (Z < X+n) ) || ( (Z < X) && (X < Z+n) ) ) { - memmove(Z, X, sizeof(LC3_FLOAT)*n); - } - else{ - memcpy(Z, X, sizeof(LC3_FLOAT)*n); - } -} - -static LC3_FLOAT TDC_dotFLOAT(const LC3_FLOAT * X, const LC3_FLOAT * Y, LC3_INT32 n) -{ - LC3_FLOAT acc; - LC3_INT32 i; - - acc = 0; - if (n) { - acc = X[0]*Y[0]; - } - - for (i=1; i= 0; i--) - { - out[j] = buf[k] - g * buf2[i]; - j++; k++; - } - - v = v * (1.0 - g * g); - } - - move_float(buf, out, len); - out[0] = 1; - - j = 1; - for (i = len - 1; i >= 0; i--) - { - out[j] = -buf[i]; - j++; - } -} - diff --git a/lib_lc3plus/plc_tdc_inverse_odft_fx.c b/lib_lc3plus/plc_tdc_inverse_odft_fx.c new file mode 100644 index 000000000..1e8e3191c --- /dev/null +++ b/lib_lc3plus/plc_tdc_inverse_odft_fx.c @@ -0,0 +1,130 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +void processInverseODFT_fx(Word32 *r_fx, Word16 *r_fx_exp, Word32 *d2_fx, Word16 d2_fx_exp, Word16 n_bands, + Word16 lpc_order, Word8 *scratchBuffer) +{ + Counter i; + Word16 s; + Word16 n_bands2; + Word32 * x; + const Word32 *inv_odft_twiddle_re; + const Word32 *inv_odft_twiddle_im; + Word8 * buffer_BASOP_rfftN; + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processInverseODFT_fx", sizeof(struct { + Counter i; + Word16 s; + Word16 n_bands2; + Word32 * x; + const Word32 *inv_odft_twiddle_re; + const Word32 *inv_odft_twiddle_im; + Word8 * buffer_BASOP_rfftN; + Word32 * params[2]; + })); +#endif + + x = scratchAlign(scratchBuffer, 0); /* Size = 320 bytes */ + buffer_BASOP_rfftN = scratchAlign(x, sizeof(*x) * (MAX_BANDS_NUMBER_PLC + MAX_BANDS_NUMBER_PLC/2)); /* Size = 480 bytes */ + + ASSERT(lpc_order <= M); + ASSERT(n_bands == 80 || n_bands == 60 || n_bands == 40 || n_bands == 20); + + n_bands2 = shr_pos_pos(n_bands, 1); + + test(); + IF (sub(n_bands, 20) == 0 || sub(n_bands, 60) == 0) + { + /* sort input samples */ + FOR (i = 0; i < n_bands2; i++) + { + x[2*i] = d2_fx[2 * i]; move32(); + x[2*i+1] = 0; move32(); + x[n_bands + 2*i] = d2_fx[n_bands - 1 - 2 * i]; move32(); + x[n_bands + 2*i + 1] = 0; move32(); + } + BASOP_cfft_lc3plus(&x[0], &x[1], n_bands, 2, &d2_fx_exp, (Word32*)buffer_BASOP_rfftN); + } + ELSE + { + /* sort input samples */ + FOR (i = 0; i < n_bands2; i++) + { + x[i] = d2_fx[2 * i]; move32(); + x[n_bands2 + i] = d2_fx[n_bands - 1 - 2 * i]; move32(); + } + + BASOP_rfftN(x, n_bands, &d2_fx_exp, buffer_BASOP_rfftN); + } + + inv_odft_twiddle_re = inv_odft_twiddle_80_re; + inv_odft_twiddle_im = inv_odft_twiddle_80_im; + IF (sub(n_bands, 20) == 0) + { + inv_odft_twiddle_re = inv_odft_twiddle_20_re; + inv_odft_twiddle_im = inv_odft_twiddle_20_im; + } + ELSE IF (sub(n_bands, 40) == 0) + { + inv_odft_twiddle_re = inv_odft_twiddle_40_re; + inv_odft_twiddle_im = inv_odft_twiddle_40_im; + } + ELSE IF (sub(n_bands, 60) == 0) + { + inv_odft_twiddle_re = inv_odft_twiddle_60_re; + inv_odft_twiddle_im = inv_odft_twiddle_60_im; + } + + s = norm_l(x[0]); + + /* imag[0] is always zero */ + r_fx[0] = L_shl_pos(x[0], s); move32(); + + /* r_fx[0] = r_fx[0] * 1.0001 */ + r_fx[0] = Mpy_32_32_lc3plus(r_fx[0], 0x4001A36E); move32(); + IF (norm_l(r_fx[0]) > 0) + { + r_fx[0] = L_shl_pos(r_fx[0], 1); + } + ELSE + { + s = sub(s, 1); + } + + /* post-twiddle */ + FOR (i = 1; i <= lpc_order; i++) + { + r_fx[i] = L_add(Mpy_32_32_lc3plus(L_shl(x[2 * i], s), inv_odft_twiddle_re[i - 1]), + Mpy_32_32_lc3plus(L_shl(x[2 * i + 1], s), inv_odft_twiddle_im[i - 1])); move32(); + } + + *r_fx_exp = sub(d2_fx_exp, s); move16(); + + /* r_fx[0] must not be zero */ + IF (r_fx[0] == 0) + { + r_fx[0] = (Word32)0x7FFFFFFF; move32(); + FOR (i = 1; i <= lpc_order; i++) + { + r_fx[i] = 0; move32(); + } + *r_fx_exp = 0; move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_phecu_setf0hz.c b/lib_lc3plus/plc_tdc_lagwin_fx.c similarity index 60% rename from lib_lc3plus/plc_phecu_setf0hz.c rename to lib_lc3plus/plc_tdc_lagwin_fx.c index 79a82d092..e5bd94d66 100644 --- a/lib_lc3plus/plc_phecu_setf0hz.c +++ b/lib_lc3plus/plc_tdc_lagwin_fx.c @@ -1,29 +1,32 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" #include "defines.h" #include "functions.h" - -LC3_FLOAT plc_phEcuSetF0Hz(LC3_INT32 fs, LC3_FLOAT * old_pitchPtr) +void processLagwin_fx(Word32 r[], const Word32 w[], Word16 m) { - LC3_FLOAT result; + /* Start Processing */ + Counter i; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processLagwin_fx", sizeof(struct { Counter i; })); +#endif - result = 0; - if (*old_pitchPtr != 0) + FOR (i = 0; i < m; i++) { - result = LC3_ROUND(fs/(*old_pitchPtr)/PHECU_FRES * 128.0) / 128.0; + r[i + 1] = Mpy_32_32_lc3plus(r[i + 1], w[i]); move32(); } - return result; +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif } + diff --git a/lib_lc3plus/plc_tdc_main_fx.c b/lib_lc3plus/plc_tdc_main_fx.c new file mode 100644 index 000000000..c6558dd1b --- /dev/null +++ b/lib_lc3plus/plc_tdc_main_fx.c @@ -0,0 +1,1257 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +/*****************************************************************************/ + +static Word16 TDC_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg); +static Word32 TDC_L_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg); +static void TDC_highPassFiltering_fx(const Word16 L_buffer, Word16 exc2[], const Word16 l_fir_fer, + const Word16 *hp_filt); +static Word32 TDC_calcGainp(Word16 x[], Word16 y[], Word16 lg); +static void TDC_calcGainc(Word16 *exc, Word16 Q_exc, Word16 old_fpitch, Word16 lg, Word16 frame_dms, Word16 lp_gainp, Word32 *lp_gainc); +static void TDC_random_fx(Word16 *seed, Word16 lg, Word16 *y); +static Word16 TDC_preemph(Word16 *x, const Word16 fac, const Word16 lg); +static void TDC_LPC_residu_fx(const Word16 *a, Word16 *x, Word16 *y, Word16 lg, Word16 m); +static void TDC_deemph_fx(const Word16 *x, Word16 *y, const Word16 fac, const Word16 lg, const Word16 mem); +static void TDC_LPC_synthesis_fx(const Word16 sh, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg, + const Word16 m); +static void TDC_normalize_energy_fx(Word16 *gain, Word16 *gain_exp, const Word16 *x, const Word16 lg); + +#ifdef CR8_G_ADD_75MS +const Word16 beforeNextIncArray_fx[4][4] = {{0,0,0,1}, + {0,1,0,1}, + {0,1,1,1}, + {1,1,1,1}}; +const Word16 nextIncArray_fx[4][4] = {{1,0,0,0}, + {1,0,1,0}, + {1,0,1,1}, + {1,1,1,1}}; +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +static Word16 type_2_alpha_long(Word16 nbLostFramesInRow, Word16 frame_dms); +static Word16 powWord16rest(Word16 base, Word16 exp, Word16 rest); +#endif + +/*****************************************************************************/ + + +/* + * processTimeDomainConcealment_Apply_fx + * + * Parameters: + * pitch_int i : integer pitch lag Q0 + * preemphFac_fx i : preemphase factor Q15 + * A_fx i : lp filter coefficients Qx + * pcmbufHist_fx i : pointer to input signal Qq_fx_old_exp + * frame_length i : frame length Q0 + * fs_idx i : sample rate index Q0 + * nbLostFramesInRow i : number of consecutive lost frames Q0 + * overlap i : overlap length Q0 + * stabFac_fx i : stability factor Q15 + * fract i/o: fraction of lag Q0 + * seed_fx i/o: pointer to seed Q0 + * gain_p_fx i/o: pointer to gainp Q15 + * gain_c_fx i/o: pointer to gainc 15Q16 + * synth_fx o : pointer to synthesized signal Q_syn + * Q_syn o : exponent for synthesized signal Q0 + * alpha o : damping factor Q15 + * scratchBuffer i : scratch buffer + * + * Function: + * Perform the time domain concealment. + * + * Returns: + * void + */ +void processTimeDomainConcealment_Apply_fx(const Word16 pitch_int, const Word16 preemphFac_fx, const Word16 *A_fx, + const Word16 lpc_order, const Word16 *pcmbufHist_fx, const Word16 frame_length, + const Word16 frame_dms, const Word16 fs_idx, const Word16 nbLostFramesInRow, + const Word16 overlap, const Word16 stabFac_fx, Word16 *fract, + Word16 *seed_fx, + Word32 *gain_c_fx, Word16 *synth_fx, Word16 *Q_syn, Word16 *alpha, Word16 max_len_pcm_plc, + Word16 harmonicBuf_fx[MAX_PITCH], Word16 synthHist_fx[M], Word16 *const harmonicBuf_Q, + Word8 *scratchBuffer +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + ,UWord8 plc_fadeout_type +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + ,Word16 * alpha_type_2_table +#endif +) +{ + Counter i; + Word16 s, s1, c1, c2, len, cnt, g_fx, ilen, Tc, nextInc, beforeNextInc; + Word32 tmp32, tmp32_2, gainc_tmp; + Word16 gain_p_fx; + Word32 gain_c_32_fx; + Word16 gain_c_16_fx, gain_c_16_fx_exp, gain_inov_fx, gain_inov_fx_exp, ilen_exp; + Word16 hpBlendFac; + Word16 len_pi_lf_2, frame_length_2, step_fx, step_n_fx, gain_h_fx, nbLostCmpt_loc, mem_deemph; + Word16 * synth_mem_fx, *synth_tmp_fx, *exc2_fx, *exc_fx, *pt_exc, *pt1_exc, *x_pre_fx; + Word16 * harmonicBufPtr; + Word16 Q_exc = 0, exp_scale; + const Word16 *hp_filt_fx, *TDC_high_harm; + Word16 alphaPrev_fx; + Word16 throttle; +#ifdef CR8_G_ADD_75MS + Word16 frame_dms_idx, nbLostFramesInRow_mod; +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processTimeDomainConcealment_Apply_fx", sizeof(struct { + Counter i; + Word16 s, s1, c1, c2, len, cnt, g_fx, ilen, Tc, nextInc, beforeNextInc; + Word32 tmp32, tmp32_2, gainc_tmp; + Word16 gain_p_fx; + Word32 gain_c_32_fx; + Word16 gain_c_16_fx, gain_c_16_fx_exp, gain_inov_fx, gain_inov_fx_exp, ilen_exp; + Word16 hpBlendFac; + Word16 len_pi_lf_2, frame_length_2, step_fx, step_n_fx, gain_h_fx, nbLostCmpt_loc, mem_deemph; + Word16 * synth_mem_fx, *synth_tmp_fx, *exc2_fx, *exc_fx, *pt_exc, *pt1_exc, *x_pre_fx; + Word16 * harmonicBufPtr; + Word16 Q_exc, exp_scale; + const Word16 *hp_filt_fx, *TDC_high_harm; + Word16 alphaPrev_fx; + Word16 throttle; + Word16 frame_dms_idx, nbLostFramesInRow_mod; + })); +#endif + +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + Word32 plc_fadeout_len = 0; +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + if (plc_fadeout_type >= 1){ +#else + if (plc_fadeout_type == 1){ +#endif + plc_fadeout_len = PLC_FADEOUT_TYPE_1_IN_MS; + } + else{ + plc_fadeout_len = PLC_FADEOUT_IN_MS; + } +#endif + + /* len of output signal */ + len = add(frame_length, overlap); + +#ifdef CR8_G_ADD_75MS + nbLostFramesInRow_mod = sub(nbLostFramesInRow, 1) & 0x0003; + + frame_dms_idx = mult(frame_dms, 0x051F); + nbLostCmpt_loc = add(shr(L_mult0(frame_dms_idx, sub(nbLostFramesInRow, 1)), 2), 1); + frame_dms_idx = sub(frame_dms_idx, 1); + beforeNextInc = beforeNextIncArray_fx[frame_dms_idx][nbLostFramesInRow_mod]; move16(); + nextInc = nextIncArray_fx [frame_dms_idx][nbLostFramesInRow_mod]; move16(); +#else + nbLostCmpt_loc = nbLostFramesInRow; move16(); + nextInc = 1; move16(); + beforeNextInc = 1; move16(); + SWITCH (frame_dms) + { + case 25: + nbLostCmpt_loc = shr(add(nbLostFramesInRow, 3), 2); + nextInc = (nbLostFramesInRow & 0x0003) == 1; move16(); + beforeNextInc = (nbLostFramesInRow & 0x0003) == 0; move16(); + BREAK; + case 50: + nbLostCmpt_loc = shr(add(nbLostFramesInRow, 1), 1); + nextInc = (nbLostFramesInRow & 0x0001) == 1; move16(); + beforeNextInc = (nbLostFramesInRow & 0x0001) == 0; move16(); + BREAK; + } +#endif + +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + IF (sub(nbLostCmpt_loc, plc_fadeout_len / 10) > 0) +#else + IF (sub(nbLostCmpt_loc, PLC_FADEOUT_IN_MS / 10) > 0) +#endif + { + gain_p_fx = 0; move16(); + *gain_c_fx = 0; move32(); + *Q_syn = 0; move16(); + *alpha = 0; move16(); + basop_memset(synth_fx, 0, len * sizeof(Word16)); +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return; + } + + frame_length_2 = shr_pos(frame_length, 1); + + Tc = pitch_int; move16(); + if (sub(*fract, 0) > 0) + { + Tc = add(Tc, 1); + } + + len_pi_lf_2 = add(Tc, frame_length_2); + + /*---------------------------------------------------------------- + * Buffer Initialization + * + * exc_fx synth_mem_fx + * |--exc_buf_past--|--exc_buf_curr--|--syn_mem--|--x_pre--| + * |--exc2--| + * |--syn--| + * + *---------------------------------------------------------------*/ + + /* pointer inits */ + exc_fx = (Word16 *)scratchAlign(scratchBuffer, + sizeof(Word16) * len_pi_lf_2); /* MAX_PITCH+MAX_LEN/2 + MAX_LEN+MDCT_MEM_LEN_MAX */ + synth_mem_fx = (Word16 *)scratchAlign(exc_fx, sizeof(*exc_fx) * len); /* M */ + x_pre_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_PITCH+MAX_LEN/2+M+1 */ + exc2_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_LEN+MDCT_MEM_LEN_MAX+TDC_L_FIR_HP-1 */ + synth_tmp_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_LEN+MDCT_MEM_LEN_MAX */ + /* Buffers 'overlap' since they are not used at the same time */ + + /*---------------------------------------------------------------* + * LPC Residual * + *---------------------------------------------------------------*/ + IF (sub(nbLostFramesInRow, 1) == 0) + { + + /* copy buffer to pre-emphasis buffer */ + cnt = add(len_pi_lf_2, lpc_order + 1); + basop_memmove(&x_pre_fx[0], &pcmbufHist_fx[max_len_pcm_plc - cnt], cnt * sizeof(Word16)); + + /* apply pre-emphasis to the signal; x_pre = x_pre_flt * 2^(q_fx_old_exp-15-Q_exc+1) */ + Q_exc = TDC_preemph(&(x_pre_fx[1]), preemphFac_fx, sub(cnt, 1)); + + /* copy memory for LPC synth */ + basop_memmove(&synth_mem_fx[0], &x_pre_fx[len_pi_lf_2 + 1], lpc_order * sizeof(Word16)); + + /* LPC Residual; exc = exc_fx * 2^(q_fx_old_exp-15-Q_exc) */ + TDC_LPC_residu_fx(A_fx, &(x_pre_fx[lpc_order + 1]), &(exc_fx[-len_pi_lf_2]), len_pi_lf_2, lpc_order); + } + + /*---------------------------------------------------------------* + * Calculate gains * + *---------------------------------------------------------------*/ + + IF (sub(nbLostFramesInRow, 1) == 0) + { + IF (sub(pitch_int, Tc) == 0) + { + gain_p_fx = + round_fx_sat(L_shl_sat(TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 1]), frame_length_2), 15)); + } + ELSE + { + tmp32 = TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 2]), frame_length_2); + tmp32_2 = TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 1]), frame_length_2); + + IF (L_sub(tmp32, tmp32_2) > 0) + { + Tc = pitch_int; move16(); + gain_p_fx = round_fx_sat(L_shl_sat(tmp32, 15)); + *fract = 0; move16(); + } + ELSE + { + gain_p_fx = round_fx_sat(L_shl_sat(tmp32_2, 15)); + } + } + + if (gain_p_fx < 0) + { + gain_p_fx = 0; move16(); + } + + IF (sub(pitch_int, Tc) == 0) + { + /* gain_c = gain_c_32_fx * 2^(q_fx_old_exp-31) */ + TDC_calcGainc(exc_fx, Q_exc, Tc, frame_length_2, frame_dms, gain_p_fx, &gain_c_32_fx); + } + ELSE + { + TDC_calcGainc(exc_fx, Q_exc, pitch_int, frame_length_2, frame_dms, gain_p_fx, &tmp32); + TDC_calcGainc(exc_fx, Q_exc, Tc , frame_length_2, frame_dms, gain_p_fx, &gain_c_32_fx); + + gain_c_32_fx = L_min(gain_c_32_fx, tmp32); move32(); + } + } + ELSE + { + gain_c_32_fx = *gain_c_fx; move32(); + gain_p_fx = *alpha; + } + + /*---------------------------------------------------------------* + * Damping factor * + *---------------------------------------------------------------*/ + + alphaPrev_fx = 0x7FFF; move16(); + IF (sub(nbLostFramesInRow,1) > 0) + { + alphaPrev_fx = *alpha; move16(); + } +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + IF (sub(plc_fadeout_type,2) == 0 ){ +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + *alpha = alpha_type_2_table[nbLostFramesInRow]; +#else + IF (sub(frame_dms,50) == 0){ + IF (sub(nbLostFramesInRow,30) >= 0){ + *alpha = 0; move16(); + } ELSE { + *alpha = FADE_OUT_TYPE_2_ALPHA_5MS[nbLostFramesInRow]; move16(); + } + } + IF (sub(frame_dms,25) == 0){ + IF (sub(nbLostFramesInRow,60) >= 0){ + *alpha = 0; move16(); + } ELSE { + *alpha = FADE_OUT_TYPE_2_ALPHA_2_5MS[nbLostFramesInRow]; move16(); + } + } +#endif + } + ELSE{ +#endif + IF (nextInc != 0) + { + IF (sub(nbLostCmpt_loc, 1) == 0) + { + /* Threshold 31470 is 0.98^2 in Q15 format */ + IF (sub(gain_p_fx, 31470) > 0) + { + *alpha = 0x7D71; /*0.98f*/ + move16(); + } + /* Threshold 28037 is 0.925^2 in Q15 format */ + ELSE IF (sub(gain_p_fx, 28037) < 0) + { + *alpha = 0x7666; /*0.925f*/ + move16(); + } + ELSE + { + exp_scale = 0; + *alpha = Sqrt16_lc3plus(gain_p_fx, &exp_scale); move16(); + *alpha = shl(*alpha, exp_scale); + } + } + ELSE + { + SWITCH (nbLostCmpt_loc) + { + case 2: + c1 = 0x50A4; /*0.630f*/ + move16(); + c2 = 0x2CCD; /*0.350f*/ + move16(); + BREAK; + default: + c1 = 0x5375; /*0.652f*/ + move16(); + c2 = 0x29FC; /*0.328f*/ + move16(); + BREAK; + } + + *alpha = mult_r(stabFac_fx, c2); + *alpha = add(*alpha, c1); + + *alpha = mult(gain_p_fx, *alpha); + + + IF (sub(nbLostCmpt_loc, 2) == 0) + { + if (sub(*alpha, 0x75A2 /*0.919f*/) < 0) + { + *alpha = 0x75A2; move16(); + } + } + ELSE IF (sub(nbLostCmpt_loc, 5) > 0) + { + gain_p_fx = *alpha; move16(); + } + } + } + + IF (sub(nbLostCmpt_loc,3) > 0) + { + SWITCH (frame_dms) + { + case 25: *alpha = mult(*alpha, PLC34_ATTEN_FAC_025_FX); BREAK; +#ifdef CR9_J_SLOW_TDC_FADEOUT + case 50: *alpha = mult(*alpha, PLC34_ATTEN_FAC_025_FX); BREAK; +#else + case 50: *alpha = mult(*alpha, PLC34_ATTEN_FAC_050_FX); BREAK; +#endif +#ifdef CR8_G_ADD_75MS + case 75: *alpha = mult(*alpha, PLC34_ATTEN_FAC_075_FX); BREAK; +#endif + case 100: *alpha = mult(*alpha, PLC34_ATTEN_FAC_100_FX); BREAK; + } + } + if (sub(nbLostCmpt_loc, 5) > 0) + { + gain_p_fx = *alpha; move16(); + } +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + } +#endif + + /*---------------------------------------------------------------* + * Construct the harmonic part * + * Last pitch cycle of the previous frame is repeatedly copied. * + *---------------------------------------------------------------*/ + + pt_exc = harmonicBuf_fx; move16(); + pt1_exc = exc_fx - Tc; move16(); + s = s_min(len, Tc); move16(); + test(); + IF (sub(nbLostFramesInRow, 1) == 0) + { + *harmonicBuf_Q = Q_exc; move16(); + IF (sub(stabFac_fx, 32767 /*1.f Q15*/) >= 0) + { + basop_memmove(pt_exc, pt1_exc, Tc * sizeof(Word16)); + } + ELSE + { + /* These values are necessary for the last five filtered samples */ + basop_memmove(exc_fx, &exc_fx[-Tc], (TDC_L_FIR_HP-1)/2 * sizeof(Word16)); + TDC_high_harm = TDC_high_32_harm; + if (sub(fs_idx, 1) <= 0) + { + TDC_high_harm = TDC_high_16_harm; + } + FOR (i = 0; i < Tc; i++) + { + pt_exc[i] = TDC_Dot_product(&pt1_exc[i-(TDC_L_FIR_HP-1)/2], TDC_high_harm, TDC_L_FIR_HP); + } + } + } + ELSE + { + Q_exc = *harmonicBuf_Q; move16(); + } + + + /*---------------------------------------------------------------* + * Construct the random part of excitation * + *---------------------------------------------------------------*/ + + TDC_random_fx(seed_fx, add(len, sub(TDC_L_FIR_HP, 1)), exc2_fx); + + /* high pass noise */ + hp_filt_fx = TDC_high_32; + if (sub(fs_idx, 1) <= 0) + { + hp_filt_fx = TDC_high_16; + } + + IF (sub(nbLostFramesInRow, 1) == 0) + { + TDC_highPassFiltering_fx(len, exc2_fx, TDC_L_FIR_HP, hp_filt_fx); + } + ELSE + { + throttle = div_s(nbLostCmpt_loc, add(nbLostCmpt_loc, PLC3_HPBLENDTHROTTLE)); + hpBlendFac = mult(sub(0x7FFF, *alpha), throttle); + c1 = sub(0x7FFF, hpBlendFac); + FOR (i = 0; i < len; i++) + { + /* Return value of dot product is Q1 */ + tmp32 = Mpy_32_16_lc3plus(TDC_L_Dot_product(&exc2_fx[i], hp_filt_fx, TDC_L_FIR_HP), c1 /*Q15*/); + exc2_fx[i] = round_fx(L_mac0(tmp32, hpBlendFac, exc2_fx[i+TDC_L_FIR_HP/2])); move16(); + } + } + + /* normalize energy */ + TDC_normalize_energy_fx(&gain_inov_fx, &gain_inov_fx_exp, exc2_fx, frame_length); + tmp32 = Mpy_32_16_lc3plus( + L_sub(590558016l /*1.1 Q29*/, Mpy_32_16_lc3plus(L_shr_pos(L_deposit_h(gain_p_fx), 2), 24576 /*0.75*/)) /*Q29*/, + gain_inov_fx /*Q15,gain_inov_e*/); /*Q29,gain_inov_e*/ + s = norm_l(tmp32); + tmp32 = L_shl_pos(tmp32, s); + tmp32 = L_min(tmp32, 0x7FFEFFFF); + gain_inov_fx_exp = add(sub(gain_inov_fx_exp, s), 31 - 29); /*->Q31*/ + gain_inov_fx = round_fx(tmp32); /*Q15,gain_inov_e*/ + + /* gains */ + gain_h_fx = alphaPrev_fx; move16(); + + /* update steps */ + if (frame_length == 720) + { + ilen = BASOP_Util_Divide1616_Scale_lc3plus((Word16)1, 960, &ilen_exp); + } else { + ilen = BASOP_Util_Divide1616_Scale_lc3plus((Word16)1, frame_length, &ilen_exp); + } + step_fx = round_fx(L_shl(L_mult(sub(gain_h_fx, *alpha), ilen), ilen_exp)); + + s = norm_l(gain_c_32_fx); + tmp32 = L_shl_pos(gain_c_32_fx, s); + + gain_c_16_fx = extract_h(tmp32); + gain_c_16_fx_exp = sub(15, s); +#ifdef CR9_M_FIX_DIV_ZERO + gainc_tmp = L_mult (gain_c_16_fx, div_s(*alpha, s_max(alphaPrev_fx, 1))); +#else + gainc_tmp = L_mult (gain_c_16_fx, div_s(*alpha, alphaPrev_fx)); +#endif + tmp32 = L_sub (tmp32, gainc_tmp); + step_n_fx = round_fx(L_shl(Mpy_32_16_lc3plus(tmp32, ilen), ilen_exp)); + + /*---------------------------------------------------------------* + * Construct the total excitation * + *---------------------------------------------------------------*/ + + harmonicBufPtr = harmonicBuf_fx + ((nbLostFramesInRow - 1) * frame_length) % Tc; + + s1 = add(Q_exc, add(gain_inov_fx_exp, gain_c_16_fx_exp)); + cnt = add(frame_length, TDC_L_FIR_HP / 2); + + g_fx = mult_r(gain_c_16_fx, gain_inov_fx); + + FOR (i = 0; i < len; i++) + { + /* harmonic */ + if (harmonicBufPtr - harmonicBuf_fx >= Tc) { + harmonicBufPtr = harmonicBuf_fx; + } + exc_fx[i] = *harmonicBufPtr++; + tmp32 = L_mult(exc_fx[i], gain_h_fx); + /* random */ + tmp32_2 = L_shl_sat(L_mult(exc2_fx[i], g_fx), s1); + /* total */ + exc_fx[i] = round_fx_sat(L_add_sat(tmp32, tmp32_2)); move16(); + /* update */ + gain_h_fx = s_max(sub(gain_h_fx, step_fx), 0); + gain_c_16_fx = s_max(sub(gain_c_16_fx, step_n_fx), 0); + g_fx = mult_r(gain_c_16_fx, gain_inov_fx); + } + + /* update gain */ + *gain_c_fx = L_shl(gainc_tmp, sub(gain_c_16_fx_exp, 15)); move32(); + + + /*----------------------------------------------------------* + * Compute the synthesis speech * + *----------------------------------------------------------*/ + + /* introduce some headroom to avoid Overflows, 2 bit seem to be sufficient */ + *Q_syn = sub(Q_exc, 2); + *Q_syn = s_max(*Q_syn, -3); + + exp_scale = sub(*Q_syn, Q_exc - 1); + + IF (sub(nbLostFramesInRow, 1) != 0) + { + synth_mem_fx = synthHist_fx; + } + Copy_Scale_sig(synth_mem_fx, &synth_tmp_fx[-lpc_order], lpc_order, exp_scale); + TDC_LPC_synthesis_fx(sub(Q_exc, *Q_syn), A_fx, exc_fx, synth_tmp_fx, len, lpc_order); + + FOR (i=0; i= 0); + synth_fx[i] = mult(synth_fx[i], gain_h_fx); + gain_h_fx = sub(gain_h_fx, step_fx); + } + basop_memset(&synth_fx[frame_length], 0, overlap * sizeof(Word16)); + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + +/*****************************************************************************/ + +static Word32 syn_kern_2(Word32 L_tmp, const Word16 a[], const Word16 y[]) +{ + L_tmp = L_msu_sat(L_tmp, y[-1], a[1]); + L_tmp = L_msu_sat(L_tmp, y[-2], a[2]); + return L_tmp; +} + +static Word32 syn_kern_4(Word32 L_tmp, const Word16 a[], const Word16 y[]) +{ + L_tmp = syn_kern_2(L_tmp, a, y); + return syn_kern_2(L_tmp, a + 2, y - 2); +} + +static Word32 syn_kern_8(Word32 L_tmp, const Word16 a[], const Word16 y[]) +{ + L_tmp = syn_kern_4(L_tmp, a, y); + return syn_kern_4(L_tmp, a + 4, y - 4); +} + +static Word32 syn_kern_16(Word32 L_tmp, const Word16 a[], const Word16 y[]) +{ + L_tmp = syn_kern_8(L_tmp, a, y); + return syn_kern_8(L_tmp, a + 8, y - 8); +} + +/* + * TDC_Dot_product + * + * Parameters: + * x i: x vector Q0 + * y i: y vector Q0 + * lg i: vector length Q0 + * + * Function: + * dot product + * + * Returns: + * dot product Q0 + */ +static Word16 TDC_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word32 sum; + ); + + sum = L_mult(x[0], y[0]); + FOR (i = 1; i < lg-1; i++) + { + sum = L_mac_sat(sum, x[i], y[i]); + } + + sum = mac_r_sat(sum, x[lg-1], y[lg-1]); + + Dyn_Mem_Deluxe_Out(); + + return sum; +} + +/* + * TDC_L_Dot_product + * + * Parameters: + * x i: x vector Q0 + * y i: y vector Q0 + * lg i: vector length Q0 + * + * Function: + * dot product + * + * Returns: + * dot product Q1 + */ +static Word32 TDC_L_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word32 sum; + ); + + sum = L_mac0(1L, x[0], y[0]); + FOR (i = 1; i < lg; i++) + { + sum = L_mac0(sum, x[i], y[i]); + } + + Dyn_Mem_Deluxe_Out(); + + return sum; +} + +/* + * TDC_highPassFiltering_fx + * + * Parameters: + * L_buffer i: buffer length + * exc2 i: unvoiced excitation before the high pass filtering Qx/Qx+1 + * l_fir_fer i: length highpass filter + * hp_filt i: highpass filter coefficients Q15 + * + * Function: + * Highpass filter + * + * Returns: + * void + */ +static void TDC_highPassFiltering_fx(const Word16 L_buffer, Word16 exc2[], const Word16 l_fir_fer, + const Word16 *hp_filt) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + FOR (i = 0; i < L_buffer; i++) + { + exc2[i] = round_fx(L_sub(TDC_L_Dot_product(&exc2[i], hp_filt, l_fir_fer), 1)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/* + * TDC_calcGainc + * + * Parameters: + * exc i: pointer to excitation buffer + * Q_exc i: Q format of excitation buffer + * old_fpitch i: pitch_int + * lg i: length + * lp_gainp i: gain p + * lp_gainc o: pointer to gain (15Q16) + * + * Function: + * Gain calculation + * + * Returns: + * void + */ +static void TDC_calcGainc(Word16 *exc, Word16 Q_exc, Word16 old_fpitch, Word16 lg, Word16 frame_dms, Word16 lp_gainp, Word32 *lp_gainc) +{ + Dyn_Mem_Deluxe_In( + Word16 tmp16, tmp_e, tmp2_e; + Word32 L_tmp, L_tmp_max; + Counter i; + ); + + L_tmp = L_deposit_l(0); + + FOR (i = 0; i < lg; i++) + { + /* gain_c += ( exc[-i-1] - *gain_p * exc[-i-1-pitch_int] ) * ( exc[-i-1] - *gain_p * exc[-i-1-pitch_int] ); */ + tmp16 = sub_sat(exc[i - lg] /*Q1*/, mult_r(lp_gainp /*Q15*/, exc[i - lg - old_fpitch] /*Q1*/) /*Q1*/); + L_tmp = L_mac0_sat(L_tmp, tmp16, tmp16); /*Q3*/ + } + + IF (sub(frame_dms, 100) < 0) + { + L_tmp_max = L_deposit_l(0); + FOR (i = 0; i < lg; i++) + { + L_tmp_max = L_mac0_sat(L_tmp_max, exc[i - lg], exc[i - lg]); /*Q3*/ + } + L_tmp = L_min(L_tmp, L_tmp_max); + } + + tmp_e = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, tmp_e); + tmp_e = sub(sub(31, shl_pos(Q_exc, 1)), tmp_e); /*L_tmp is Q31, now*/ + tmp16 = BASOP_Util_Divide3216_Scale_lc3plus(L_tmp /*Q31,norm,tmp_e*/, lg /*Q15,15*/, &tmp2_e) /*Q15,tmp2_e+tmp_e-15*/; + tmp_e = sub(add(tmp2_e, tmp_e), 15); + + IF (tmp16 != 0) + { + tmp16 = Sqrt16_lc3plus(tmp16, &tmp_e); /*Q15,norm,tmp_e*/ + tmp_e = L_min(tmp_e, 15); + *lp_gainc = L_shl_pos(L_deposit_l(tmp16), add(tmp_e, 1)); /*15Q16*/ + move32(); + } + ELSE + { + *lp_gainc = 0; + } + + Dyn_Mem_Deluxe_Out(); +} + +/* + * TDC_calcGainp + * + * Parameters: + * x i: input signal + * y i: shifted input signal + * lg i: vector length + * + * Function: + * Gain calculation + * + * Returns: + * gain (15Q16) + */ +static Word32 TDC_calcGainp(Word16 x[], Word16 y[], Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Word32 tcorr, tener, Lgain, L_tmp1, L_tmp2; + Word16 m_corr, m_ener, negative, Q_corr, Q_ener; + Counter i; + ); + + negative = 0; move16(); + + L_tmp1 = L_deposit_l(0); + L_tmp2 = L_deposit_l(0); + FOR (i = 0; i < lg; i += 2) + { + L_tmp1 = L_mac0_sat(L_tmp1, x[i], y[i]); + L_tmp2 = L_mac0_sat(L_tmp2, x[i + 1], y[i + 1]); + } + tcorr = L_add(L_shr_pos(L_tmp1, 1), L_shr_pos(L_tmp2, 1)); + Q_corr = norm_l(tcorr); + tcorr = L_shl(tcorr, Q_corr); + Q_corr = sub(2, Q_corr); + + L_tmp1 = L_deposit_l(0); + L_tmp2 = L_deposit_l(0); + FOR (i = 0; i < lg; i += 2) + { + L_tmp1 = L_mac0_sat(L_tmp1, y[i], y[i]); + L_tmp2 = L_mac0_sat(L_tmp2, y[i + 1], y[i + 1]); + } + tener = L_add(L_shr_pos(L_tmp1, 1), L_shr_pos(L_tmp2, 1)); + Q_ener = norm_l(tener); + tener = L_shl(tener, Q_ener); + Q_ener = sub(2, Q_ener); + + tener = L_max(tener, 1); + + if (tcorr <= 0) + { + negative = 1; move16(); + } + tcorr = L_abs(tcorr); + + m_corr = extract_h(tcorr); + + m_ener = extract_h(tener); + + IF (sub(m_corr, m_ener) > 0) + { + m_corr = shr_pos(m_corr, 1); + Q_corr = add(Q_corr, 1); + } + if (m_ener == 0) + { + move16(); + m_corr = 0x7FFF; + } + if (m_ener != 0) + { + m_corr = div_s(m_corr, m_ener); + } + + Q_corr = sub(Q_corr, Q_ener); + + Lgain = L_shl(L_deposit_l(m_corr), add(Q_corr, 1)); + + if (negative != 0) + { + Lgain = L_negate(Lgain); + } + + Dyn_Mem_Deluxe_Out(); + + return Lgain; +} + +/* + * TDC_LPC_synthesis_fx + * + * Parameters: + * sh i : scaling to apply for a[0] Q0 + * a[] i : LP filter coefficients Qx + * x[] i : input signal Qx + * y[] o : output signal Qx-s + * lg i : size of filtering Q0 + * m i : order of LP filter Q0 + * + * Function: + * Apply LP filtering to obtain synthesis signal. + * Memory size is always m. + * + * Returns: + * void + */ +static void TDC_LPC_synthesis_fx(const Word16 sh, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg, + const Word16 m) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word16 a0; + Word16 q; + Word32(*syn_kern)(Word32 L_tmp, const Word16 a[], const Word16 y[] + );); + + ASSERT(m == 16 || m == 8); + + if (sub(m, 16) == 0) + { + syn_kern = syn_kern_16; + } + if (sub(m, 8) == 0) + { + syn_kern = syn_kern_8; + } + + q = add(norm_s(a[0]), 1); + a0 = shr_sat(a[0], sh); + + FOR (i = 0; i < lg; i++) + { + y[i] = round_fx_sat(L_shl_sat(syn_kern(L_mult(a0, x[i]), a, &y[i]), q)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/* TDC_LPC_residu_fx + * + * Parameters: + * a I: LP filter coefficients (Qx) + * x I: input signal + * y O: output signal + * lg I: size of filtering + * m I: lpc order + * + * Function: + * Apply inverse filtering to obtain LP residual signal. + * + * Returns: + * void + */ +static void TDC_LPC_residu_fx(const Word16 *a, Word16 *x, Word16 *y, Word16 lg, Word16 m) +{ + Dyn_Mem_Deluxe_In( + Word16 a_exp; + Word32 s; + Counter i; + ); + + ASSERT(m == 16 || m == 8); + + a_exp = add(norm_s(a[0]), 1); + a_exp = add(a_exp, 1); + + IF (sub(m, 16) == 0) + { + FOR (i = 0; i < lg; i++) + { + s = L_mult(x[i], a[0]); + s = L_mac_sat(s, x[i - 1], a[1]); + s = L_mac_sat(s, x[i - 2], a[2]); + s = L_mac_sat(s, x[i - 3], a[3]); + s = L_mac_sat(s, x[i - 4], a[4]); + s = L_mac_sat(s, x[i - 5], a[5]); + s = L_mac_sat(s, x[i - 6], a[6]); + s = L_mac_sat(s, x[i - 7], a[7]); + s = L_mac_sat(s, x[i - 8], a[8]); + s = L_mac_sat(s, x[i - 9], a[9]); + s = L_mac_sat(s, x[i - 10], a[10]); + s = L_mac_sat(s, x[i - 11], a[11]); + s = L_mac_sat(s, x[i - 12], a[12]); + s = L_mac_sat(s, x[i - 13], a[13]); + s = L_mac_sat(s, x[i - 14], a[14]); + s = L_mac_sat(s, x[i - 15], a[15]); + s = L_mac_sat(s, x[i - 16], a[16]); + + s = L_shl_sat(s, a_exp); + y[i] = round_fx_sat(s); move16(); + } + } + IF (sub(m, 8) == 0) + { + FOR (i = 0; i < lg; i++) + { + s = L_mult(x[i], a[0]); + s = L_mac_sat(s, x[i - 1], a[1]); + s = L_mac_sat(s, x[i - 2], a[2]); + s = L_mac_sat(s, x[i - 3], a[3]); + s = L_mac_sat(s, x[i - 4], a[4]); + s = L_mac_sat(s, x[i - 5], a[5]); + s = L_mac_sat(s, x[i - 6], a[6]); + s = L_mac_sat(s, x[i - 7], a[7]); + s = L_mac_sat(s, x[i - 8], a[8]); + + s = L_shl_sat(s, a_exp); + y[i] = round_fx_sat(s); move16(); + } + } + + Dyn_Mem_Deluxe_Out(); +} + +/* TDC_random_fx + * + * Parameters: + * seed i/o: seed for random number + * lg i : vector length + * y o : output values + * + * Function: + * Uniform distributed random generator. + * + * Returns: + * random number + */ +static void TDC_random_fx(Word16 *seed, Word16 lg, Word16 *y) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + FOR (i = 0; i < lg; i++) + { + *seed = extract_l(L_mac0(16831L, *seed, 12821)); + *y++ = *seed; move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/* + * TDC_preemph + * + * Parameters: + * x i/o: signal Qx + * fac i: preemphasis factor Q15 + * lg i: vector length + * + * Function: + * Filtering through 1 - fac z^-1 + * + * Returns: + * Q-factor + */ +static Word16 TDC_preemph(Word16 *x, const Word16 fac, const Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Word16 fac_sh, Q_max_value, Q_out; + Word32 max_val; + Counter i; + ); + + fac_sh = shr(fac, 3); + Q_max_value = 4096; move16(); + Q_out = 12; move16(); + + max_val = 0; move32(); + FOR (i = sub(lg, 1); i >= 0; i--) + { + max_val = L_max(L_abs(L_msu(L_mult(x[i], Q_max_value), x[i - 1], fac_sh)), max_val); + } + + IF (extract_h(max_val) != 0) + { + Q_out = s_min(s_max(sub(norm_s(extract_h(max_val)), 3), 0), 12); + } + + FOR (i = sub(lg, 1); i >= 0; i--) + { + x[i] = round_fx(L_shl(L_msu(L_mult(x[i], Q_max_value), x[i - 1], fac_sh), Q_out)); move16(); + } + + Dyn_Mem_Deluxe_Out(); + + return sub(Q_out, 2); +} + +/* + * TDC_deemph_fx + * + * Parameters: + * x i: input signal Qx + * y o: output signal Qx + * fac i: deemphasis factor Q15 + * lg i: size of filtering Q0 + * mem i: memory (x[-1]) + * + * Function: + * Filtering through 1/(1-fac z^-1) + * + * Returns: + * void + */ +static void TDC_deemph_fx(const Word16 *x, Word16 *y, const Word16 fac, const Word16 lg, const Word16 mem) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + y[0] = round_fx_sat(L_mac_sat(L_deposit_h(x[0]), mem, fac)); move16(); + FOR (i = 1; i < lg; i++) + { + y[i] = round_fx_sat(L_mac_sat(L_deposit_h(x[i]), y[i - 1], fac)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/* + * TDC_normalize_energy_fx + * + * Parameters: + * gain o: gain + * gain_exp o: exponent of gain + * x i: input signal + * lg i: length of input signal + * + * Function: + * Normalizes the energy. + * + * Returns: + * void + */ +static void TDC_normalize_energy_fx(Word16 *gain, Word16 *gain_exp, const Word16 *x, const Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word16 c; + Word16 e; + Word16 e1; + Word16 e2; + Word32 tmp; + Word16 tmp16; + ); + + tmp = 0; move32(); + FOR (i = 0; i < lg; i++) + { + tmp16 = mult_r(x[i], 2048); + tmp = L_mac(tmp, tmp16, tmp16); + } + + e = norm_l(tmp); + tmp = L_shl_pos(tmp, e); + e1 = sub(sub(30, e), -8); move16(); + tmp16 = BASOP_Util_Divide3216_Scale_lc3plus(tmp, lg, &e2); + + e = 0; move16(); + if (tmp16 != 0) + { + e = sub(add(e1, e2), 15); + } + + c = 0x0148; /* 0.01 */ + move16(); + IF (e > 0) + { + c = shr(c, s_min(e, 15)); + } + ELSE + { + tmp16 = shr(tmp16, s_min(negate(e), 15)); + e = 0; move16(); + } + + e2 = 2; move16(); + if (s_and(e, 1)) + { + e2 = 1; move16(); + } + + tmp16 = add(shr_pos(tmp16, e2), shr_pos(c, e2)); + e = add(e, e2); + + tmp16 = Sqrt16_lc3plus(tmp16, &e); + + *gain = BASOP_Util_Divide1616_Scale_lc3plus((Word16)0x7FFF, tmp16, &e1); move16(); + *gain_exp = sub(e1, e); move16(); + + Dyn_Mem_Deluxe_Out(); +} + +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +static Word16 type_2_alpha_long(Word16 nbLostFramesInRow, Word16 frame_dms) +{ + Word16 n_help; + Word32 n_shift; + + if (nbLostFramesInRow <= 3*(100.0/frame_dms)){ + n_help = (nbLostFramesInRow + (100/frame_dms) - 1) * frame_dms; + return powWord16rest(31129,n_help/100,n_help%100); + } + else { + n_shift = (nbLostFramesInRow - 3*(100/frame_dms)) * 50/frame_dms; + n_help = (n_shift + (100/frame_dms) - 1) * frame_dms; + return powWord16rest(22937,n_help/100,n_help%100); + } +} + +Word16 type_2_fadeout_fx(Word16 nbLostFramesInRow, Word16 frame_dms) +{ + Word16 n_help; + Word16 selector = PLC_FADEOUT_TYPE_2_SELECTOR * 2 * (100/frame_dms); + + if (selector >= nbLostFramesInRow){ + return type_2_alpha_long(nbLostFramesInRow, frame_dms); + } + else { + n_help = (nbLostFramesInRow + (100/frame_dms) - 1) * frame_dms; + return powWord16rest(16383,n_help/100, n_help%100); + } +} + +static Word16 powWord16rest(Word16 base, Word16 exp, Word16 rest) { + Word32 exp_result = 32767; + Word32 tmp_result; + Word16 root, i, exp2; + + FOR (i = 0; i < exp; ++i) { + tmp_result = (Word32)exp_result * base; + exp_result = (Word16)(tmp_result >> 15); + } + + IF (rest != 0) { + exp2 = 0; + SWITCH (rest) + { + case 50: + root = Sqrt16_lc3plus(base, &exp2); + shr(root,exp2); + exp_result = L_shr(exp_result * root,15); /* 0.5^1.5 = 0.5^(3/2) = 0.5^3*sqrt(0.5) */ + BREAK; + case 25: + root = Sqrt16_lc3plus(base, &exp2); + shr(root,exp2); + exp2 = 0; + root = Sqrt16_lc3plus(root, &exp2); + shr(root,exp2); + exp_result = L_shr(exp_result * root,15); /* 0.5^(1/4) = 0.5^sqrt(sqrt(0.5)) */ + BREAK; + case 75: + root = Sqrt16_lc3plus(base, &exp2); + shr(root,exp2); + exp2 = 0; + root = Sqrt16_lc3plus(root, &exp2); + shr(root,exp2); + tmp_result = powWord16rest(root, 3, 0); + exp_result = L_shr( exp_result * tmp_result,15); + BREAK; + } + } + return (Word16) exp_result; +} +#endif diff --git a/lib_lc3plus/plc_tdc_pre_emphasis_fx.c b/lib_lc3plus/plc_tdc_pre_emphasis_fx.c new file mode 100644 index 000000000..3a961acf7 --- /dev/null +++ b/lib_lc3plus/plc_tdc_pre_emphasis_fx.c @@ -0,0 +1,95 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +void processPreEmphasis_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 frame_dms, Word8 *scratchBuffer) +{ + Word16 s; + Word32 nrg; + Word16 smax; + Counter band; + const Word16 *pre_emph; + const Word16 *pre_emph_e; + Word16 * d2_band_fx_exp; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processPreEmphasis_fx", sizeof(struct { + Word16 s; + Word32 nrg; + Word16 smax; + Counter band; + const Word16 *pre_emph; + const Word16 *pre_emph_e; + Word16 * d2_band_fx_exp; + })); +#endif + + d2_band_fx_exp = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER_PLC = 160 bytes */ + + pre_emph = lpc_lin_pre_emphasis[fs_idx]; + pre_emph_e = lpc_lin_pre_emphasis_e[fs_idx]; + SWITCH (frame_dms) + { + case 25: + pre_emph = lpc_lin_pre_emphasis_2_5ms[fs_idx]; + pre_emph_e = lpc_lin_pre_emphasis_e_2_5ms[fs_idx]; + BREAK; + case 50: + pre_emph = lpc_lin_pre_emphasis_5ms[fs_idx]; + pre_emph_e = lpc_lin_pre_emphasis_e_5ms[fs_idx]; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + pre_emph = lpc_lin_pre_emphasis_7_5ms[fs_idx]; + pre_emph_e = lpc_lin_pre_emphasis_e_7_5ms[fs_idx]; + BREAK; +#endif + } + + ASSERT(n_bands==20 || n_bands==40 || n_bands==60 || n_bands ==80); + + /* start processing */ + smax = -31; move16(); + + FOR (band = 0; band < n_bands; band++) + { + nrg = Mpy_32_16_lc3plus(d2_fx[band], pre_emph[band]); + + if (nrg == 0) + { + s = 31; move16(); + } + + if (nrg != 0) + { + s = norm_l(nrg); + } + + d2_fx[band] = L_shl_pos(nrg, s); move32(); + d2_band_fx_exp[band] = sub(pre_emph_e[band], s); move16(); + + smax = s_max(smax, d2_band_fx_exp[band]); + } + +/* Rescale band energies */ + FOR (band = 0; band < n_bands; band++) + { + d2_fx[band] = L_shr_pos(d2_fx[band], s_min(sub(smax, d2_band_fx_exp[band]), 31)); move32(); + } + /* Save common exponent for all bands */ + *d2_fx_exp = add(*d2_fx_exp, smax); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_tdc_tdac.c b/lib_lc3plus/plc_tdc_tdac.c deleted file mode 100644 index 596c23db0..000000000 --- a/lib_lc3plus/plc_tdc_tdac.c +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processTdcTdac_fl(const LC3_FLOAT *synth_inp, const LC3_FLOAT *win, LC3_INT32 frame_length, LC3_INT32 la_zeroes, LC3_FLOAT *ola_mem) -{ - LC3_INT32 i, L, LD2, NZ, synth_len; - LC3_FLOAT synth[(MAX_LEN + MDCT_MEM_LEN_MAX)], *synth1, *synth2, *ola_mem1, *ola_mem2, sz; - const LC3_FLOAT *win1, *win2, *win3, *win4; - - assert(la_zeroes <= frame_length / 2); - - L = frame_length; - LD2 = L/2; - NZ = LD2 - la_zeroes; - synth_len = 2*L - la_zeroes; - - move_float(synth, synth_inp, synth_len); - - /* calculate x_ov[L+la_zeroes] ... x_ov[2*L-1] */ - win1 = &win[L + LD2 - 1]; - win2 = &win[L + LD2]; - - win3 = &win[LD2 - 1]; - win4 = &win[LD2]; - - synth1 = &synth[L + LD2 - 1 - la_zeroes]; - synth2 = &synth[L + LD2 - la_zeroes]; - - ola_mem1 = &ola_mem[LD2 - la_zeroes]; - ola_mem2 = &ola_mem[LD2 - la_zeroes - 1]; - - for (i = 0; i < NZ; i++) - { - /* analysis windowing + 2N -> N */ - sz = *synth1 * *win1 + *synth2 * *win2; - - /* N -> 2N + synthesis windowing */ - *ola_mem1 = sz * *win3; - *ola_mem2 = sz * *win4; - - /* pointer update */ - win1--; - win2++; - win3--; - win4++; - synth1--; - synth2++; - ola_mem1++; - ola_mem2--; - } - - for (; i < LD2; i++) - { - /* analysis windowing + 2N -> N */ - sz = *synth1 * *win1; - - /* N -> 2N + synthesis windowing */ - *ola_mem1 = sz * *win3; - - /* pointer update */ - win1--; - win2++; - win3--; - synth1--; - synth2++; - ola_mem1++; - } -} - diff --git a/lib_lc3plus/plc_update.c b/lib_lc3plus/plc_update.c deleted file mode 100644 index 40520fb25..000000000 --- a/lib_lc3plus/plc_update.c +++ /dev/null @@ -1,126 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processPlcUpdate_fl(PlcAdvSetup *PlcAdvSetup, LC3_INT32 frame_length, LC3_FLOAT *syntM, LC3_FLOAT *scf_q, - LC3_INT32 *nbLostCmpt, LC3_FLOAT *cum_alpha, LC3_INT32 bfi, LC3_INT32 *prevBfi, LC3_INT32 *prevprevBfi) -{ - LC3_FLOAT tmp[MAX_LEN_PCM_PLC]; - - move_float(tmp, &PlcAdvSetup->pcmbufHist[frame_length], PlcAdvSetup->max_len_pcm_plc - frame_length); - move_float(&PlcAdvSetup->pcmbufHist[0], tmp, PlcAdvSetup->max_len_pcm_plc - frame_length); - move_float(&PlcAdvSetup->pcmbufHist[PlcAdvSetup->max_len_pcm_plc - frame_length], syntM, frame_length); - - if (bfi != 1) - { - *nbLostCmpt = 0; - *cum_alpha = 1; - - if (PlcAdvSetup) - { - move_float(PlcAdvSetup->scf_q_old_old, PlcAdvSetup->scf_q_old, M); - move_float(PlcAdvSetup->scf_q_old, scf_q, M); - /* PLC fullband transient detector setting for non-bfi frames */ - PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev = 0; /* fullband transient not active */ - } - } - - *prevprevBfi = *prevBfi; - *prevBfi = bfi; -} - -void plc_phEcu_processPLCspec2shape(LC3_INT16 prev_bfi, LC3_INT16 bfi, LC3_FLOAT q_d[], LC3_INT32 yLen, - LC3_FLOAT *stPhECU_oold_grp_shape, LC3_FLOAT *stPhECU_old_grp_shape) -{ - LC3_INT32 i, j, N_grp; - LC3_INT32 local_prev_bfi; - LC3_INT32 fs_idx; - LC3_FLOAT E_tot = 0.0; - LC3_INT32 l_grp; - LC3_FLOAT *pX; - - if (bfi != 1) /* compute only for bfi== 0 or 2 */ - { - fs_idx = (LC3_INT32)floor(yLen / 100); - assert(fs_idx < 5); - N_grp = xavg_N_grp[fs_idx]; - - local_prev_bfi = prev_bfi; - if (local_prev_bfi == 2) { - local_prev_bfi = 0; - } - - - /* Copy old to oold grp shape */ - for (i = 0; i < MAX_LGW; i++) - { - stPhECU_oold_grp_shape[i] = stPhECU_old_grp_shape[i]; - } - - /* Accumulate DC-coupled bins to total */ - E_tot = 0; - pX = q_d; /* ptr setup */ - for (i = 0; i < mdct_grp_bins[0]; i++) - { - E_tot += sqrf( *pX ); - pX++; - } - - /* Accumulate middle grps and add to total */ - for (i = 0; i < (N_grp - 1); i++) - { - l_grp = mdct_grp_bins[i + 1] - mdct_grp_bins[i]; ; - stPhECU_old_grp_shape[i] = 0.0; - for (j = 0; j < l_grp; j++) { - stPhECU_old_grp_shape[i] += sqrf( *pX ); - pX++; - } - E_tot += stPhECU_old_grp_shape[i]; - } - - /* Accumulate last subbband and add to total */ - stPhECU_old_grp_shape[(N_grp - 1)] = 0.0; - l_grp = mdct_grp_bins[N_grp] - mdct_grp_bins[N_grp - 1] - mdct_grp_bins[0]; - assert( (mdct_grp_bins[N_grp] - mdct_grp_bins[0]) <= yLen); - for (j = 0; j < l_grp; j++) - { - stPhECU_old_grp_shape[(N_grp - 1)] += sqrf( *pX ); - pX++; - } - E_tot += stPhECU_old_grp_shape[(N_grp - 1)]; - - - /* Normalize shape */ - for (i = 0; i < (N_grp); i++) { - if (E_tot > 0.0) { - stPhECU_old_grp_shape[i] /= E_tot; - } - else - { - stPhECU_old_grp_shape[i] = 0.0; - } - } - if (local_prev_bfi == 1) { - for (i = 0; i < MAX_LGW; i++) { - stPhECU_oold_grp_shape[i] = stPhECU_old_grp_shape[i]; - } - } - }/*bfi*/ - return; -} - -void processPlcUpdateSpec_fl(LC3_FLOAT *q_d_prev, LC3_FLOAT *q_d_fl_c, LC3_INT32 yLen) -{ - move_float(q_d_prev, q_d_fl_c, yLen); -} - diff --git a/lib_lc3plus/plc_update_aft_imdct_fx.c b/lib_lc3plus/plc_update_aft_imdct_fx.c new file mode 100644 index 000000000..663f491c9 --- /dev/null +++ b/lib_lc3plus/plc_update_aft_imdct_fx.c @@ -0,0 +1,343 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +static void processPLCcomputeStabFac(Word16 scf_q[], Word16 old_scf_q[], Word16 prev_bfi, Word16 *stab_fac); + +void processPLCUpdateAfterIMDCT_fx(Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 xLen, Word16 fs_idx, + Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, Word16 scf_q[], + Word16 *ns_cum_alpha, AplcSetup *plcAd) +{ + Word16 oldLen, usedHistlen; + Word16 scale_fac_old, scale_fac_new, q_theo_new_old, q_theo_new_new, q_new, shift_old, shift_new; + Word16 frontLen, pastLen; + Word16 marginOldPast; + Word16 marginNewXlen, marginOldFront; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processPLCUpdateAfterIMDCT_fx", sizeof(struct { + Word16 oldLen, usedHistlen; + Counter i; + Word16 scale_fac_old, scale_fac_new, q_theo_new_old, q_theo_new_new, q_new, shift_old, shift_new; + Word16 frontLen, pastLen; + Word16 marginOldPast; + Word16 scale_fac_old_dual; + Word16 marginNewXlen, marginOldFront; + })); +#endif + + + + +#ifdef WMOPS + BASOP_sub_sub_start("processPLCUpdateAfterIMDCT "); +#endif + + + if (plcAd) + { + /* for short NB frames(2.5 ms) TDC-filtering requires more PCM samples than the plc_xcorr function */ + usedHistlen = plcAd->max_len_pcm_plc; + + + logic16(); + IF( (sub(bfi,1) == 0) && sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0 && xLen == (Word16)(((double)LprotSzPtr[fs_idx])*0.625)) + { /* % reduced buffering update length during concealment method 2 as Xsav_fx is stored in the joint q_old_fx and pcmbufHist buffer */ + usedHistlen = sub(usedHistlen, sub(LprotSzPtr[fs_idx], s_min(MAX_BW_BIN, xLen))); + ASSERT(xLen == (Word16)(((double)LprotSzPtr[fs_idx])*0.625)); /*/ only enter here for 10 ms cases */ + + /* actually one can select to always update xLen(10 ms) less samples of x_old_tot, also in TDC-PLC bfi frames ,, and for PhECU.PLC */ + } + oldLen = sub(usedHistlen, xLen); + + /* update ltpf-free pcm history buffer for TD-PLC */ + + basop_memmove(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen], + &plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen + xLen], oldLen * sizeof(Word16)); + + basop_memcpy(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - xLen], &x_fx[0], xLen * sizeof(Word16)); + +#ifdef ENABLE_HR_MODE + frontLen = 0; + IF (sub(fs_idx, 5) < 0) +#endif + { + frontLen = sub(LprotSzPtr[fs_idx], xLen); /*16-10 = 6ms of the prev_synth/xfp part */ + } + pastLen = sub(oldLen, frontLen); /* ~11.8 ms*/ + + marginOldPast = getScaleFactor16_0(&(plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen]), pastLen); + marginOldFront = getScaleFactor16_0(&(plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen + pastLen]), frontLen); + + scale_fac_old = s_min(marginOldFront, marginOldPast); + + frontLen = 0; move16(); + logic16(); logic16(); + IF(bfi == 1 && *prev_bfi == 0 && sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0) + { /* prepare localized margin_xfp value for a next bad concealment Method 2 frame */ + frontLen = *nbLostFramesInRow; + frontLen = add(hamm_len2Tab[fs_idx], shr(hamm_len2Tab[fs_idx], 2)); /* find margin in the 3.75 ms front part */ + pastLen = sub(xLen, frontLen); + scale_fac_new = getScaleFactor16_0(&(x_fx[0]), pastLen); + marginNewXlen = getScaleFactor16_0(&(x_fx[0]) + pastLen, frontLen); /* for pHEcuprev_synth in 2nd+ bfi frame */ + + scale_fac_new = s_min(scale_fac_new, marginNewXlen); + } + ELSE + { /* prepare margin value for any coming good frame or any coming first bad frame */ + + marginNewXlen = getScaleFactor16_0(&(x_fx[0]),xLen); /* prevsynth in first bfi frame */ + scale_fac_new = marginNewXlen; move16(); + } + + q_theo_new_old = s_max(plcAd->q_fx_old_exp - scale_fac_old, 0); + q_theo_new_new = s_max(q_fx_exp - scale_fac_new, 0); + + q_new = s_max(q_theo_new_old, q_theo_new_new); + + shift_old = plcAd->q_fx_old_exp - q_new; + shift_new = q_fx_exp - q_new; + + IF(shift_old != 0) + { + Scale_sig(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen], oldLen, shift_old); + logic16(); + test(); + IF ((sub(bfi,1) == 0) && (sub(concealMethod, LC3_CON_TEC_TDPLC) == 0)) + { + plcAd->harmonicBuf_Q -= shift_old; + plcAd->tdc_gain_c = L_shl_sat(plcAd->tdc_gain_c, shift_old); + } + move16(); /* count move to static RAM */ + + marginOldFront = s_min(16, sub(marginOldFront, shift_old)); + } + IF(shift_new) + { + Scale_sig(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - xLen], xLen, shift_new); /* positive shift_new means upshift=less margin */ + marginNewXlen = s_min(16, sub(marginNewXlen, shift_new)); + } + + plcAd->q_fx_old_exp = sub(q_fx_exp, shift_new); + + plcAd->PhECU_margin_xfp = s_min(marginNewXlen, marginOldFront); move16(); /* for pHECU winEncalc xfp energy calculations */ + if (frontLen != 0) + { /* prepare margin value for a first pHECU(16 ms) or a consecutive bad PhEcu frame (3.75ms) */ + plcAd->PhECU_margin_xfp = marginNewXlen; move16(); + } + if (sub(plcAd->PhECU_margin_xfp, 16) == 0) + { + plcAd->PhECU_margin_xfp = 1; move16(); /* "1" --> does not rescale the all-zero vector, inside PhECU */ + } + } + + /* Update PLC params */ + IF(sub(bfi, 1) != 0) + { + /* % reset counters in GF */ + *nbLostFramesInRow = 0; move16(); + *ns_cum_alpha = 32767; move16(); + + if (plcAd) + { + basop_memmove(plcAd->old_old_scf_q, plcAd->old_scf_q, M * sizeof(Word16)); + basop_memmove(plcAd->old_scf_q, scf_q, M * sizeof(Word16)); + + /* PLC fullband transient detector setting for non-bfi frames */ + plcAd->PhECU_short_flag_prev = 0; move16(); /* fullband transient not active */ + } + } + + /* values may be {0,1,2} */ + *prev_prev_bfi = *prev_bfi; move16(); + *prev_bfi = bfi; move16(); + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +void processPLCcomputeStabFac_main(Word16 scf_q[], Word16 old_scf_q[], Word16 old_old_scf_q[], Word16 bfi, Word16 prev_bfi, + Word16 prev_prev_bfi, Word16 *stab_fac) +{ + IF (sub(bfi, 1) == 0) + { + IF (sub(prev_bfi, 1) != 0) + { + processPLCcomputeStabFac(old_scf_q, old_old_scf_q, prev_prev_bfi, stab_fac); + } + } + ELSE IF(sub(bfi, 2) == 0) + { + processPLCcomputeStabFac(scf_q, old_scf_q, prev_bfi, stab_fac); + } +} + +static void processPLCcomputeStabFac(Word16 scf_q[], Word16 old_scf_q[], Word16 prev_bfi, Word16 *stab_fac) +{ + Counter i; + Word32 tmp32; + Word16 d; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("calculateStabFac", sizeof(struct { + Counter i; + Word32 tmp32; + Word16 d; + })); +#endif + + /* calculate stability factor */ + IF (sub(prev_bfi, 1) == 0) + { + *stab_fac = 26214; move16(); + } + ELSE + { + tmp32 = 0; move32(); + FOR (i = 0; i < M; i++) + { + d = sub(scf_q[i], old_scf_q[i]); + tmp32 = L_mac_sat(tmp32, d, d); + } + tmp32 = L_shl_sat(tmp32, 3); + IF (tmp32 > 0x7D000000 /*1.25*25*/) + { + *stab_fac = 0; move16(); + } + ELSE IF (tmp32 < 0x19003E82 /*0.25*25*/) + { + *stab_fac = 0x7FFF; move16(); + } + ELSE + { + tmp32 = L_shl_pos(L_sub(0x50000000 /*1.25/2*/, Mpy_32_16_lc3plus(tmp32, 0x51EC /*16/25*/)), 1); + *stab_fac = round_fx(tmp32); move16(); + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +void processPLCUpdateXFP_w_E_hist_fx(Word16 prev_bfi, Word16 bfi, Word16 *xfp_fx, Word16 xfp_exp_fx, Word16 margin_xfp, + Word16 fs_idx, + Word32 *L_oold_xfp_w_E_fx, Word16 *oold_xfp_w_E_exp_fx, + Word32 *L_old_xfp_w_E_fx, Word16 *old_xfp_w_E_exp_fx, + + Word16 *oold_Ltot_exp_fx ,Word16 *old_Ltot_exp_fx ) + +{ + Word32 L_tot ; + Word16 dn_scale, exp_shift; + Word16 used_xfp_exp_fx; + Word16 exp_out ; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("PLCUpdateXFP_w_E_hist", sizeof(struct { + Word32 L_tot; + Word16 dn_scale, exp_shift; + Word16 used_xfp_exp_fx; + Word16 exp_out; + })); +#endif +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::UpdateXfp_w_E_hist_fx"); +#endif + + IF (sub(bfi,1) != 0) + { + + if (sub(prev_bfi,1) == 0) + { + /* only a single historic frame available in the next frame + , force artifical update of oold energy to be the same as old */ + *old_xfp_w_E_exp_fx = LTOT_INIT_FLAG ; move16(); + } + + /* Time shift energy state and xfp exp */ + IF (sub_sat(*old_xfp_w_E_exp_fx, LTOT_INIT_FLAG ) == 0) + { + *L_oold_xfp_w_E_fx = LTOT_MIN_MAN ; move32(); + *oold_xfp_w_E_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL ; move16(); + } + ELSE + { + *L_oold_xfp_w_E_fx = *L_old_xfp_w_E_fx; move32(); /* regular update */ + *oold_xfp_w_E_exp_fx = *old_xfp_w_E_exp_fx; move16(); + } + + /* Time shift L_tot energy state and L_tot_exp */ + IF (sub_sat(*old_Ltot_exp_fx, LTOT_INIT_FLAG ) == 0) + { + *L_oold_xfp_w_E_fx = LTOT_MIN_MAN ; move32(); + *oold_Ltot_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL ; move16(); + } + ELSE + { + *L_oold_xfp_w_E_fx = *L_old_xfp_w_E_fx; move32(); /* regular update */ + *oold_Ltot_exp_fx = *old_Ltot_exp_fx; move16(); + } + + + dn_scale = e_tot_headroom[fs_idx]; /* allowed minimum dn_scale for a max upshifted signal */ + used_xfp_exp_fx = xfp_exp_fx; + + IF( margin_xfp > 0 ) /* xfp_fx was normalized on a larger area than 16ms part of pcmBuffer */ + { + ASSERT(bfi !=1) ; /* if bfi was set the margin_xfp does not reflect the correct 16ms part of pcm_buf hist, prev_synth */ + dn_scale = s_max(0, sub(e_tot_headroom[fs_idx], margin_xfp)); + + exp_shift = sub(e_tot_headroom[fs_idx], dn_scale); + used_xfp_exp_fx = sub(xfp_exp_fx, exp_shift); /* the virtual change of the xfp_buffer due to reduced downscaling in L_tot calc */ + } + + /* use semifixed dn_scale as adjusted by margin_xfp in 16 ms region */ + exp_out = xfp_exp_fx; move16(); + L_tot = winEnCalc(xfp_fx, dn_scale , PhECU_wins[fs_idx][0], rectLengthTab[fs_idx], hamm_len2Tab[fs_idx], &exp_out ); + + *L_old_xfp_w_E_fx = L_tot; move32(); + + *old_xfp_w_E_exp_fx = used_xfp_exp_fx ; move16(); + /* this now needs to be in Q1 , used_fx_exp , (exp_out-1-2*e_tot_headroom[fs_idx])/2 */ + + *old_Ltot_exp_fx = exp_out; /* new proper _Ltot value from winEnCalc function */ + + + /* use true Word32 exponent of L_tot */ + + + /* restart oold and old from same state for init or prevBFI cases */ + logic16(); + IF (sub_sat(*oold_xfp_w_E_exp_fx, UNINIT_OR_UNSAFE_OOLD_SENTINEL) <= 0 || /* old xfp_Exp */ + sub_sat(*oold_Ltot_exp_fx, UNINIT_OR_UNSAFE_OOLD_SENTINEL) <= 0 ) /* new L_tot_exp */ + { + *L_oold_xfp_w_E_fx = L_tot; move32(); + *oold_xfp_w_E_exp_fx = used_xfp_exp_fx; move16(); + *oold_Ltot_exp_fx = *old_Ltot_exp_fx; /* use Ltot exp value */ + } + } + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + + diff --git a/lib_lc3plus/plc_update_fx.c b/lib_lc3plus/plc_update_fx.c new file mode 100644 index 000000000..fb05770d5 --- /dev/null +++ b/lib_lc3plus/plc_update_fx.c @@ -0,0 +1,224 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +void processPLCupdate_fx(AplcSetup *plcAd, Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 frame_length, + Word16 fs_idx, Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, Word16 scf_q[], + Word16 *ns_cum_alpha +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + ) +{ + processPLCUpdateAfterIMDCT_fx(x_fx, q_fx_exp, concealMethod, frame_length, fs_idx, nbLostFramesInRow, prev_prev_bfi, prev_bfi, bfi, + scf_q, ns_cum_alpha, plcAd); /* NB *prev_bfi updated here */ + + IF ( plcAd != 0 ) + { + /* reuse/inplace the most recent 16 ms of x_old_tot without additional rescaling, keep exponent aligned with tdc pitch buffer to save WMOPS */ + + +#ifdef ENABLE_HR_MODE + if (hrmode == 0) +#endif + { + ASSERT( (&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - LprotSzPtr[fs_idx] ]) == plcAd->PhECU_xfp_fx ); + plcAd->PhECU_xfp_exp_fx = plcAd->q_fx_old_exp; move16(); /* exponent used by concealmethod 2 in prevBfi frames and also right after non bfi frames */ + } + } +} + +void processPLCupdateSpec_fx(Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], Word16 *q_fx_exp, Word16 yLen) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word16 s; + ); + + /* save spectrum and the corresponding exponent */ + s = getScaleFactor32_lc3plus(q_d_fx, yLen); + + *q_old_fx_exp = sub(*q_fx_exp, s); + + + FOR (i = 0; i < yLen; i++) + { + q_old_d_fx[i] = round_fx_sat(L_shl_sat(q_d_fx[i], s)); /* */ + } + + Dyn_Mem_Deluxe_Out(); +} + +void processPLCspec2shape_fx(Word16 prev_bfi, Word16 bfi, Word16 q_old_d_fx[], Word16 yLen, + Word16 *stPhECU_oold_grp_shape_fx, Word16 *stPhECU_old_grp_shape_fx) + +#define L_GRP_DC 4 + +{ + Counter i,l; + Word16 *pX, tmp; + Word16 N_grp,l_grp; + Word16 man, expo; + Word32 L_acc; + Word32 L_tot; + Word32 L_grp_shape[MAX_LGW]; + Word16 grp_shape[MAX_LGW]; /**/ + Word16 fs_idx,local_prev_bfi; + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("process_plc_spec_2_shape_fx", sizeof(struct { + Counter i,l; + Word16 *pX; + Word16 N_grp,l_grp; + Word32 L_acc; + Word32 L_tot; + Word32 L_grp_shape[MAX_LGW]; + Word16 fs_idx,local_prev_bfi; + })); +#endif +#ifdef WMOPS + BASOP_sub_sub_start("PhECU::GF::process_plc_spec_2_shape_fx"); +#endif + + IF(sub(bfi, 1) != 0) + { + fs_idx = mult(yLen, (Word16)(32768.0 / (99.0))); /* truncation needed , i.e no rounding can be applied here */ + N_grp = xavg_N_grp_fx[fs_idx]; move16(); + + local_prev_bfi = prev_bfi; move16(); + if (sub(local_prev_bfi, 2)==0) + { + local_prev_bfi = 0; move16(); + } + + if( stPhECU_oold_grp_shape_fx[0] < 0 ) + { + local_prev_bfi = 1 ; move16(); /* handle startup in the case 2nd frame is a BFI frame */ + } + + /* Copy old to oold grp shape */ + FOR( i=0; i < MAX_LGW ; i++) + { + stPhECU_oold_grp_shape_fx[i] = stPhECU_old_grp_shape_fx[i]; move16(); + } + + + /* Accumulate DC bin(s) to total */ + pX = q_old_d_fx; /* ptr setup */ + L_tot = L_deposit_h(0); /* acc on negative side */ + + FOR( i= 0; i < L_GRP_DC; i++) + { + tmp = shr_pos(*pX++ ,spec_shape_headroom[fs_idx]); /* scale down upscaled MDCT to create some headroom */ + L_tot = L_msu0(L_tot, tmp, tmp); + + } + + /* Accumulate middle subbands and add to total */ + FOR( i=0; i < sub(N_grp,1) ; i++) + { + + L_acc = L_deposit_h(0); /* acc on negative side */ + l_grp = sub(mdct_grp_bins_fx[i+1], mdct_grp_bins_fx[i]); move16(); + + + + FOR(l=0;l 0) + { + FOR(i=0; i < N_grp ; i++) + { + man = plc_phEcu_ratio_fx(L_grp_shape[i], L_tot, &expo); /* The mantissa is considered in Q15 output in Q14 */ + grp_shape[i] = shr_sat(man, sub(expo,1)); /* gfrom Q14 to in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */ + } + } + ELSE + { + FOR(i=0; i < N_grp ; i++) + { + grp_shape[i] = GRP_SHAPE_INIT; move16(); + + } + } + + /* copy to output */ + FOR(i=0; i < N_grp ; i++) + { + stPhECU_old_grp_shape_fx[i] = grp_shape[i]; move16(); + } + FOR(i = N_grp; i < MAX_LGW ; i++) + { + stPhECU_old_grp_shape_fx[i] = GRP_SHAPE_INIT; move16(); + } + + + + /* handle oold states for the frame sequence BAD, GOOD, NEXT_BAD */ + if(sub(local_prev_bfi, 1)==0) + { + FOR( i=0; i < MAX_LGW ; i++) + { + stPhECU_oold_grp_shape_fx[i] = stPhECU_old_grp_shape_fx[i] ; move16(); + } + } + + } + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + +} + + + + diff --git a/lib_lc3plus/plc_xcorr_fx.c b/lib_lc3plus/plc_xcorr_fx.c new file mode 100644 index 000000000..720015295 --- /dev/null +++ b/lib_lc3plus/plc_xcorr_fx.c @@ -0,0 +1,250 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" +#include "functions.h" + +#define MAX_ACCS 3 /* sum(x.*y), sum(x.*x), sum(y.*y), nb of always nonsaturated shorter sub_blocks*/ +#define MAX_BLOCKS 8 +#define MAX_ACC_LEN_BITS 7 +#define MIN_ACC_LEN_BITS 5 +#define MAX_ACC_LEN (1 << MAX_ACC_LEN_BITS) +#define MIN_PITCH_8K 20 /* 8000* MIN_PITCH_12k8/12800 */ + +static const Word16 pitch_min_2[] = {2 * MIN_PITCH_8K , 2 * MIN_PITCH_8K * 2, 2 * MIN_PITCH_8K * 3, + 2 * MIN_PITCH_8K * 4, 2 * MIN_PITCH_8K * 6, 2 * MIN_PITCH_8K * 12}; + +/* req headroom in bits, for safe summing of block results w/o downshift */ +/* also the safe pre subblock acc downshift for various number of blocks */ +static const Word16 tab_req_headroom[MAX_BLOCKS + 1] = {0, 0, 1, 2, 2, 3, 3, 3, 3}; +/*(0, 1, 2, 3,4, 5,6,7,8)*/ + +static Word16 plc_norm_corr_blocks_fx(Word16 tot_len, Word16 l2_base_len, Word16 n_blocks, Word16 inshift, + Word16 *currFrame, Word16 *predFrame); + +Word16 plc_norm_corr_blocks_fx( /* o: norm_corr range [-1 ... 1.0[ in Q15 */ + Word16 tot_len, /* i: total correlation length in Q0 */ + Word16 l2_base_len, /* i: size of subblocks in log2 */ + Word16 n_blocks, /* i: number of accumulator sub_blocks */ + Word16 inshift, /* i: required inshift of curr/pred Q0 */ + Word16 *currFrame, /* i: ptr to most recent section */ + Word16 *predFrame) /* i: ptr to historic section */ +{ + Word16 scale0, scale1, scale2, scale_min, shift, prod_exp, acc_margin; + Word32 L_prod, L_inv, L_tmp0 = 0, L_tmp1 = 0, L_tmp2 = 0; + Word16 norm_corr, curr, pred; + Counter m, b; + Word32 L_ce[MAX_ACCS][MAX_BLOCKS]; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_norm_corr_blocks_fx", sizeof(struct { + Word16 scale0, scale1, scale2, scale_min, shift, prod_exp, acc_margin; + Word32 L_prod, L_inv, L_tmp0, L_tmp1, L_tmp2; + Word16 norm_corr, curr, pred; + Counter m, b; + Word32 L_ce[MAX_ACCS][MAX_BLOCKS]; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("plc_norm_corr_blocks_fx"); +#endif + + /* Calculate normalized correlation with added shift and block interleaving possibility */ + ASSERT(n_blocks <= MAX_BLOCKS && n_blocks > 0); + ASSERT(((float)tot_len / (float)n_blocks) <= (float)(1 << l2_base_len)); + ASSERT(inshift > 0); + UNUSED(l2_base_len); + + FOR (b = 0; b < n_blocks; b++) + { /* block loop with fixed pre_down shifting(inshift) of input signal */ + curr = shr_pos(currFrame[b], inshift); + pred = shr_pos(predFrame[b], inshift); + L_tmp2 = L_deposit_l(0); + L_tmp0 = L_msu0(L_tmp2, curr, pred); /* acc L_tmp0 on negative side to avoid saturation for (-1*-1) */ + L_tmp1 = L_msu0(L_tmp2, pred, pred); /* acc_energy on negative side */ + L_tmp2 = L_msu0(L_tmp2, curr, curr); /* acc_energy on negative side */ + + FOR (m = (b + n_blocks); m < tot_len; m += n_blocks) + { /* interleaved accumulation over total length */ + curr = shr_pos(currFrame[m], inshift); + pred = shr_pos(predFrame[m], inshift); + L_tmp0 = L_msu0(L_tmp0, curr, pred); + L_tmp1 = L_msu0(L_tmp1, pred, pred); + L_tmp2 = L_msu0(L_tmp2, curr, curr); + } + + L_ce[0][b] = L_add(L_tmp0, 0); /* account for moves from register to stack memory */ + L_ce[1][b] = L_add(L_tmp1, 0); + L_ce[2][b] = L_add(L_tmp2, 0); + } + + /* aggregate interleaved subsections */ + IF (sub(n_blocks, 1) >= 0) + { /* 100% safe non saturating L_ce with a safe acc_margin */ + acc_margin = tab_req_headroom[n_blocks]; move16(); + + L_tmp0 = L_shr_pos(L_ce[0][0], acc_margin); + L_tmp1 = L_shr_pos(L_ce[1][0], acc_margin); + L_tmp2 = L_shr_pos(L_ce[2][0], acc_margin); + + FOR (b = 1; b < n_blocks; b++) + { + L_tmp0 = L_add(L_tmp0, L_shr_pos(L_ce[0][b], acc_margin)); /* add negative values */ + L_tmp1 = L_add(L_tmp1, L_shr_pos(L_ce[1][b], acc_margin)); /* add negative values */ + L_tmp2 = L_add(L_tmp2, L_shr_pos(L_ce[2][b], acc_margin)); /* add negative values */ + } + + /* evaluate headroom margin in coarse representation */ + scale0 = norm_l(L_tmp0); + scale1 = norm_l(L_tmp1); + scale2 = norm_l(L_tmp2); + + scale_min = s_min(scale0, scale1); + scale_min = s_min(scale_min, scale2); + + shift = sub(scale_min, acc_margin); + IF (shift >= 0) + { /* re-accumulate blocks with highest possible precision */ + L_tmp0 = L_add(L_ce[0][0], 0); /* add negative values */ + L_tmp1 = L_add(L_ce[1][0], 0); /* add negative values */ + L_tmp2 = L_add(L_ce[2][0], 0); /* add negative values */ + + FOR (b = 1; b < n_blocks; b++) + { + L_tmp0 = L_add(L_tmp0, L_ce[0][b]); /* add negative values */ + L_tmp1 = L_add(L_tmp1, L_ce[1][b]); /* add negative values */ + L_tmp2 = L_add(L_tmp2, L_ce[2][b]); /* add negative values */ + } + } + } + + /* quota: norm_corr = corr/sqrt(en1*en2) = negate(L_tmp1)/sqrt(-L_tmp1*-L_tmp2) */ + L_tmp1 = L_min(L_tmp1, -1); /* make sure there is negative energy */ + L_tmp2 = L_min(L_tmp2, -1); /* make sure there is negative energy */ + + ASSERT(L_tmp1 < 0 && L_tmp2 < 0); + + /* negate correlation, due to the used safe msu0 accumulation, with a saturation pre-check ctrl */ + L_tmp0 = L_max(L_tmp0, (MIN_32 + 1)); + L_tmp0 = L_negate(L_tmp0); + + scale0 = norm_l(L_tmp0); + scale1 = norm_l(L_tmp1); + scale2 = norm_l(L_tmp2); + + L_tmp1 = L_shl_pos(L_tmp1, scale1); + L_tmp2 = L_shl_pos(L_tmp2, scale2); + L_prod = Mpy_32_32_lc3plus(L_tmp1, L_tmp2); /* neg * neg -> positive */ + shift = norm_l(L_prod); + L_prod = L_shl_pos(L_prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + L_inv = Isqrt(L_prod, &prod_exp); + + L_tmp0 = L_shl_pos(L_tmp0, scale0); + L_prod = Mpy_32_32_lc3plus(L_tmp0, L_inv); + prod_exp = add(sub(31, scale0), prod_exp); + + norm_corr = 32767; move16(); /* as close to 1.0 as possible in Q15 */ + if (L_tmp0 < 0) + { + norm_corr = -32768; move16(); /*-1.0*/ + } + + test(); + IF (L_prod == 0 || sub(norm_l(L_prod), prod_exp) >= 0) + { + norm_corr = round_fx_sat(L_shl_sat(L_prod, prod_exp)); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return norm_corr; +} + +Word16 plc_xcorr_lc_fx( /* o: quantized output xcorr in Q15 [ 0 ..32767 ] = [0. 1.0[ */ + Word16 *pcmbuf_fx, /* i: NB should be an already dynamically upscaled pcm buffer with about + 0...1(2) bits margin */ + Word16 max_len_pcm_plc, /* i: Q0 physical size of pcmbuf_fx */ + Word16 pitch_int, /* i: Q0 in Fs, lag value to evaluate, corresponding to the current f0 in + pcm_buf_Fx */ + Word16 fs_idx /*i: */) +{ + Word16 *range1Ptr; + Word16 *range2Ptr; + Word16 corr_len_fx, inshift, l2_base_len, n_blocks, norm_xcorr_est_q, pcm_max_corr_len, max_corr_len; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_xcorr_lc_fx", sizeof(struct { + Word16 *range1Ptr; + Word16 *range2Ptr; + Word16 corr_len_fx, inshift, l2_base_len, n_blocks, norm_xcorr_est_q, pcm_max_corr_len, max_corr_len; + })); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("plc_xcorr_lc_fx"); +#endif + + norm_xcorr_est_q = 0; move16(); + + IF (pitch_int > 0) + { + pcm_max_corr_len = sub(max_len_pcm_plc, pitch_int); + + max_corr_len = rectLengthTab[fs_idx]; /* maximum 10 ms */ + max_corr_len = s_min(max_corr_len, pcm_max_corr_len); + + corr_len_fx = s_min(max_corr_len, pitch_int); + corr_len_fx = s_max(corr_len_fx, pitch_min_2[fs_idx]); /* at least 5 ms (=2*pitchmin*) corr length */ + + ASSERT(corr_len_fx >= (pitch_min_2[fs_idx])); /* at least 2 x pitch min(fs) */ + ASSERT(corr_len_fx <= (MAX_ACC_LEN * MAX_BLOCKS)); + ASSERT(corr_len_fx <= max_corr_len); + ASSERT( max_len_pcm_plc - corr_len_fx - pitch_int + 1 > 0 ); + + range1Ptr = &(pcmbuf_fx[max_len_pcm_plc]) - corr_len_fx; /* ptr setup, start of head section */ + range2Ptr = range1Ptr - pitch_int; /* ptr setup, history = tail - lag distance */ + + /* assume 32 bit acc of up to 32 values -> sum(over 32, x_up>>2 * y_up>>2) */ + inshift = 2; move16(); + l2_base_len = MIN_ACC_LEN_BITS; move16(); + n_blocks = shr(add(corr_len_fx, (1 << MIN_ACC_LEN_BITS) - 1), MIN_ACC_LEN_BITS); + + IF (sub(n_blocks, MAX_BLOCKS) > 0) + { /* shift to 32 bit acc of up to 128 values -> sum(over 128, x_up>>3 * y_up>>3) */ + inshift = 3; move16(); + l2_base_len = MAX_ACC_LEN_BITS; move16(); + n_blocks = shr(add(corr_len_fx, ((1 << MAX_ACC_LEN_BITS) - 1)), MAX_ACC_LEN_BITS); + } + + ASSERT(n_blocks <= MAX_BLOCKS); /* MAX_BLOCKS*(32 or 128) is max possible total corr_length */ + ASSERT(n_blocks > 0); + + /* subblock accumulation of corr and energies, to achieve high low level precision */ + norm_xcorr_est_q = + plc_norm_corr_blocks_fx(corr_len_fx, l2_base_len, n_blocks, inshift, range1Ptr, /* curr_frame */ + range2Ptr); /* pred_frame = curr_frame-lag, i.e historic section */ + + norm_xcorr_est_q = s_max(0, norm_xcorr_est_q); /* do not allow negative output values */ + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + return norm_xcorr_est_q; +} + + diff --git a/lib_lc3plus/pvq_dec_fx.c b/lib_lc3plus/pvq_dec_fx.c new file mode 100644 index 000000000..d77aae809 --- /dev/null +++ b/lib_lc3plus/pvq_dec_fx.c @@ -0,0 +1,153 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +Word16 pvq_dec_deidx_fx( /* out BER detected 1 , ok==0 */ + Word16 * y, /* o: decoded vector (non-scaled int) */ + const Word16 k_val, /* i: number of allocated pulses */ + const Word16 dim, /* i: Length of vector */ + const Word16 LS_ind, /* i; lS index 1 bit */ + const UWord32 UL_MPVQ_ind /* i; MPVQ index */ +) +{ + Dyn_Mem_Deluxe_In( + Word16 BER_flag; + UWord32 h_mem[1 + KMAX_FX + 1]; + PvqEntry_fx entry; + ); + + BER_flag = 0; move16(); + + /* get_size will likely be called before this function, as the range decoder needs the size to fetch the index + */ + entry = get_size_mpvq_calc_offset_fx(dim, k_val, h_mem); /* TBD should be made into tables for N=16,10,6 */ + + entry.lead_sign_ind = LS_ind; move16(); + entry.index = L_deposit_l(0); /* only in case dim == 1 */ + IF (sub(dim, 1) != 0) + { + entry.index = UL_MPVQ_ind; + + /* safety check in case of bit errors */ + IF (L_sub(entry.index, entry.size) >= 0) + { + BER_flag = 1; move16(); + entry.index = 0; move16(); /* return something deterministic/valid, and LOW complex */ + } + } + mpvq_deindex_fx(&entry, h_mem, y); /* actual deindexing */ + + Dyn_Mem_Deluxe_Out(); + return BER_flag; +} + + + +#ifdef ENABLE_HR_MODE +void pvq_dec_scale_vec_fx(const Word32 *inQ29, Word16 adjGainQ13, Word32 *outQ) +#else +void pvq_dec_scale_vec_fx(const Word16 *inQ14, Word16 adjGainQ13, Word16 *outQ14) +#endif +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + FOR (i = 0; i < M; i++) + { +#ifdef ENABLE_HR_MODE + outQ[i] = L_shr(L_add(outQ[i], Mpy_32_16_lc3plus(inQ29[i], adjGainQ13)), 1); + move16(); +#else + outQ14[i] = add(outQ14[i], mult_r(adjGainQ13, inQ14[i])); move16(); +#endif + } + Dyn_Mem_Deluxe_Out(); +} + + +void pvq_dec_en1_normQ14_fx(/* Have to be used EXACTLY the same way in both both encoder and decoder */ +#ifdef ENABLE_HR_MODE + Word32 * xq, /* o: en1 normalized decoded vector (Q14) */ +#else + Word16 * xq, /* o: en1 normalized decoded vector (Q14) */ +#endif + const Word16 *y, /* i: decoded vector (non-scaled int) */ + const Word16 k_val_max, + /* i: max possible K in Q0 kO or kA */ /* OPT: not BE , use dynamic max pulse + amplitude */ + const Word16 dim /* i: Length of vector */ +) +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In( + Counter i; + Word32 L_tmp; + Word16 shift_num, shift_tot; + Word32 isqrtQ31_local; + Word16 tmp, exp, exp_shift; + Word32 L_yy; + ); +#else + Dyn_Mem_Deluxe_In( + Counter i; + Word32 L_tmp; + Word16 shift_num, shift_tot; + Word16 isqrtQ16_local, tmp, exp, exp_shift; + Word32 L_yy; + ); +#endif + +/* energy normalization starts here */ + L_yy = L_mult0(y[0], y[0]); + FOR (i = 1; i < dim; i++) + { + L_yy = L_mac0(L_yy, y[i], y[i]); /* stay in Q0 */ /* OPT: reuse some energies from PVQ linear search */ + } + /* 16 bit */ + IF (L_sub(L_yy, SQRT_EN_MAX_FX) < 0) + { + ASSERT(L_yy > 4); /* Q16 isqrt table lookup not valid below 5 */ +#ifdef ENABLE_HR_MODE + isqrtQ31_local = isqrt_Q31tab[L_yy]; move16(); /* 1 cycle */ +#else + isqrtQ16_local = isqrt_Q16tab[L_yy]; move16(); /* 1 cycle */ +#endif + } + ELSE + { + /* about 8-9 cycles */ + exp = 15; move16(); /* set ISqrt16() exp_in to get delta exp out near 0 when Lyy is in Q0 */ + tmp = ISqrt16(extract_l(L_yy), + &exp); /* exp out is now a delta shift with a later tmp Q15 multiplication in mind */ +#ifdef ENABLE_HR_MODE + exp_shift = add(exp, 16); /* up to Q16 */ + isqrtQ31_local = L_shl(L_deposit_l(tmp), exp_shift); /* new mantissa in a fixed Q16 */ +#else + exp_shift = add(exp, 16 - 15); /* up to Q16 */ + isqrtQ16_local = shl(tmp, exp_shift); /* new mantissa in a fixed Q16 */ +#endif + } + + shift_num = norm_s(k_val_max); /* simply account for the preknown fixed max possible pulseamp in y */ + shift_tot = sub(14 - 1, shift_num); /* upshift to get to Q14 */ + FOR (i = 0; i < dim; i++) /* upshifted y[i] used */ + { +#ifdef ENABLE_HR_MODE + L_tmp = Mpy_32_16_lc3plus(isqrtQ31_local, shl_pos(y[i], shift_num)); /* Q(16+0+shift_num +1 = shift_num+1 */ + xq[i] = L_shl(L_tmp, shift_tot + 1); move32(); /* Q30 , */ +#else + L_tmp = L_mult(isqrtQ16_local, shl_pos(y[i], shift_num)); /* Q(16+0+shift_num +1 = shift_num+1 */ + xq[i] = round_fx(L_shl(L_tmp, shift_tot)); move16(); /* Q14 , */ +#endif + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/pvq_enc_fx.c b/lib_lc3plus/pvq_enc_fx.c new file mode 100644 index 000000000..9c164dda5 --- /dev/null +++ b/lib_lc3plus/pvq_enc_fx.c @@ -0,0 +1,369 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +static void pvq_pyr_project(const Word16 dim_proj, /* end vector dimension+1 */ + const Word16 *xabs, /* absolute vector values */ + Word32 L_xsum, /* absolute vector sum over dim */ + Word16 num, /* target number of pulses */ + Word16 * y, /* projected output vector */ + Word16 *pulse_tot_ptr, Word32 *L_xy_ptr, /* accumulated correlation Q(in+0+1) = Qin+1 */ + Word32 *L_yy_ptr /* accumulated energy Q0 */ +) +{ + + Dyn_Mem_Deluxe_In( + Counter i; + Word32 L_tmp, L_num; + Word16 den, shift_num, shift_den, shift_delta, proj_fac; + ); + + *pulse_tot_ptr = 0; move16(); + *L_xy_ptr = L_deposit_l(0); + *L_yy_ptr = L_deposit_l(0); + + shift_den = norm_l(L_xsum); /* x_sum input Qin */ + den = extract_h(L_shl_pos(L_xsum, shift_den)); /* now in Qin+shift_den */ + + L_num = L_deposit_l(num); + shift_num = sub(norm_l(L_num), 1); + L_num = L_shl_pos(L_num, shift_num); /* now in Q0 +shift_num -1 */ + proj_fac = div_l(L_num, den); /* L_num always has to be less than den<<16 , norm_l-1 makes that happen */ + + shift_delta = sub(shift_num, shift_den); + FOR (i = 0; i < dim_proj; i++) + { + L_tmp = L_mult(proj_fac, xabs[i]); /* Q shift_delta + PVQ_SEARCH_QIN */ + y[i] = extract_h(L_shr(L_tmp, shift_delta)); move16(); /* to Q0 with floor , and potential sturation */ + ; + + *pulse_tot_ptr = add(*pulse_tot_ptr, y[i]); /* Q0 */ + *L_yy_ptr = L_mac0(*L_yy_ptr, y[i], y[i]); /* Energy, Q0 */ + *L_xy_ptr = L_mac(*L_xy_ptr, xabs[i], y[i]); /* Corr, Q0*Q12 +1 --> Q13 */ + } + + Dyn_Mem_Deluxe_Out(); +} + + +static __forceinline Word16 one_pulse_search(const Word16 dim_start, /* start vector dimension */ + const Word16 dim_end, /* end vector dimension+1 */ + const Word16 *x_abs, /* absolute vector values */ + Word16 * y, /* output vector */ + Word16 * pulse_tot_ptr, + Word32 * L_xy_ptr, /* accumulated correlation Q(12+0+1) = Q13 */ + Word32 * L_yy_ptr, /* accumulated energy Q0 */ + Word16 max_xabs) /* current max amplitude for target */ +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word16 corr_tmp, corr_sq_tmp, en_max_den, cmax_num, en_tmp; + Word32 L_tmp_en_lc, L_tmp_corr; + Word16 corr_up_shift, imax; + ); + + /* maximize correlation precision, prior to every unit pulse addition in the vector */ + corr_up_shift = norm_l(L_mac(*L_xy_ptr, 1, max_xabs)); /* pre analyze worst case L_xy update in the dim loop */ + imax = -1; /* not needed for search, only added to avoid compiler warning */ + { + en_max_den = 0; move16(); + cmax_num = -1; move16(); /* req. to force a 1st update for n==dim_start */ + + FOR (i = dim_start; i < dim_end; i++) + { + L_tmp_corr = L_shl_pos(L_mac(*L_xy_ptr, 1, x_abs[i]), corr_up_shift); /* actual in-loop target value */ + + corr_tmp = round_fx_sat(L_tmp_corr); + + corr_sq_tmp = mult(corr_tmp, corr_tmp); /* CorrSq_tmp for a 16bit low complexity cross multiplication */ + + L_tmp_en_lc = L_mac(*L_yy_ptr, 1, y[i]); /*Q0 x^2+ 2x , "+1" added once before loop , result , energy may + span up to ~14+1(Q1)+1(sign)=16 bits */ + /* extract_l without shift can always be used for this section as energy is guaranteed to stay in the lower + * word*/ + + en_tmp = extract_l(L_tmp_en_lc); /* L_shl + round_fx could also be used also but then adds an uphift cost */ + + /* 16/32 bit comparison WC (4 +1+1 + (1+1+1) = 9 */ + IF (L_msu(L_mult(corr_sq_tmp, en_max_den), cmax_num, en_tmp) > 0) /* use L_mult and then a L_msu */ + { + cmax_num = corr_sq_tmp; move16(); + en_max_den = en_tmp; move16(); + imax = i; move16(); + } + } /* dim */ + } + + + /* finally add found unit pulse contribution to past L_xy, Lyy, for next pulse loop */ + *L_xy_ptr = L_mac(*L_xy_ptr, x_abs[imax], 1); /* Qin+1 */ + *L_yy_ptr = L_mac(*L_yy_ptr, 1, y[imax]); + + y[imax] = add(y[imax], 1); move16(); /* Q0 added pulse */ + (*pulse_tot_ptr) = add((*pulse_tot_ptr), 1); /* increment total pulse sum */ + Dyn_Mem_Deluxe_Out(); + return imax; +} + + +void pvq_enc_search_fx( + const Word16 *x, /* i: target vector to quantize Qin */ + Word16 * y_far, /* o: outl_far o, raw pulses (non-scaled short) Q0 , length dim */ + Word16 * y, /* o: outl_near o, raw pulses (non-scaled short) Q0 , length dim */ + Word16 * yA, /* o: A section raw pulses (non-scaled short) Q0 , length dimA */ + Word16 * yB, /* o: B section raw pulses (non-scaled short) Q0 , length dim-dimA */ + Word32 * L_corr, /* o: 4 un-normalized correlation sums for outl_far, outl_near, A, AB */ + Word32 * L_search_en, /* o: 4 energy sums for outl_far, outl_near, A, AB */ + Word16 * pulses_fin, /* i: number of allocated pulses to outl_far, outl_near , A, AB sections */ + Word16 * pulses_proj, /* i: number of projection pulses for outl_far, outl_near, A, AB */ + + const Word16 dim, /* i: Length of outlier vector */ + const Word16 dimA /* i: Length of vector A section */ +) +{ + + Dyn_Mem_Deluxe_In( + Counter i; + Word16 pulse_tot_far, pulse_tot, pulse_totA, pulse_totB; + Word16 xabs[PVQ_MAX_VEC_SIZE]; + Word16 max_xabs, max_xabsA, max_xabsB; + Word32 L_xsum, L_xsumA; + Word32 L_yy, L_xy; + Word16 imax; + Counter k; + Word16 dim_m1; + Word16 dimB; + const Word16 *xBptr; + Word16 pulses_far, pulses, pulsesA, pulsesB; + ); + +#ifdef WMOPS + BASOP_sub_sub_start("pvq_enc_search_fx"); +#endif + + pulses_far = pulses_fin[0]; move16(); + pulses = pulses_fin[1]; move16(); + pulsesA = pulses_fin[2]; move16(); + pulsesB = pulses_fin[3]; move16(); + + FOR (i = 0; i < N_SCF_SHAPES_ST2; i++) + { + L_corr[i] = L_deposit_l(0); + L_search_en[i] = L_deposit_l(0); + } + + dimB = sub(dim, dimA); + + L_xsum = L_deposit_h(0); + + max_xabs = -1; move16(); + max_xabsA = -1; move16(); + max_xabsB = -1; move16(); + FOR (i = 0; i < dimA; i++) + { + xabs[i] = abs_s(x[i]); move16(); /* Qx */ + max_xabsA = s_max(max_xabsA, xabs[i]); /* for efficient search correlation scaling */ + L_xsum = L_mac0(L_xsum, 1, xabs[i]); /* stay in Qx */ + } + + basop_memset(y_far, 0, dim * sizeof(Word16)); + basop_memset(y, 0, dimA * sizeof(Word16)); + basop_memset(yA, 0, dimA * sizeof(Word16)); + + L_xsumA = L_add(L_xsum, 0); /* save for section A projection */ + + FOR (i = dimA; i < dim; i++) + { + xabs[i] = abs_s(x[i]); move16(); /* Qx */ + max_xabsB = s_max(max_xabsB, xabs[i]); /* for efficient search correlation scaling */ + L_xsum = L_mac0(L_xsum, 1, xabs[i]); /* stay in Qx */ + } + + basop_memset(&y[dimA], 0, (dim - dimA) * sizeof(Word16)); + + basop_memset(yB, 0, dimB * sizeof(Word16)); + + max_xabs = s_max(max_xabsA, max_xabsB); /* global max abs value */ + + test(); + IF (L_xsum == 0) + { /* no shape in any section, projection in outl_far, outl_near, A, AB not possible, any search meaningless */ + + dim_m1 = sub(dim, 1); + y_far[0] = shr_pos(pulses_far, 1); move16(); + y_far[dim_m1] = add(y_far[dim_m1], sub(pulses_far, y_far[0])); move16(); + + dim_m1 = sub(dim, 1); + y[0] = shr_pos(pulses, 1); move16(); + y[dim_m1] = add(y[dim_m1], sub(pulses, y[0])); move16(); + + dim_m1 = sub(dimA, 1); + yA[0] = shr_pos(pulsesA, 1); move16(); + yA[dim_m1] = add(yA[dim_m1], sub(pulsesA, yA[0])); move16(); + + dim_m1 = sub(dimB, 1); + yB[0] = shr_pos(pulsesB, 1); move16(); + yB[dim_m1] = add(yB[dim_m1], sub(pulsesB, yB[0])); move16(); + } + ELSE + { + ASSERT(pulses_proj[0] > 0); + ASSERT(L_xsum > 0); + + pvq_pyr_project(dim, xabs, L_xsum, pulses_proj[0], y_far, &pulse_tot_far, &L_xy, + &L_yy); /* outlier submode projection */ + + ASSERT(pulses_far <= 127); + FOR (k = pulse_tot_far; k < pulses_far; k++) + { + L_yy = L_add(L_yy, 1); /* pre add 1 in Q0 in L_yyQ0 = (x^2 + 2*x + 1) */ + imax = one_pulse_search(0, dim, xabs, y_far, &pulse_tot_far, &L_xy, &L_yy, max_xabs); + } + ASSERT(pulse_tot_far == pulses_far); + /* outlier far submode result vector in y_far[0...15] */ + L_corr[0] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */ + + basop_memmove(y, y_far, dim * sizeof(Word16)); /*y_far->y */ + + pulse_tot = pulse_tot_far; move16(); + + ASSERT(pulses <= 127); + FOR (k = pulse_tot; k < pulses; k++) + { + L_yy = L_add(L_yy, 1); /* pre add 1 in Q0 in L_yyQ0 = (x^2 + 2*x + 1) */ + imax = one_pulse_search(0, dim, xabs, y, &pulse_tot, &L_xy, &L_yy, max_xabs); + } + + /* outlier near submode result vector in y[0...15] */ + L_corr[1] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */ + + ASSERT(pulse_tot == pulses); + + IF (L_xsumA == 0) + { + /* no shape in A section, projection in A not possible, search meaningless */ + dim_m1 = sub(dimA, 1); + yA[0] = shr_pos(pulsesA, 1); move16(); + yA[dim_m1] = add(yA[dim_m1], sub(pulsesA, yA[0])); move16(); + } + ELSE + { + IF (pulses_proj[2] != 0) /* fixed setup if bitrate is fixed */ + { + ASSERT(pulses_proj[2] > 0); + ASSERT(L_xsumA > 0); + pvq_pyr_project(dimA, xabs, L_xsumA, pulses_proj[2], yA, &pulse_totA, &L_xy, + &L_yy); /* section A , in submode 1 projection */ + } + ELSE + { + /* default, otherwise recalculate A from outlier result (to remove any section B pulses influence) + */ + pulse_totA = 0; move16(); + L_xy = L_deposit_l(0); + L_yy = L_deposit_l(0); + + basop_memmove(yA, y, dimA * sizeof(Word16)); + FOR (i = 0; i < dimA; i++) + { + pulse_totA = add(pulse_totA, yA[i]); /* Q0 */ + L_xy = L_mac(L_xy, xabs[i], yA[i]); /* Corr, Q0*Q12 +1 --> Q13 */ + L_yy = L_mac(L_yy, yA[i], yA[i]); /* Energy, Q(0+0)+1)= Q1 */ + } + L_yy = L_shr_pos(L_yy, 1); /* En to Q0 */ + } + + /* search remaining pulses in regular section A */ + FOR (k = pulse_totA; k < pulsesA; k++) + { + L_yy = L_add(L_yy, 1); /* 1 added in Q0 */ + imax = one_pulse_search(0, dimA, xabs, yA, &pulse_totA, &L_xy, &L_yy, max_xabsA); + } + ASSERT(pulse_totA == pulsesA); + } /* L_xsumA!=0 */ + + /* reg Set A result vector now in yA[0...9] */ + L_corr[2] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */ + + /* search remaining pulses in regular section B, even if energy in B is zero */ + ASSERT(pulses_proj[3] == 0); + pulse_totB = 0; move16(); + + IF (sub(pulsesB, 1) == 0) + { /* LC search, sufficient to find a single max, as pulses can not be stacked, when nb-pulses==1 */ + imax = 0; move16(); /* safety */ + FOR (i = dimA; i < dim; i++) + { + if (xabs[i] == max_xabsB) + { + imax = sub(i, dimA); + } + } + pulse_totB = 1; move16(); + yB[imax] = 1; move16(); /* reg set B result vector in yB[0...5] */ + L_xy = L_mac(L_xy, xabs[add(imax, dimA)], 1); /* calc total corr for A+B sections */ + L_yy = L_add(L_yy, 1); + } + ELSE + { /* more than one target pulse in section B */ + /* keep A pulses influence, search section B pulses influence */ + FOR (k = pulse_totB; k < pulsesB; k++) + { + L_yy = L_add(L_yy, 1); /* 1 added in Q0*/ + imax = one_pulse_search(dimA, dim, xabs, &(yB[-dimA]), &pulse_totB, &L_xy, &L_yy, max_xabsB); + } + } + + L_corr[3] = L_shr_pos(L_xy, 1); move32(); /* to Qin*Q0 , corr of combined A and B */ + + ASSERT(pulse_totB == pulsesB); + /* reg set B result vector now in yB[0...5] */ + } /* L_xsum != 0 */ + +/* apply sign of (x) to first orthant result */ + FOR (i = 0; i < dim; i++) + { + if (x[i] < 0) + { + y_far[i] = negate(y_far[i]); /* apply sign for outlier far */ + } + } + + FOR (i = 0; i < dim; i++) + { + if (x[i] < 0) + { + y[i] = negate(y[i]); /* apply sign for outliers near */ + } + } + + xBptr = &(x[dimA]); move32(); /* ptr init to B target section */ + FOR (i = 0; i < dimA; i++) + { + if (x[i] < 0) + { + yA[i] = negate(yA[i]); /* apply sign in N_SETA */ + } + } + + FOR (i = 0; i < (dimB); i++) + { + if (xBptr[i] < 0) + { + yB[i] = negate(yB[i]); /* apply sign in N_SETB */ + } + } + + Dyn_Mem_Deluxe_Out(); +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +} + diff --git a/lib_lc3plus/pvq_index_fx.c b/lib_lc3plus/pvq_index_fx.c new file mode 100644 index 000000000..c7d63c840 --- /dev/null +++ b/lib_lc3plus/pvq_index_fx.c @@ -0,0 +1,513 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +#define SIGNBIT_FX 0x80000000u +#define SIGNBIT_SHRT_FX 0x8000 + +static void initOffsets_fx(Word16 dim_in, UWord32 *h_mem, + Word16 k_val_in) /* may be removed with tables for N=16,10,6 */ +{ + UWord32 k_val_prev, k_val_curr; + UWord32 k_val, UL_k_val_in; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("initOffsets_fx", sizeof(struct { + UWord32 k_val_prev, k_val_curr; + UWord32 k_val, UL_k_val_in; + })); +#endif + + h_mem[0] = UL_deposit_l(0); + h_mem[1] = UL_deposit_l(1); + + UL_k_val_in = UL_deposit_l(k_val_in); + IF (sub(dim_in, 2) == 0) + { + FOR (k_val = 2; k_val <= UL_k_val_in; k_val++) + { + h_mem[k_val] = UL_subNsD(UL_lshl(k_val, 1), 1U); move32(); + } + h_mem[k_val] = UL_k_val_in; move32(); + } + ELSE + { + k_val_prev = UL_deposit_l(1U); + FOR (k_val_curr = 2; k_val_curr <= UL_k_val_in; k_val_curr++) + { + h_mem[k_val_curr] = UL_addNsD(1U, UL_Mpy_32_32(k_val_curr, UL_lshl(k_val_prev, 1))); move32(); + k_val_prev = UL_addNsD(k_val_curr, 0U); + } + h_mem[k_val_curr] = UL_Mpy_32_32(k_val_curr, k_val_prev); move32(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static void a_fwd_fx(UWord32 *a_in, /* i/o: offsets */ + Word16 n_items /* i : items, k's */ +) +{ + UWord32 a_1, a_in0; + Counter i; + UWord32 *a_in_prev_ptr; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("a_fwd_fx", sizeof(struct { + UWord32 a_1, a_in0; + Counter i; + UWord32 *a_in_prev_ptr; + })); +#endif + + a_in0 = UL_deposit_l(1); + + a_in_prev_ptr = &(a_in[-1]); + FOR (i = 1; i <= n_items; i++) + { + a_1 = UL_addNsD(a_in0, UL_addNsD(a_in_prev_ptr[i], a_in[i])); + a_in_prev_ptr[i] = a_in0; move32(); + a_in0 = UL_addNsD(a_1, 0U); + } + a_in_prev_ptr[i] = a_in0; move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static void a_bwd_fx(UWord32 *a_in, /* i/o: offsets */ + Word16 n_items /* i: n_items */ +) +{ + UWord32 a_1, a_in0; + Counter i; + UWord32 *a_in_prev_ptr; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("a_bwd_fx", sizeof(struct { + UWord32 a_1, a_in0; + Counter i; + UWord32 *a_in_prev_ptr; + })); +#endif + + a_in0 = UL_deposit_l(0); + a_in_prev_ptr = &(a_in[-1]); + + FOR (i = 1; i <= n_items; i++) + { + a_1 = UL_subNsD(UL_subNsD(a_in[i], a_in0), a_in_prev_ptr[i]); + a_in_prev_ptr[i] = a_in0; move32(); + a_in0 = UL_addNsD(a_1, 0U); + } + a_in_prev_ptr[i] = a_in0; move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static void a_u_fwd_fx(UWord32 *a_u_in, Word16 k_val_in, Word16 mem_size_m1) +{ + UWord32 u_kp1_prev, u_kp1; + UWord32 u_k_prev; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("a_u_fwd_fx", sizeof(struct { + UWord32 u_kp1_prev, u_kp1; + UWord32 u_k_prev; + })); +#endif + + u_kp1_prev = a_u_in[mem_size_m1]; move32(); + u_k_prev = UL_lshr(a_u_in[k_val_in], 1); + + a_fwd_fx(&a_u_in[1], k_val_in); + + u_kp1 = UL_lshr(a_u_in[k_val_in], 1); + a_u_in[mem_size_m1] = UL_addNsD(1U, UL_addNsD(u_kp1_prev, UL_addNsD(u_k_prev, u_kp1))); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static Word16 get_lead_sign_fx(UWord32 *ind) +{ + Word16 leading_sign; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("get_lead_sign_fx", sizeof(struct { Word16 leading_sign; })); +#endif + + leading_sign = 1; move16(); + if (UL_and(*ind, 1) != 0) + { + leading_sign = -1; move16(); + } + (*ind) = UL_lshr(*ind, 1); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + return leading_sign; +} + +/*-------------------------------------------------------------------* + * mind2vec_one_fx() + *-------------------------------------------------------------------*/ +static void mind2vec_one_fx(Word16 k_val_in, /* i: nb unit pulses , [ 0...K_MAX ] */ + Word16 leading_sign, /* i: leading sign -1, 0, 1*/ + UWord32 ind, /* i: index */ /* parameter could be omitted */ + Word16 *vec_out /* o: pulse train */ +) +{ + *vec_out = (Word16)ind; /* dummy assignment to handle the common ind parameter warning */ + + if (leading_sign < 0) + { + k_val_in = negate(k_val_in); + } + *vec_out = k_val_in; move16(); +} + +static Word16 setval_update_sign_fx(Word16 k_delta, Word16 k_max_local, Word16 *leading_sign, UWord32 *ind_in, + Word16 *vec_out) +{ + IF (k_delta != 0) + { + mind2vec_one_fx(k_delta, *leading_sign, *ind_in, vec_out); + *leading_sign = get_lead_sign_fx(ind_in); + k_max_local = sub(k_max_local, k_delta); + } + return k_max_local; +} + +/*-------------------------------------------------------------------* + * mind2vec_fx() + *-------------------------------------------------------------------*/ +static void mind2vec_fx(Word16 dim_in, /* i: dimension */ + Word16 k_max_local, /* i: nb unit pulses */ + Word16 leading_sign, /* i: leading sign */ + UWord32 ind, /* i: index */ + Word16 * vec_out, /* o: pulse train */ + UWord32 *h_in /* i: offset vector A=1+2U */ +) +{ + Counter pos; + Word16 k_acc, k_delta; + UWord32 UL_tmp_offset, UL_diff; + UWord16 sgn; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("mind2vec_fx", sizeof(struct { + Counter pos; + Word16 k_acc, k_delta; + UWord32 UL_tmp_offset, UL_diff; + UWord16 sgn; + })); +#endif + + k_acc = k_max_local; move16(); + FOR (pos = 0; pos < dim_in; pos++) + { + + IF (ind != 0) + { + + k_acc = k_max_local; move16(); + + UL_tmp_offset = UL_addNsD(h_in[k_acc], 0U); + + UL_diff = UL_subNs(ind, UL_tmp_offset, &sgn); + + WHILE (sgn) + { + UL_diff = UL_subNs(ind, h_in[--k_acc], &sgn); + } + + ind = UL_addNsD(UL_diff, 0U); + + k_delta = sub(k_max_local, k_acc); + } + ELSE + { + mind2vec_one_fx(k_max_local, leading_sign, ind, &vec_out[pos]); + BREAK; + } + + k_max_local = setval_update_sign_fx(k_delta, k_max_local, &leading_sign, &ind, &vec_out[pos]); + + a_bwd_fx(h_in, add(k_max_local, 1)); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +PvqEntry_fx get_size_mpvq_calc_offset_fx( /* o : size, dim, k_val */ + Word16 dim_in, /* i : dimension */ + Word16 k_val_in, /* i : nb unit pulses */ + UWord32 *h_mem /* o : offsets */ +) +{ + Counter i; + PvqEntry_fx entry; + Word16 kp1; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("get_size_mpvq_calc_offset_fx", sizeof(struct { + Counter i; + PvqEntry_fx entry; + Word16 kp1; + })); +#endif + + entry.dim = dim_in; move16(); + entry.k_val = k_val_in; move16(); + + entry.index = L_deposit_l(0); + entry.lead_sign_ind = 0; move16(); + + ASSERT(dim_in <= M); + ASSERT(tabledKMAX[dim_in] != 0); + + /* tabled values for worst case K */ /* made into table lookup for N=16, 10, 6 */ + kp1 = add(k_val_in, 1); + FOR (i = 0; i <= kp1; i++) /* A+U copying */ + { + h_mem[i] = + UL_addNsD(MPVQ_offs_ptr[dim_in][i], 0U); /* a vector copying is needed as MPVQ recursion is in place */ + } + /* special handling of last U offset in k+1 column */ + if (sub(k_val_in, tabledKMAX[dim_in]) != 0) + { + h_mem[kp1] = UL_lshr(h_mem[kp1], 1); /* (A+1)/2 , convert from A(K+1) to U(K+1) domain */ + } + entry.size = + UL_addNsD(1U, UL_addNsD(h_mem[kp1], UL_lshr(h_mem[k_val_in], 1))); /* MPVQ size calc. 1 + H(K+1) + (A(K)>>1) */ + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + return entry; +} + +/*-------------------------------------------------------------------* + * mpvq_deindex_fx() + *-------------------------------------------------------------------*/ +void mpvq_deindex_fx( /* o : void */ + const PvqEntry_fx *entry, /* i : sign_ind, index, dim, k_val */ + UWord32 * h_mem, /* i : A/U offsets */ + Word16 * vec_out /* o : pulse train */ +) +{ + Word16 leading_sign; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("mpvq_deindex_fx", sizeof(struct { Word16 leading_sign; })); +#endif +#ifdef WMOPS + BASOP_sub_sub_start("mpvq_deindex_fx"); +#endif + + basop_memset(vec_out, 0, (entry->dim) * sizeof(Word16)); + + leading_sign = 1; move16(); + if (entry->lead_sign_ind != 0) + { + leading_sign = -1; move16(); + } + + IF (entry->k_val != 0) + { + mind2vec_fx(entry->dim, entry->k_val, leading_sign, entry->index, vec_out, h_mem); + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +} + +/*-------------------------------------------------------------------* + * vec2mind_two_fx() + *-------------------------------------------------------------------*/ +static void vec2mind_two_fx(const Word16 *vec_in, /* i : PVQ pulse train */ + Word16 * k_val_out_ptr, /* o : number of unit pulses */ + UWord32 * next_sign_ind, /* i/o: next sign ind */ + UWord32 * ind /* o: MPVQ index */ +) +{ + UWord32 lead_sign_ind_add; + Word16 abs0, abs1, abs01, sptr; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("vec2mind_two_fx", sizeof(struct { + UWord32 lead_sign_ind_add; + Word16 abs0, abs1, abs01, sptr; + })); +#endif + + abs0 = abs_s(vec_in[0]); + abs1 = abs_s(vec_in[1]); + abs01 = add(abs0, abs1); + *k_val_out_ptr = abs01; move16(); + *ind = UL_deposit_l(0); + + *next_sign_ind = UL_deposit_h(SIGNBIT_SHRT_FX); + + IF (abs01 != 0) + { + sptr = 0; move16(); + *next_sign_ind = UL_deposit_l(sptr); + + test(); + IF (abs0 != 0 && abs1 != 0) + { + lead_sign_ind_add = UL_deposit_l(1); + if (vec_in[1] < 0) + { + lead_sign_ind_add = UL_deposit_l(2); + } + *ind = UL_addNsD(UL_deposit_l((UWord16)lshl(sub(abs1, 1), 1)), lead_sign_ind_add); + } + ELSE + { + IF (abs0 == 0) + { + *ind = UL_deposit_l((UWord16)sub(lshl(abs1, 1), 1)); + sptr = 1; move16(); + } + } + + if (vec_in[sptr] < 0) + { + *next_sign_ind = UL_deposit_l(1); + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static void enc_push_sign(Word16 val, UWord32 *next_sign_ind, UWord32 *index) +{ + test(); + IF ((UL_and(*next_sign_ind, SIGNBIT_FX) == 0) && (val != 0)) + { + *index = UL_addNsD(UL_lshl(*index, 1), *next_sign_ind); + } + if (val < 0) + { + *next_sign_ind = UL_deposit_l(1); + } + if (val > 0) + { + *next_sign_ind = UL_deposit_l(0); + } +} + +static void vec2mind_fx(Word16 dim_in, /* i : dim */ + Word16 k_val_in, /* i : number of unit pulses */ + const Word16 *vec_in, /* i : PVQ pulse train */ + UWord32 * next_sign_ind, /* o : pushed leading sign */ + UWord32 * index, /* o : MPVQ index */ + UWord32 * N_MPVQ_ptr, /* o : size(N_MPVQ(dim,K_val_in))*/ + UWord32 * h_mem) /* o : offsets */ +{ + Counter pos; + Word16 mem_size_m1, k_val_acc, tmp_val; + UWord32 tmp_h; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("vec2mind_fx", sizeof(struct { + Counter pos; + Word16 mem_size_m1, k_val_acc, tmp_val; + UWord32 tmp_h; + })); +#endif + + mem_size_m1 = add(k_val_in, 1); + *next_sign_ind = UL_deposit_h(SIGNBIT_SHRT_FX); + + pos = sub(dim_in, 2); + vec2mind_two_fx(&vec_in[pos], &k_val_acc, next_sign_ind, index); + initOffsets_fx(3, h_mem, k_val_in); + + tmp_h = h_mem[k_val_acc]; move32(); + FOR (pos--; pos >= 0; pos--) + { + tmp_val = vec_in[pos]; move16(); + enc_push_sign(tmp_val, next_sign_ind, index); + + *index = UL_addNsD(*index, tmp_h); + + k_val_acc = add(k_val_acc, abs_s(tmp_val)); + + IF (pos != 0) + { + a_u_fwd_fx(h_mem, k_val_in, mem_size_m1); + } + tmp_h = UL_addNsD(h_mem[k_val_acc], 0U); + } + *N_MPVQ_ptr = UL_addNsD(1U, UL_addNsD(UL_lshr(tmp_h, 1), h_mem[mem_size_m1])); move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +PvqEntry_fx mpvq_index_fx( /* o : leading_sign_index, index, size, k_val */ + const Word16 *vec_in, /* i : signed pulse train */ + Word16 dim_in, /* i : dimension */ + Word16 k_val_local /* i : nb unit pulses */ +) +{ + PvqEntry_fx result; + UWord32 h_mem[1 + KMAX_FX + 1]; + UWord32 lead_sign_ind; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("mpvq_index_fx", sizeof(struct { + PvqEntry_fx result; + UWord32 h_mem[1 + KMAX_FX + 1]; + UWord32 lead_sign_ind; + })); +#endif +#ifdef WMOPS + BASOP_sub_sub_start("mpvq_index_fx"); +#endif + + ASSERT(k_val_local <= KMAX_FX); + + result.k_val = k_val_local; move16(); + result.dim = dim_in; move16(); + + vec2mind_fx(dim_in, k_val_local, vec_in, &lead_sign_ind, &result.index, &result.size, h_mem); + + result.lead_sign_ind = u_extract_l(lead_sign_ind); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + + return result; +} + diff --git a/lib_lc3plus/quantize_spec.c b/lib_lc3plus/quantize_spec.c deleted file mode 100644 index fdaee2890..000000000 --- a/lib_lc3plus/quantize_spec.c +++ /dev/null @@ -1,283 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -LC3_INT32 find_last_nz_pair(LC3_INT32 x[], LC3_INT32 length); -LC3_INT32 find_last_nz_pair(LC3_INT32 x[], LC3_INT32 length) -{ - LC3_INT32 last_nz, lobs[4]; LC3_INT32 stage, i; - - lobs[0] = 4; - - lobs[1] = (length >> 1); /* length/2 */ - - lobs[2] = (lobs[1]+ (length >> 2)); - - lobs[3] = (lobs[2]+ (length >> 3)); - - - last_nz = 0; - - i = length; - - for (stage = 3; stage >= 0; --stage) - { - /* unmapped kernel */ - for (; i >= lobs[stage]; i -= 2) - { - if (x[i - 2] != 0) - { - last_nz = MAX(last_nz, i); - } - if (x[i - 1] != 0) - { - last_nz = MAX(last_nz, i); - } - } - if (last_nz > 0) - { - break; - } - } - - return MAX(last_nz, 2); -} - - -void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT nt, LC3_INT totalBits, LC3_INT* nbits, LC3_INT* nbits2, LC3_INT fs, - LC3_INT* lastnzout, LC3_INT* codingdata, LC3_INT* lsbMode, LC3_INT mode, LC3_INT target, LC3_INT hrmode) -{ - - LC3_INT rateFlag, i, lastnz2, m, maxlev, k; - LC3_INT nbits_lsb; - LC3_INT c; - LC3_INT a, b, lev1, sym, t, pki; - LC3_INT a1_msb, b1_msb; - LC3_INT lastnz = 1, nt_half; - LC3_FLOAT offset = 0.375; - LC3_INT32 bits, bits2; -#ifdef CR9_QUANT_SPEC_REWRITE - LC3_FLOAT inv_gain; -#endif - - assert(target >= 0); - - nbits_lsb = 0; - - nt_half = nt >> 1; - rateFlag = 0; c = 0; - - - if (hrmode) - { - offset = 0.5; - } - - /* Quantization */ - -#ifdef CR9_QUANT_SPEC_REWRITE - inv_gain = 1.0 / gain; -#endif - - for (i = 0; i < nt; i++) { - if (x[i] > 0) - { -#ifdef CR9_QUANT_SPEC_REWRITE - xq[i] = (LC3_INT32) ( x[i] * inv_gain + offset); -#else - xq[i] = (LC3_INT32) ( x[i] / gain + offset); -#endif - } - else - { -#ifdef CR9_QUANT_SPEC_REWRITE - xq[i] = -((LC3_INT32) (-x[i] * inv_gain + offset)); -#else - xq[i] = -((LC3_INT32) (-x[i] / gain + offset)); -#endif - } - if (hrmode == 0) { - assert(xq[i] <= 32767 && xq[i] >= -32768); - } - } - - /* Rate flag */ - if (fs != 96000 && (totalBits > (160 + FS2FS_IDX(fs) * 160))) - { - rateFlag = 512; - } - - /* Init */ - if (fs != 96000 && (mode == 0 && (totalBits >= (480 + FS2FS_IDX(fs) * 160)))) - { - mode = 1; - } - - /* Last non-zero 2-tuple */ - for (i = nt - 2; i >= 2; i = i - 2) { - if (xq[i + 1] != 0 || xq[i] != 0) { - lastnz = i + 1; - break; - } - } - - if (mode < 0) - { - lastnz2 = lastnz + 1; - } - else - { - lastnz2 = 2; - } - - bits = bits2 = 0; - - /* Calculate number of estimated bits */ - - for (k = 0; k < lastnz; k = k + 2) - { - t = c + rateFlag; - if (k > nt_half) - { - t += 256; - } - - codingdata[0] = t; - - a = abs(xq[k]); - b = abs(xq[k + 1]); - m = MAX(a, b); - - if (m == 0) - { - maxlev = -1; - } - else - { - maxlev = 29 - (clz_func(MAX(m, 3)) - 1); - } - - codingdata[1] = maxlev; - - if (mode <= 0) { - bits = bits + (MIN(a, 1) << 11); - bits = bits + (MIN(b, 1) << 11); - } - - lev1 = 0; - - while (MAX(a, b) >= 4) - { - pki = ari_spec_lookup_fl[t + lev1 * 1024]; - bits = bits + ari_spec_bits_fl[pki][16]; - - if (lev1 == 0 && mode > 0) - { - nbits_lsb += 2; - } - else - { - bits = bits + 2 * 2048; - } - - a = a >> 1; - b = b >> 1; - lev1 = MIN(lev1 + 1, 3); - } - - pki = ari_spec_lookup_fl[t + lev1 * 1024]; - sym = a + 4 * b; - codingdata[2] = sym; - codingdata += 3; - bits = bits + ari_spec_bits_fl[pki][sym]; - - if (mode > 0) - { - a1_msb = abs(xq[k]); - b1_msb = abs(xq[k + 1]); - - if (lev1 > 0) - { - a1_msb = a1_msb >> 1; - b1_msb = b1_msb >> 1; - - if (a1_msb == 0 && xq[k] != 0) - { - nbits_lsb++; - } - - if (b1_msb == 0 && xq[k + 1] != 0) - { - nbits_lsb++; - } - } - - bits = bits + (MIN(a1_msb, 1) << 11); - bits = bits + (MIN(b1_msb, 1) << 11); - } - - if (mode >= 0 && (abs(xq[k]) != 0 || abs(xq[k + 1]) != 0) && bits <= target * 2048) - { - lastnz2 = k + 2; - bits2 = bits; - } - - lev1 = lev1 - 1; - - if (lev1 <= 0) - { - t = 1 + (a + b) * (lev1 + 2); - } - else - { - t = 13 + lev1; - } - - c = (c & 15) * 16 + t; - } - - *nbits = (bits + 2047) >> 11; // Exactly same as ceil((LC3_FLOAT)*nbits / 2048.0); - - if (mode >= 0) - { - *nbits2 = (bits2 + 2047) >> 11; //ceil((LC3_FLOAT)*nbits2 / 2048.0); - } - else - { - *nbits2 = *nbits; - } - - if (mode > 0) - { - *nbits += nbits_lsb; - *nbits2 += nbits_lsb; - } - - /* Truncation of high-frequency coefficients */ - for (i = lastnz2; i <= lastnz; i++) - { - xq[i] = 0; - } - - /* Truncation of LSBs */ - if (mode > 0 && *nbits > target) - { - *lsbMode = 1; - } - else - { - *lsbMode = 0; - } - - *lastnzout = lastnz2; -} diff --git a/lib_lc3plus/quantize_spec_fx.c b/lib_lc3plus/quantize_spec_fx.c new file mode 100644 index 000000000..4667cf146 --- /dev/null +++ b/lib_lc3plus/quantize_spec_fx.c @@ -0,0 +1,1167 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +# ifdef ENABLE_HR_MODE +void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word32 gain, Word16 gain_e, Word32 xq[], Word16 nt, Word16 target, + Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnzout, + Word16 *codingdata, Word16 *lsbMode, Word16 mode, Word16 hrmode) +{ + + Word32 a1, b1, a1_i, b1_i; + Word16 t, lev1; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 nbits32, nbits232, target32; + Word16 nt_half; + Word32 c, ab_max, msb, a1_msb, b1_msb; + Word16 levmax; + Word16 s; + Word16 totBits, nbits_lsb; + Counter k, lev; + Word16 maxlevs; +# ifndef FUNCTION_quantizeSpec_func1 + Word16 tmp16; + Word32 offs32; + Counter i; +# else + Word32 ARM_params[3]; +# endif + +# ifdef DYNMEM_COUNT + Dyn_Mem_In("processQuantizeSpec_fx", sizeof(struct { + Word32 a1, b1, a1_i, b1_i, ab_max, c; + Word16 t, lev1; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 nbits32, nbits232; + Word16 nt_half; + Word16 msb, a1_msb, b1_msb, levmax; + Counter k, lev, i; + Word16 s; + Word16 tmp16; + Word32 offs32, target32; + Word16 totBits, nbits_lsb; + Word16 maxlevs; + })); +# endif + + assert(target >= 0); + + /* Quantization */ + gain = invFixp(gain, &gain_e); + + maxlevs = 21; + IF (hrmode) + { + s = sub(add(x_e, gain_e), 23); + s = s_min(s, 31); +# ifdef FUNCTION_quantizeSpec_func1 + ARM_params[0] = gain; + ARM_params[1] = s; + + quantizeSpec_func1_hr_ip(xq, x, nt, ARM_params); +# else + IF(s > 4) + { + s = sub(s, 4); /* Use extra bits of precision for fine calculation */ + FOR(i = 0; i < nt; i++) + { + offs32 = Mpy_32_32_lc3plus(L_shl_pos(x[i], s), gain); /* multiply */ + xq[i] = L_shr_r_pos(offs32, 4); /* Convert to Q0 with rounding */ + /* rounding is the equivalent of adding 0.5, which is the offset in hrmode */ + + move32(); + } + } + ELSE + { + FOR(i = 0; i < nt; i++) + { + offs32 = Mpy_32_32_lc3plus(x[i], gain); /* multiply */ + offs32 = L_shl(offs32, s); /* convert to 23Q8 */ + xq[i] = L_shr_r_pos(offs32, 8); /* Convert to Q0 with rounding */ + /* rounding is the equivalent of adding 0.5, which is the offset in hrmode */ + + move32(); + } + } +# endif /* FUNCTION_quantizeSpec_func1 */ + } + ELSE + { + s = sub(add(x_e, gain_e), 15); + s = s_max(s_min(s, 15), -15); +# ifdef FUNCTION_quantizeSpec_func1 + ARM_params[0] = gain; + ARM_params[1] = s; + ARM_params[2] = -4096; + quantizeSpec_func1_ip(xq, x, nt, ARM_params); +# else + FOR (i = 0; i < nt; i++) + { + offs32 = Mpy_32_32_lc3plus(L_abs(x[i]), gain); /* multiply */ + offs32 = L_shl(offs32, s); /* convert to 15Q16 */ + tmp16 = mac_r(offs32, -4096, 1); /* add offset and truncate */ + + if (x[i] < 0) + tmp16 = negate(tmp16); /* restore sign */ + + /* Normal quantization: xq[i] = x[i] / gg + sign(x[i]) * 0.375 + quant_offset is -0.125 in Q15 and round adds 0.5 in Q16. Hence + mac_r results in abs(x[i])/gain - 0.125 + 0.5 = abs(x[i])/gain + 0.375. + Due to the abs and negate combination this achieves the same result + as spec. + */ + + xq[i] = tmp16; + move16(); + } +# endif /* FUNCTION_quantizeSpec_func1 */ + } + /* Rate flag */ + rateFlag = 0; + move16(); + if (fs_idx != 5) + { + if (sub(totalBits, add(160, DEPR_i_mult(fs_idx, 160))) > 0) + { + rateFlag = 2 << NBITS_CONTEXT; + move16(); + } + } + + /* Init */ + nt_half = shr_pos(nt, 1); + c = 0; + move16(); + t = 0; + move16(); + a1_i = 0; + move16(); + b1_i = 1; + move16(); + target32 = L_shl_pos(L_deposit_l(target), SYM_BITS_Q); + nbits32 = L_negate(target32); + nbits232 = 0; + move32(); + nbits_lsb = 0; + move16(); + + if (fs_idx != 5) + { + IF (mode == 0 && sub(totalBits, add(480, DEPR_i_mult(fs_idx, 160))) >= 0) + { + mode = 1; + move16(); + } + } + + /* Find last non-zero tuple */ + lastnz = find_last_nz_pair(xq, nt); + IF (mode >= 0) + { + lastnz2 = 2; + } + ELSE + { + lastnz2 = lastnz; + } + + IF (mode < 0) + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + ab_max = L_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (L_sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_add(a1, b1), 1)); + } + ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + nbits32 = L_add(nbits32, 2 << SYM_BITS_Q); + a1_msb = L_shr_pos_pos(a1, 1); + b1_msb = L_shr_pos_pos(b1, 1); + msb = L_add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_shl_pos(L_add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(maxlevs, sub(norm_l(ab_max), 8)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1)); + a1_msb = L_shr(a1, levmax); + b1_msb = L_shr(b1, levmax); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + ELSE IF (mode == 0) + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + ab_max = L_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (L_sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_add(a1, b1), 1)); + } + ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + nbits32 = L_add(nbits32, 2 << SYM_BITS_Q); + a1_msb = L_shr_pos_pos(a1, 1); + b1_msb = L_shr_pos_pos(b1, 1); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), L_add(L_shl_pos(L_add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(maxlevs, sub(norm_l(ab_max), 8)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1)); + a1_msb = L_shr(a1, levmax); + b1_msb = L_shr(b1, levmax); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + ELSE + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + ab_max = L_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (L_sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1)); + } + ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + a1_msb = L_shr_pos_pos(a1, 1); + b1_msb = L_shr_pos_pos(b1, 1); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + nbits_lsb = add(nbits_lsb, 2); + if (L_sub(a1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (L_sub(b1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(maxlevs, sub(norm_l(ab_max), 8)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(sub(levmax, 1)), SYM_BITS_Q + 1)); + a1_msb = L_shr(a1, levmax); + b1_msb = L_shr(b1, levmax); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + a1_msb = L_shr_pos(a1, 1); + b1_msb = L_shr_pos(b1, 1); + if (a1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + nbits_lsb = add(nbits_lsb, 2); + if (L_sub(a1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (L_sub(b1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + + /* Number of consumed bits */ + nbits32 = L_add(nbits32, target32); + totBits = add(extract_l(L_shr_pos_pos(L_sub(nbits32, 1), SYM_BITS_Q)), 1); + IF (mode > 0) + { + totBits = add(totBits, nbits_lsb); + } + IF (nBits != NULL) + { + *nBits = totBits; + } + IF (mode >= 0) + { + nbits232 = L_add(nbits232, target32); + *nBits2 = add(extract_l(L_shr_pos(L_sub(nbits232, 1), SYM_BITS_Q)), 1); + } + ELSE + { + *nBits2 = *nBits; + move16(); + } + IF (mode > 0) + { + *nBits2 = add(*nBits2, nbits_lsb); + } + *lastnzout = lastnz2; + + /* Truncation of high frequency coefficients */ + IF (lastnz > lastnz2) + { + basop_memset(&xq[lastnz2], 0, (lastnz - lastnz2) * sizeof(*xq)); + } + + /* Truncation of LSBs */ + test(); + IF (mode > 0 && sub(totBits, target) > 0) + { + *lsbMode = 1; + move16(); + } + ELSE + { + *lsbMode = 0; + move16(); + } + +# ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +# endif +} + +# else /* ENABLE_HR_MODE */ + +void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word16 gain, Word16 gain_e, Word16 xq[], Word16 nt, Word16 target, + Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnzout, + Word16 *codingdata, Word16 *lsbMode, Word16 mode +) +{ + + Word16 a1, b1, a1_i, b1_i; + Word16 t, lev1; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 nbits32, nbits232, target32; + Word16 nt_half; + Word16 c, ab_max, msb, a1_msb, b1_msb, levmax; + Word16 s; + Word16 totBits, nbits_lsb; + Counter k, lev; + Word16 tmp16; + Word32 offs32; + Counter i; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processQuantizeSpec_fx", sizeof(struct { + Word16 a1, b1, a1_i, b1_i; + Word16 t, lev1; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 nbits32, nbits232; + Word16 nt_half; + Word16 c, ab_max, msb, a1_msb, b1_msb, levmax; + Counter k, lev, i; + Word16 s; + Word16 tmp16; + Word32 offs32, target32; + Word16 totBits, nbits_lsb; + })); +#endif + + /* Quantization */ + gain = Inv16_lc3plus(gain, &gain_e); + s = sub(add(x_e, gain_e), 15); + s = s_max(s_min(s, 15), -15); + + FOR (i = 0; i < nt; i++) + { + offs32 = Mpy_32_16_lc3plus(L_abs(x[i]), gain); /* multiply */ + offs32 = L_shl(offs32, s); /* convert to 15Q16 */ + tmp16 = extract_h(L_add(offs32, 0x00006000)); /* add offset and truncate */ + Word16 x_sign = (Word16) L_shr(x[i], 31); + xq[i] = sub(s_xor(tmp16, x_sign), x_sign); + move16(); + /* + Normal quantization: xq[i] = x[i] / gg + sign(x[i]) * 0.375 + -> 0.375 = 0x00006000 in 15Q16 + */ + } + + /* Rate flag */ + rateFlag = 0; + move16(); + if (sub(totalBits, add(160, DEPR_i_mult(fs_idx, 160))) > 0) + { + rateFlag = 2 << NBITS_CONTEXT; + move16(); + } + + /* Init */ + nt_half = shr_pos(nt, 1); + c = 0; + move16(); + t = 0; + move16(); + a1_i = 0; + move16(); + b1_i = 1; + move16(); + target32 = L_shl_pos(L_deposit_l(target), SYM_BITS_Q); + nbits32 = L_negate(target32); + nbits232 = 0; + move32(); + nbits_lsb = 0; + move16(); + IF (mode == 0 && sub(totalBits, add(480, DEPR_i_mult(fs_idx, 160))) >= 0) + { + mode = 1; + move16(); + } + + /* Find last non-zero tuple */ + lastnz = find_last_nz_pair(xq, nt); + IF (mode >= 0) + { + lastnz2 = 2; + } + ELSE + { + lastnz2 = lastnz; + } + + IF (mode < 0) + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + ab_max = s_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = add(a1, shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1)); + } + ELSE IF (sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + nbits32 = L_add(nbits32, 2 << SYM_BITS_Q); + a1_msb = shr_pos_pos(a1, 1); + b1_msb = shr_pos_pos(b1, 1); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(13, norm_s(ab_max)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1)); + a1_msb = shr(a1, levmax); + b1_msb = shr(b1, levmax); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + ELSE IF (mode == 0) + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + ab_max = s_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = add(a1, shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1)); + } + ELSE IF (sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + nbits32 = L_add(nbits32, 2 << SYM_BITS_Q); + a1_msb = shr_pos_pos(a1, 1); + b1_msb = shr_pos_pos(b1, 1); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(13, norm_s(ab_max)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1)); + a1_msb = shr(a1, levmax); + b1_msb = shr(b1, levmax); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + ELSE + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + ab_max = s_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = add(a1, shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1)); + } + ELSE IF (sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + a1_msb = shr_pos_pos(a1, 1); + b1_msb = shr_pos_pos(b1, 1); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + nbits_lsb = add(nbits_lsb, 2); + if (sub(a1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (sub(b1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(13, norm_s(ab_max)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(sub(levmax, 1)), SYM_BITS_Q + 1)); + a1_msb = shr(a1, levmax); + b1_msb = shr(b1, levmax); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + a1_msb = shr_pos(a1, 1); + b1_msb = shr_pos(b1, 1); + if (a1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + nbits_lsb = add(nbits_lsb, 2); + if (sub(a1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (sub(b1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + + /* Number of consumed bits */ + nbits32 = L_add(nbits32, target32); + totBits = add(extract_l(L_shr_pos_pos(L_sub(nbits32, 1), SYM_BITS_Q)), 1); + IF (mode > 0) + { + totBits = add(totBits, nbits_lsb); + } + IF (nBits != NULL) + { + *nBits = totBits; + } + IF (mode >= 0) + { + nbits232 = L_add(nbits232, target32); + *nBits2 = add(extract_l(L_shr_pos(L_sub(nbits232, 1), SYM_BITS_Q)), 1); + } + ELSE + { + *nBits2 = *nBits; + move16(); + } + IF (mode > 0) + { + *nBits2 = add(*nBits2, nbits_lsb); + } + *lastnzout = lastnz2; + + /* Truncation of high frequency coefficients */ + IF (lastnz > lastnz2) + { + basop_memset(&xq[lastnz2], 0, (lastnz - lastnz2) * sizeof(*xq)); + } + + /* Truncation of LSBs */ + test(); + IF (mode > 0 && sub(totBits, target) > 0) + { + *lsbMode = 1; + move16(); + } + ELSE + { + *lsbMode = 0; + move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +# endif /* ENABLE_HR_MODE */ diff --git a/lib_lc3plus/reorder_bitstream.c b/lib_lc3plus/reorder_bitstream.c deleted file mode 100644 index 118a05b6e..000000000 --- a/lib_lc3plus/reorder_bitstream.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - - -void processReorderBitstream_fl(LC3_UINT8* bytes, LC3_INT32 n_pccw, LC3_INT32 n_pc, LC3_INT32 b_left, LC3_INT32 len) -{ - LC3_UINT8 bytes_local[MAX_NBYTES2]; - LC3_INT32 i, block_bytes; - - assert(b_left > 0); - - memcpy(bytes_local, bytes, len * sizeof(LC3_UINT8)); - - if (n_pccw == 0) - { - return; - } - - block_bytes = ceil((LC3_FLOAT) n_pc / 2.0); - - for (i = 0; i < block_bytes; i++) - { - bytes[i] = bytes_local[b_left + i]; - } - - for (i = 0; i < b_left; i++) - { - bytes[block_bytes + i] = bytes_local[i]; - } -} - diff --git a/lib_lc3plus/reorder_bitstream_fx.c b/lib_lc3plus/reorder_bitstream_fx.c new file mode 100644 index 000000000..281eef325 --- /dev/null +++ b/lib_lc3plus/reorder_bitstream_fx.c @@ -0,0 +1,56 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "defines.h" + +#include "constants.h" +#include "functions.h" + + +void processReorderBitstream_fx(UWord8 *bytes, Word16 n_pccw, Word16 n_pc, Word16 b_left, Word8 *scratchBuffer) +{ + Word16 block_bytes; + UWord8 * bytes_tmp; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Word16 block_bits, block_bytes; + UWord8 * bytes_tmp; + }; + Dyn_Mem_In("processReorderBitstream_fx", sizeof(struct _dynmem)); +#endif + + bytes_tmp = (UWord8 *)scratchAlign(scratchBuffer, 0); /* Size = LC3PLUS_MAX_BYTES */ + + if (n_pccw == 0) + { +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return; + } + + assert(b_left >= 0); + + /* set block size in bits and full bytes */ + block_bytes = shr_sat(add(n_pc, 1), 1); + + /* rearrange bitstream */ + basop_memmove(&bytes_tmp[0], &bytes[b_left], block_bytes * sizeof(UWord8)); + basop_memmove(&bytes_tmp[block_bytes], &bytes[0], b_left * sizeof(UWord8)); + + basop_memmove(&bytes[0], &bytes_tmp[0], add(block_bytes, b_left) * sizeof(UWord8)); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/resamp12k8.c b/lib_lc3plus/resamp12k8.c deleted file mode 100644 index 295b6e7f2..000000000 --- a/lib_lc3plus/resamp12k8.c +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], - LC3_INT mem_out_len, LC3_FLOAT y[], LC3_INT* y_len, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT fs) -{ - - - LC3_INT len_12k8, N12k8, i, k; - LC3_FLOAT mac, bufdown[128], buf[120 + MAX_LEN]; - LC3_INT32 index_int, index_frac, resamp_upfac, resamp_delay, resamp_off_int, resamp_off_frac; - LC3_FLOAT u_11, u_21, u_1, u_2; - const LC3_FLOAT *filter; - const LC3_FLOAT *filt_input, *filt_coeff; - - switch (frame_dms) - { - case 25: - len_12k8 = LEN_12K8 / 4; - break; - case 50: - len_12k8 = LEN_12K8 / 2; - break; -#ifdef CR8_G_ADD_75MS - case 75: - len_12k8 = (LEN_12K8 / 4) * 3; - break; -#endif - case 100: - len_12k8 = LEN_12K8; - break; - } - - *y_len = len_12k8; - N12k8 = x_len * 12800 / fs; - - /* Init Input Buffer */ - memmove(buf, mem_in, mem_in_len * sizeof(LC3_FLOAT)); - memmove(&buf[mem_in_len], x, x_len * sizeof(LC3_FLOAT)); - memmove(mem_in, &buf[x_len], mem_in_len * sizeof(LC3_FLOAT)); - - filter = lp_filter[fs_idx]; - - /* Upsampling & Low-pass Filtering & Downsampling */ - - index_int = 1; - index_frac = 0; - resamp_upfac = resamp_params[fs_idx][0]; - resamp_delay = resamp_params[fs_idx][1]; - resamp_off_int = resamp_params[fs_idx][2]; - resamp_off_frac = resamp_params[fs_idx][3]; - - k = 0; - for (i = 0; i < N12k8; i++) { - - filt_input = &buf[index_int]; - filt_coeff = &filter[index_frac * resamp_delay * 2]; - - mac = mac_loop(filt_input, filt_coeff, (2 * resamp_delay)); - - bufdown[k++] = mac; - - index_int = index_int + resamp_off_int; - index_frac = index_frac + resamp_off_frac; - - if ((resamp_upfac - index_frac) <= 0) - { - index_int = index_int + 1; - index_frac = index_frac - resamp_upfac; - } - } - - - /* 50Hz High-Pass */ - u_11 = mem_50[0]; - u_21 = mem_50[1]; - - for (i = 0; i < len_12k8; i++) { - LC3_FLOAT y1 = (highpass50_filt_b[0] * bufdown[i] + u_11); - u_1 = (highpass50_filt_b[1] * bufdown[i] + u_21) - highpass50_filt_a[1] * y1; - u_2 = highpass50_filt_b[2] * bufdown[i] - highpass50_filt_a[2] * y1; - u_11 = u_1; - u_21 = u_2; - bufdown[i] = (LC3_FLOAT)y1; - } - - mem_50[0] = (LC3_FLOAT)u_11; - mem_50[1] = (LC3_FLOAT)u_21; - - /* Output Buffer */ - memmove(buf, mem_out, mem_out_len * sizeof(LC3_FLOAT)); - - memmove(&buf[mem_out_len], bufdown, len_12k8 * sizeof(LC3_FLOAT)); - - memmove(y, buf, (*y_len + 1) * sizeof(LC3_FLOAT)); - - memmove(mem_out, &buf[N12k8], mem_out_len * sizeof(LC3_FLOAT)); -} diff --git a/lib_lc3plus/resamp12k8_fx.c b/lib_lc3plus/resamp12k8_fx.c new file mode 100644 index 000000000..a54f6bc29 --- /dev/null +++ b/lib_lc3plus/resamp12k8_fx.c @@ -0,0 +1,121 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void process_resamp12k8_fx(Word16 x[], Word16 x_len, Word16 mem_in[], Word16 mem_in_len, Word32 mem_50[], + Word16 mem_out[], Word16 mem_out_len, Word16 y[], Word16 *y_len, Word16 fs_idx, + Word16 frame_dms, Word8 *scratchBuffer + , Word16 bps + ) +{ + Dyn_Mem_Deluxe_In( + Word16 * buf; + Word16 index_int, index_frac, len_12k8; + Word16 resamp_upfac, resamp_off_int, resamp_off_frac, resamp_delay; + const Word16 *resamp_filt; + const Word16 *filt_coeff; + Word16 * filt_input; + Word32 filt_output, mem_50_0, mem_50_1; + Counter n, m; + Word32 L_tmp; + ); + + buf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * (MAX_LEN + MAX_LEN / 8) bytes */ + + /* resamp parameters : {upsample-factor, 120 / upsample-factor, down_sample_int_part, down_sample_frac_part } + upsample is to 384 kHz. upsample-facor = 192000 / samp-freq + Fractional downsample parameters are calculated from : downsample samp-freq to 128000 + At 48000 sampling frequency: + upsample-factor = 192000 / 48000 = 4 + 120 / upsample-factor = 120 / 4 = 30 + downsample-ratio = 48000 / 12800 = 3.75 + down_sample_int_part = 3 + down_sample_frac_part = int(0.75 * upsample-factor ) = 0.75 * 4 = 3 + */ + resamp_upfac = resamp_params[fs_idx][0]; move16(); + resamp_delay = resamp_params[fs_idx][1]; move16(); + resamp_off_int = resamp_params[fs_idx][2]; move16(); + resamp_off_frac = resamp_params[fs_idx][3]; move16(); + resamp_filt = resamp_filts[fs_idx]; move16(); + + len_12k8 = LEN_12K8 / 4 * (frame_dms / 25); move16(); + *y_len = len_12k8; move16(); + + /* Init Input Buffer */ + basop_memmove(buf, mem_in, mem_in_len * sizeof(Word16)); + basop_memmove(&buf[mem_in_len], x, x_len * sizeof(Word16)); + basop_memmove(mem_in, &buf[x_len], mem_in_len * sizeof(Word16)); + + /* Init Input Indices */ + index_int = 1; move16(); + index_frac = 0; move16(); + + /* Resampling */ + FOR (n = 0; n < len_12k8; n++) + { + /* Init Filtering */ + filt_input = &buf[index_int]; + filt_coeff = &resamp_filt[index_frac * resamp_delay * 2]; + +/* Perform Filtering */ + filt_output = L_mult0(*filt_input, *filt_coeff); + FOR (m = 1; m < resamp_delay * 2; m++) + { + filt_coeff++; + filt_input++; + if (*filt_coeff) + { + filt_output = L_mac0(filt_output, *filt_input, *filt_coeff); + } + } + y[n] = round_fx(filt_output); move16(); + + /* Update Input Indices */ + index_int = add(index_int, resamp_off_int); + index_frac = add(index_frac, resamp_off_frac); + IF (sub(resamp_upfac, index_frac) <= 0) + { + index_int = add(index_int, 1); + index_frac = sub(index_frac, resamp_upfac); + } + } + + /* High Pass Filtering (-3dB at 50Hz) */ + mem_50_0 = mem_50[0]; move32(); + mem_50_1 = mem_50[1]; move32(); + + FOR (n = 0; n < len_12k8; n++) + { + filt_output = L_mac0_sat(mem_50_0, highpass50_filt_num[0], y[n]); + L_tmp = L_mac0(Mpy_32_16_lc3plus(filt_output, highpass50_filt_den[0]), highpass50_filt_num[1], y[n]); + + IF (sub(bps, 24) == 0) + { + mem_50_0 = L_shl_sat(L_add_sat(L_shr_pos(mem_50_1,1), L_tmp), 1); + } ELSE + { + mem_50_0 = L_add_sat(mem_50_1, L_shl_sat(L_tmp, 1)); + } + + mem_50_1 = L_mac0(Mpy_32_16_lc3plus(filt_output, highpass50_filt_den[1]), highpass50_filt_num[2], y[n]); + y[n] = round_fx_sat(filt_output); move16(); + } + mem_50[0] = mem_50_0; move32(); + mem_50[1] = mem_50_1; move32(); + +/* Output Buffer */ + basop_memmove(buf, mem_out, mem_out_len * sizeof(Word16)); + basop_memmove(&buf[mem_out_len], y, len_12k8 * sizeof(Word16)); + basop_memmove(y, buf, (*y_len + 1) * sizeof(Word16)); + basop_memmove(mem_out, &buf[len_12k8], mem_out_len * sizeof(Word16)); + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/residual_coding.c b/lib_lc3plus/residual_coding.c deleted file mode 100644 index 777b97d73..000000000 --- a/lib_lc3plus/residual_coding.c +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t* resBits, LC3_INT* numResBits - , LC3_INT hrmode -) -{ - LC3_INT n = 0, m = 0, k = 0; - LC3_INT iter=0; - LC3_FLOAT offset; - LC3_INT iter_max = 1; - LC3_INT nz_idx[MAX_LEN]; - LC3_INT N_nz = 0, idx = 0; - - - memset(resBits, 0, MAX_RESBITS_LEN); - - m = targetBits - nBits + 4; - if (hrmode) - { - m += 10; - } - - assert(m <= MAX_RESBITS); - - offset = .25; - if (hrmode) - { - iter_max = EXT_RES_ITER_MAX; - - } - for (k = 0; k < L_spec; k ++) - { - if (xq[k]) - { - nz_idx[N_nz ++] = k; - } - } - while (iter < iter_max && n < m) - { - k = 0; - while (k < N_nz && n < m) - { - idx = nz_idx[k]; - - if (x[idx] >= (LC3_FLOAT)xq[idx] * gain) - { - resBits[n >> 3] |= 1 << (n & 7); - x[idx] -= gain * offset; - } - else - { - resBits[n >> 3] &= ~(1 << (n & 7)); - x[idx] += gain * offset; - } - - n++; - - k++; - } - iter ++; - offset *= .5; - } - - *numResBits = n; -} diff --git a/lib_lc3plus/residual_coding_fx.c b/lib_lc3plus/residual_coding_fx.c new file mode 100644 index 000000000..2cb6c791f --- /dev/null +++ b/lib_lc3plus/residual_coding_fx.c @@ -0,0 +1,238 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +#ifdef ENABLE_HR_MODE + +void processResidualCoding_fx(Word16 x_e, Word32 x[], + Word32 xq[], Word32 gain, + Word16 gain_e, Word16 L_spec, + Word16 targetBits, Word16 nBits, UWord8 *resBits, Word16 *numResBits + , Word16 hrmode +) +{ + + Counter i; + Word16 s, n, m; + Word32 L_tmp; + Word16 iter = 0; + Counter idx; + Word16 N_nz = 0; + Word16 n1, n2; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processResidualCoding_fx", sizeof(struct { + Counter i; + Word16 s, n, m; + Word32 L_tmp; + Word16 iter; + Counter idx; + Word16 N_nz; + Word16 *nz_idx; + Word16 n1, n2; + })); +#endif + + n = 0; + move16(); + + IF (hrmode) + { + m = add(sub(targetBits, nBits), 14); + assert(m <= (MAX_RESBITS_LEN << RESBITS_PACK_SHIFT)); + } + ELSE + { + m = add(sub(targetBits, nBits), 4); + if (m > L_spec) + { + m = L_spec; + } + } + + basop_memset(resBits, 0, sizeof(*resBits)*((m + RESBITS_PACK_MASK) >> RESBITS_PACK_SHIFT)); + + s = sub(add(15, gain_e), x_e); + + IF(hrmode) + { + /* + x = xval * 2^(31 - x_e) + gain = gainval * 2^(15 - gain_e) + + To bring gain to the same q of x : + + gain (in_Qx_e) = gain * 2^(16 + gain_e - x_e) + + gain*offset (in Qx_e) = gain (in_Qx_e) * 0.25 = gain (in_Qx_e) / 4 = gain * 2^(16 - 2 + gain_e - x_e) + */ + Word16 shift_val; + shift_val = sub(sub(gain_e, x_e), 2); + + Word32 gain_offset; + + IF (shift_val <= -32) + gain_offset = 0; + ELSE + { + gain_offset = L_shl_sat(gain, shift_val); + } + + Word16 exit_iter = 0; + + Word16 nz_idx[MAX_LEN]; + + /* enumerate non-zero coefficients */ + FOR (i = 0; i < L_spec; i++) + { + IF (xq[i]) + { + nz_idx[N_nz] = i; move16(); + N_nz = add(N_nz, 1); + } + } + + s = sub(31, sub(x_e, gain_e)); + FOR (iter = 0; iter < EXT_RES_ITER_MAX; iter++) + { + FOR (i = 0; i < N_nz; i++) + { + idx = nz_idx[i]; + + L_tmp = L_sub(x[idx], Mpy_32_32_lc3plus(L_shl(xq[idx], s), gain)); + + IF (L_tmp >= 0) + { + n1 = shr(n, RESBITS_PACK_SHIFT); + n2 = s_and(n, RESBITS_PACK_MASK); + resBits[n1] = (UWord8)s_or(resBits[n1], shl(1, n2)); + move16(); + x[idx] = L_sub(x[idx], gain_offset); + move16(); + } + ELSE + { + move16(); + x[idx] = L_add(x[idx], gain_offset); + move16(); + } + n = add(n, 1); + IF (sub(n, m) == 0) + { + exit_iter = 1; + BREAK; + } + } + gain_offset = L_shr(gain_offset, 1); /* offset *= 0.5 */ + + IF (exit_iter) + { + BREAK; + } + } + } + ELSE + { + s = add(s, 16); + gain = round_fx(gain); + + FOR (i = 0; i < L_spec; i++) + { + IF (xq[i] != 0) + { + L_tmp = L_sub(x[i], Mpy_32_16_lc3plus(L_shl(xq[i], s), gain)); + if (L_tmp >= 0) + { + n1 = shr(n, RESBITS_PACK_SHIFT); + n2 = s_and(n, RESBITS_PACK_MASK); + resBits[n1] = (UWord8) s_or(resBits[n1], shl(1, n2)); + move16(); + } + n = add(n, 1); + IF (sub(n, m) == 0) + { + BREAK; + } + } + } + } + *numResBits = n; + move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#else + +void processResidualCoding_fx(Word16 x_e, Word32 x[], + Word16 xq[], + Word16 gain, Word16 gain_e, Word16 L_spec, + Word16 targetBits, Word16 nBits, UWord8 *resBits, Word16 *numResBits +) +{ + + Counter i; + Word16 s, n, m; + Word32 L_tmp; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processResidualCoding_fx", sizeof(struct { + Counter i; + Word16 s, n, m; + Word32 L_tmp; + })); +#endif + + n = 0; + move16(); + { + m = add(sub(targetBits, nBits), 4); + if (m > L_spec) + { + m = L_spec; + } + } + + + s = sub(add(15, gain_e), x_e); + { + FOR (i = 0; i < L_spec; i++) + { + IF (xq[i] != 0) + { + L_tmp = L_sub(x[i], L_shl(L_mult(xq[i], gain), s)); + if (L_tmp < 0) + { + resBits[n] = 0; + move16(); + } + if (L_tmp >= 0) + { + resBits[n] = 1; + move16(); + } + n = add(n, 1); + IF (sub(n, m) == 0) + { + BREAK; + } + } + } + } + *numResBits = n; + move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#endif diff --git a/lib_lc3plus/residual_decoding.c b/lib_lc3plus/residual_decoding.c deleted file mode 100644 index 90084c981..000000000 --- a/lib_lc3plus/residual_decoding.c +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits - , LC3_INT hrmode -) -{ - LC3_INT k = 0, n = 0; - LC3_FLOAT offset1 = 0, offset2 = 0; - LC3_FLOAT offset = 0; - LC3_INT nz_idx[MAX_LEN]; - LC3_INT N_nz = 0, idx = 0; - - LC3_INT iter = 0, iter_max = 1; - - if (hrmode) - { - iter_max = EXT_RES_ITER_MAX; - offset = offset1 = offset2 = 0.25; - } - else - { - offset1 = 0.1875; - offset2 = 0.3125; - } - - if (hrmode) - { - /* enumerat non-zero coefficients */ - for (k = 0; k < L_spec; k ++) - { - if (x[k]) - { - nz_idx[N_nz ++] = k; - } - } - /* apply residual corrections */ - while (n < resQBits && iter < iter_max) - { - for (k = 0; k < N_nz; k ++) - { - idx = nz_idx[k]; - - if ((prm[n >> 3] & 1 << (n & 7)) == 0) - { - x[idx] -= offset; - } - else - { - - x[idx] += offset; - } - if (++n >= resQBits) - { - break; - } - } - offset *= 0.5; - iter ++; - } - } - else - { - while (k < L_spec && n < resQBits) { - if (x[k] != 0) { - if ((prm[n >> 3] & 1 << (n & 7)) == 0) - { - if (x[k] > 0) { - x[k] -= offset1; - } else { - x[k] -= offset2; - } - } else { - if (x[k] > 0) { - x[k] += offset2; - } else { - x[k] += offset1; - } - } - n++; - } - - k++; - } - } - *bitsRead = n; -} diff --git a/lib_lc3plus/residual_decoding_fx.c b/lib_lc3plus/residual_decoding_fx.c new file mode 100644 index 000000000..686398cdd --- /dev/null +++ b/lib_lc3plus/residual_decoding_fx.c @@ -0,0 +1,207 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +#ifdef ENABLE_HR_MODE /* HRMODE enables packing of residual bits */ + +void processResidualDecoding_fx(Word32 x[], Word16 x_e, Word16 L_spec, UWord8 prm[], Word16 resQBits +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + + Counter i; + Word32 fac_m, fac_p; + Word16 s, bits; + Word32 tmp; + Counter idx; + Word16 N_nz = 0; + Word16 iter; + Word32 fac_hr; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processResidualDecoding_fx", sizeof(struct { + Counter i; + Word32 fac_m, fac_p; + Word16 s, bits; + Word32 tmp; + Counter idx; + Word16 N_nz; + Word16 *nz_idx; + Word16 iter; + })); +#endif + + tmp = 0; + s = sub(x_e, 1); + s = s_min(s, 31); + + IF (hrmode) + { + fac_hr = L_shr(0x10000000, s); /* 0.25 in 1Q30 */ + } + ELSE + { + fac_m = L_shr(0xC000000, s); /* 0.1875 in 1Q30 */ + fac_p = L_shr(0x14000000, s); /* 0.3125 in 1Q30 */ + } + + bits = 0; + move16(); + + Word16 nz_idx[MAX_LEN]; + + IF (hrmode) + { + FOR (i = 0; i < L_spec; i++) + { + IF (x[i]) + { + nz_idx[N_nz] = i; move16(); + N_nz = add(N_nz, 1); + } + } + FOR (iter = 0; iter < EXT_RES_ITER_MAX; iter++) + { + IF (sub(bits, resQBits) >= 0) + { + BREAK; + } + FOR (i = 0; i < N_nz; i++) + { + idx = nz_idx[i]; move16(); + + IF (sub(bits, resQBits) >= 0) + { + BREAK; + } + + IF (! (s_and(prm[shr(bits, RESBITS_PACK_SHIFT)], shl(1, s_and(bits, RESBITS_PACK_MASK))))) + { + tmp = L_sub_sat(x[idx], fac_hr); + } + ELSE + { + tmp = L_add_sat(x[idx], fac_hr); + } + x[idx] = tmp; + move32(); + bits = add(bits, 1); + } + fac_hr = L_shr(fac_hr, 1); + } + } + ELSE + { + FOR (i = 0; i < L_spec; i++) + { + IF (sub(bits, resQBits) >= 0) + { + BREAK; + } + + IF (x[i] != 0) + { + IF (! (s_and(prm[shr(bits, RESBITS_PACK_SHIFT)], shl(1, s_and(bits, RESBITS_PACK_MASK))))) + { + if (x[i] > 0) + tmp = L_sub(x[i], fac_m); + if (x[i] < 0) + tmp = L_sub(x[i], fac_p); + } + ELSE + { + if (x[i] > 0) + tmp = L_add(x[i], fac_p); + if (x[i] < 0) + tmp = L_add(x[i], fac_m); + } + x[i] = tmp; + move32(); + bits = add(bits, 1); + } + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#else + +void processResidualDecoding_fx(Word32 x[], Word16 x_e, Word16 L_spec, UWord8 prm[], Word16 resQBits +) +{ + + Counter i; + Word32 fac_m, fac_p; + Word16 s, bits; + Word32 tmp; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processResidualDecoding_fx", sizeof(struct { + Counter i; + Word32 fac_m, fac_p; + Word16 s, bits; + Word32 tmp; + })); +#endif + + tmp = 0; + s = sub(x_e, 1); + s = s_min(s, 31); + + { + fac_m = L_shr(0xC000000, s); /* 0.1875 in 1Q30 */ + fac_p = L_shr(0x14000000, s); /* 0.3125 in 1Q30 */ + } + + bits = 0; + move16(); + + { + FOR (i = 0; i < L_spec; i++) + { + IF (sub(bits, resQBits) >= 0) + { + BREAK; + } + + IF (x[i] != 0) + { + IF (prm[bits] == 0) + { + if (x[i] > 0) + tmp = L_sub(x[i], fac_m); + if (x[i] < 0) + tmp = L_sub(x[i], fac_p); + } + ELSE + { + if (x[i] > 0) + tmp = L_add(x[i], fac_p); + if (x[i] < 0) + tmp = L_add(x[i], fac_m); + } + x[i] = tmp; + move32(); + bits = add(bits, 1); + } + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#endif diff --git a/lib_lc3plus/rom_basop_util.c b/lib_lc3plus/rom_basop_util.c new file mode 100644 index 000000000..e37b4bfad --- /dev/null +++ b/lib_lc3plus/rom_basop_util.c @@ -0,0 +1,2904 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "rom_basop_util.h" +#include "basop_util_lc3plus.h" +#include "functions.h" + + +/* clang-format off */ +# ifdef ENABLE_HR_MODE +# define STC(x) (x) +# define WTC(x) (x) +# define STCP(a, b) {{STC(a), STC(b)}} +# define WTCP(a, b) {{WTC(a), WTC(b)}} +# else +# define STC(x) WORD322WORD16(x) +# define WTC(x) WORD322WORD16(x) +# define STCP(a, b) {{STC(a), STC(b)}} +# define WTCP(a, b) {{WTC(a), WTC(b)}} +# endif +/* clang-format on */ + +/** + * \brief Lookup-Table for binary logarithm + */ +RAM_ALIGN const Word16 ldCoeff_lc3plus[7] = {-32768, -16384, -10923, -8192, -6554, -5461, -4681}; + +/** + \brief Lookup-Table for binary power algorithm + + This table is used for lookup 2^x with + x in range [0...1.0[ in steps of 1/32 +*/ +const UWord32 exp2_tab_long_lc3plus[32] = { + 0x40000000, 0x4166C34C, 0x42D561B4, 0x444C0740, 0x45CAE0F2, 0x47521CC6, 0x48E1E9BA, 0x4A7A77D4, + 0x4C1BF829, 0x4DC69CDD, 0x4F7A9930, 0x51382182, 0x52FF6B55, 0x54D0AD5A, 0x56AC1F75, 0x5891FAC1, + 0x5A82799A, 0x5C7DD7A4, 0x5E8451D0, 0x60962665, 0x62B39509, 0x64DCDEC3, 0x6712460B, 0x69540EC9, + 0x6BA27E65, 0x6DFDDBCC, 0x70666F76, 0x72DC8374, 0x75606374, 0x77F25CCE, 0x7A92BE8B, 0x7D41D96E, +}; + +/** + \brief Lookup-Table for binary power algorithm + + This table is used for lookup 2^x with + x in range [0...1/32[ in steps of 1/1024 +*/ +const UWord32 exp2w_tab_long_lc3plus[32] = { + 0x40000000, 0x400B1818, 0x4016321B, 0x40214E0C, 0x402C6BE9, 0x40378BB4, 0x4042AD6D, 0x404DD113, + 0x4058F6A8, 0x40641E2B, 0x406F479E, 0x407A7300, 0x4085A051, 0x4090CF92, 0x409C00C4, 0x40A733E6, + 0x40B268FA, 0x40BD9FFF, 0x40C8D8F5, 0x40D413DD, 0x40DF50B8, 0x40EA8F86, 0x40F5D046, 0x410112FA, + 0x410C57A2, 0x41179E3D, 0x4122E6CD, 0x412E3152, 0x41397DCC, 0x4144CC3B, 0x41501CA0, 0x415B6EFB, +}; + +/** + \brief Lookup-Table for binary power algorithm + + This table is used for lookup 2^x with + x in range [0...1/1024[ in steps of 1/32768 +*/ +const UWord32 exp2x_tab_long_lc3plus[32] = { + 0x40000000, 0x400058B9, 0x4000B173, 0x40010A2D, 0x400162E8, 0x4001BBA3, 0x4002145F, 0x40026D1B, + 0x4002C5D8, 0x40031E95, 0x40037752, 0x4003D011, 0x400428CF, 0x4004818E, 0x4004DA4E, 0x4005330E, + 0x40058BCE, 0x4005E48F, 0x40063D51, 0x40069613, 0x4006EED5, 0x40074798, 0x4007A05B, 0x4007F91F, + 0x400851E4, 0x4008AAA8, 0x4009036E, 0x40095C33, 0x4009B4FA, 0x400A0DC0, 0x400A6688, 0x400ABF4F, +}; + +/* square root tables */ +const Word32 SqrtTable_lc3plus[32] = { + /* Q31 */ + 0x5A82D429, 0x5BEA10FE, 0x5D4BE6E5, 0x5EA89270, 0x60004BE2, 0x615347A1, 0x62A1B68C, 0x63EBC651, + 0x6531A1B5, 0x667370D4, 0x67B1595F, 0x68EB7EC8, 0x6A220277, 0x6B5503F0, 0x6C84A0F9, 0x6DB0F5BD, + 0x6EDA1CE9, 0x70002FC7, 0x7123465A, 0x72437773, 0x7360D8C5, 0x747B7EFA, 0x75937DC4, 0x76A8E7EB, + 0x77BBCF60, 0x78CC4545, 0x79DA5A00, 0x7AE61D3E, 0x7BEF9E07, 0x7CF6EAC2, 0x7DFC113F, 0x7EFF1EC0, +}; + +const Word16 SqrtDiffTable_lc3plus[32] = { + /* Q21 */ + 0x59CF, 0x5875, 0x572B, 0x55EE, 0x54BF, 0x539C, 0x5284, 0x5177, 0x5074, 0x4F7A, 0x4E89, + 0x4DA1, 0x4CC0, 0x4BE7, 0x4B15, 0x4A4A, 0x4985, 0x48C6, 0x480C, 0x4758, 0x46AA, 0x4600, + 0x455B, 0x44BA, 0x441D, 0x4385, 0x42F1, 0x4260, 0x41D3, 0x414A, 0x40C3, 0x4040, +}; + +const Word32 ISqrtTable_lc3plus[32] = { + /* Q31 */ + 0x7FFE7F85, 0x7E0A4E25, 0x7C2C56C7, 0x7A63002C, 0x78ACD922, 0x7708939D, 0x75750088, 0x73F10C2D, + 0x727BBB1A, 0x71142774, 0x6FB97EA5, 0x6E6AFF54, 0x6D27F79D, 0x6BEFC388, 0x6AC1CBA4, 0x699D83DA, + 0x68826A53, 0x6770068E, 0x6665E882, 0x6563A7DF, 0x6468E364, 0x63754043, 0x62886999, 0x61A20FEE, + 0x60C1E8C8, 0x5FE7AE45, 0x5F131EBE, 0x5E43FC76, 0x5D7A0D4F, 0x5CB51A81, 0x5BF4F061, 0x5B395E26, +}; + +const Word16 ISqrtDiffTable_lc3plus[32] = { + /* Q21 */ + 0x7D0C, 0x777E, 0x7256, 0x6D8A, 0x6911, 0x64E5, 0x60FD, 0x5D54, 0x59E5, 0x56AA, 0x53A0, + 0x50C2, 0x4E0D, 0x4B7E, 0x4912, 0x46C6, 0x4499, 0x4288, 0x4090, 0x3EB1, 0x3CE9, 0x3B36, + 0x3996, 0x380A, 0x368F, 0x3524, 0x33C9, 0x327C, 0x313D, 0x300B, 0x2EE5, 0x2DCA, +}; + +/* 1/x tables */ +const Word32 InvTable_lc3plus[32] = { + /* Q31 */ + 0x7FFBFE40, 0x7C1B608E, 0x78752176, 0x750440BA, 0x71C44C49, 0x6EB14D0A, 0x6BC7B6B4, 0x69045A19, + 0x6664598A, 0x63E51EE2, 0x61845308, 0x5F3FD698, 0x5D15BB8E, 0x5B043FD0, 0x5909C861, 0x5724DD3C, + 0x555425B2, 0x53966532, 0x51EA787F, 0x504F5331, 0x4EC3FD84, 0x4D479267, 0x4BD93DBE, 0x4A783ADC, + 0x4923D31D, 0x47DB5CAE, 0x469E3974, 0x456BD608, 0x4443A8D9, 0x43253159, 0x420FF746, 0x41038A01, +}; + +#ifdef ENABLE_HR_MODE +const Word16 InvIntTable[74] = { + 32767, 32767, 16384, 10923, 8192, 6554, 5461, 4681, 4096, 3641, 3277, 2979, 2731, 2521, 2341, + 2185, 2048, 1928, 1820, 1725, 1638, 1560, 1489, 1425, 1365, 1311, 1260, 1214, 1170, 1130, + 1092, 1057, 1024, 993, 964, 936, 910, 886, 862, 840, 819, 799, 780, 762, 745, + 728, 712, 697, 683, 669, 655, 643, 630, 618, 607, 596, 585, 575, 565, 555, + 546, 537, 529, 520, 512, 504, 496, 489, 482, 475, 468, 462, 455, 449 +}; +#else +const Word16 InvIntTable[32] = { + 0x7FFF, 0x7FFF, 0x4000, 0x2AAB, 0x2000, 0x199A, 0x1555, 0x1249, 0x1000, 0x0E39, 0x0CCD, + 0x0BA3, 0x0AAB, 0x09D9, 0x0925, 0x0889, 0x0800, 0x0788, 0x071C, 0x06BD, 0x0666, 0x0618, + 0x05D1, 0x0591, 0x0555, 0x051F, 0x04EC, 0x04BE, 0x0492, 0x046A, 0x0444, 0x0421, +}; +#endif + +const Word16 InvDiffTable_lc3plus[32] = { + /* Q20 */ + 0x7C14, 0x74C8, 0x6E1C, 0x67FF, 0x6260, 0x5D33, 0x586C, 0x5400, 0x4FE7, 0x4C19, 0x4890, + 0x4543, 0x422F, 0x3F4F, 0x3C9D, 0x3A17, 0x37B8, 0x357E, 0x3365, 0x316B, 0x2F8D, 0x2DCB, + 0x2C20, 0x2A8D, 0x290F, 0x27A4, 0x264C, 0x2506, 0x23CF, 0x22A7, 0x218E, 0x2081, +}; + +/* + Sine tables + */ +# ifdef ENABLE_HR_MODE +const PWord32 SineTable480[] = { +# else +const PWord16 SineTable480[] = { +# endif + STCP(0x7fffffff, 0x00000000), STCP(0x7fffd315, 0x006b3b9b), STCP(0x7fff4c54, 0x00d676eb), + STCP(0x7ffe6bbf, 0x0141b1a5), STCP(0x7ffd3154, 0x01aceb7c), STCP(0x7ffb9d15, 0x02182427), + STCP(0x7ff9af04, 0x02835b5a), STCP(0x7ff76721, 0x02ee90c8), STCP(0x7ff4c56f, 0x0359c428), + STCP(0x7ff1c9ef, 0x03c4f52f), STCP(0x7fee74a2, 0x0430238f), STCP(0x7feac58d, 0x049b4f00), + STCP(0x7fe6bcb0, 0x05067734), STCP(0x7fe25a0f, 0x05719be2), STCP(0x7fdd9dad, 0x05dcbcbe), + STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd317b4, 0x06b2f1d2), STCP(0x7fcd4e24, 0x071e0575), + STCP(0x7fc72ae2, 0x07891418), STCP(0x7fc0adf2, 0x07f41d72), STCP(0x7fb9d759, 0x085f2137), + STCP(0x7fb2a71b, 0x08ca1f1b), STCP(0x7fab1d3d, 0x093516d4), STCP(0x7fa339c5, 0x09a00817), + STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f92661d, 0x0a75d60e), STCP(0x7f8975f9, 0x0ae0b22c), + STCP(0x7f802c52, 0x0b4b86a8), STCP(0x7f76892f, 0x0bb65336), STCP(0x7f6c8c96, 0x0c21178c), + STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f578721, 0x0cf68662), STCP(0x7f4c7e54, 0x0d61304e), + STCP(0x7f411c2f, 0x0dcbd0d5), STCP(0x7f3560b9, 0x0e3667ad), STCP(0x7f294bfd, 0x0ea0f48c), + STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7f1016ce, 0x0f75ef33), STCP(0x7f02f66f, 0x0fe05c64), + STCP(0x7ef57cea, 0x104abe71), STCP(0x7ee7aa4c, 0x10b5150f), STCP(0x7ed97e9c, 0x111f5ff4), + STCP(0x7ecaf9e5, 0x11899ed3), STCP(0x7ebc1c31, 0x11f3d164), STCP(0x7eace58a, 0x125df75b), + STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e8d6d91, 0x13321c53), STCP(0x7e7d2c54, 0x139c1abf), + STCP(0x7e6c9251, 0x14060b68), STCP(0x7e5b9f93, 0x146fee03), STCP(0x7e4a5426, 0x14d9c245), + STCP(0x7e38b017, 0x154387e6), STCP(0x7e26b371, 0x15ad3e9a), STCP(0x7e145e42, 0x1616e618), + STCP(0x7e01b096, 0x16807e15), STCP(0x7deeaa7a, 0x16ea0646), STCP(0x7ddb4bfc, 0x17537e63), + STCP(0x7dc79529, 0x17bce621), STCP(0x7db3860f, 0x18263d36), STCP(0x7d9f1ebd, 0x188f8357), + STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d7547a7, 0x1961db9b), STCP(0x7d5fd801, 0x19caed29), + STCP(0x7d4a105d, 0x1a33ec9c), STCP(0x7d33f0ca, 0x1a9cd9ac), STCP(0x7d1d7958, 0x1b05b40f), + STCP(0x7d06aa16, 0x1b6e7b7a), STCP(0x7cef8315, 0x1bd72fa4), STCP(0x7cd80464, 0x1c3fd045), + STCP(0x7cc02e15, 0x1ca85d12), STCP(0x7ca80038, 0x1d10d5c2), STCP(0x7c8f7ade, 0x1d793a0b), + STCP(0x7c769e18, 0x1de189a6), STCP(0x7c5d69f7, 0x1e49c447), STCP(0x7c43de8e, 0x1eb1e9a7), + STCP(0x7c29fbee, 0x1f19f97b), STCP(0x7c0fc22a, 0x1f81f37c), STCP(0x7bf53153, 0x1fe9d75f), + STCP(0x7bda497d, 0x2051a4dd), STCP(0x7bbf0aba, 0x20b95bac), STCP(0x7ba3751d, 0x2120fb83), + STCP(0x7b8788ba, 0x2188841a), STCP(0x7b6b45a5, 0x21eff528), STCP(0x7b4eabf1, 0x22574e65), + STCP(0x7b31bbb2, 0x22be8f87), STCP(0x7b1474fd, 0x2325b847), STCP(0x7af6d7e6, 0x238cc85d), + STCP(0x7ad8e482, 0x23f3bf7e), STCP(0x7aba9ae6, 0x245a9d65), STCP(0x7a9bfb27, 0x24c161c7), + STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a5db997, 0x258e9ce0), STCP(0x7a3e17f2, 0x25f51307), + STCP(0x7a1e2082, 0x265b6e8a), STCP(0x79fdd35c, 0x26c1af22), STCP(0x79dd3098, 0x2727d486), + STCP(0x79bc384d, 0x278dde6e), STCP(0x799aea92, 0x27f3cc94), STCP(0x7979477d, 0x28599eb0), + STCP(0x79574f28, 0x28bf547b), STCP(0x793501a9, 0x2924edac), STCP(0x79125f19, 0x298a69fc), + STCP(0x78ef678f, 0x29efc925), STCP(0x78cc1b26, 0x2a550adf), STCP(0x78a879f4, 0x2aba2ee4), + STCP(0x78848414, 0x2b1f34eb), STCP(0x7860399e, 0x2b841caf), STCP(0x783b9aad, 0x2be8e5e8), + STCP(0x7816a759, 0x2c4d9050), STCP(0x77f15fbc, 0x2cb21ba0), STCP(0x77cbc3f2, 0x2d168792), + STCP(0x77a5d413, 0x2d7ad3de), STCP(0x777f903c, 0x2ddf0040), STCP(0x7758f886, 0x2e430c6f), + STCP(0x77320d0d, 0x2ea6f827), STCP(0x770acdec, 0x2f0ac320), STCP(0x76e33b3f, 0x2f6e6d16), + STCP(0x76bb5521, 0x2fd1f5c1), STCP(0x76931bae, 0x30355cdd), STCP(0x766a8f04, 0x3098a223), + STCP(0x7641af3d, 0x30fbc54d), STCP(0x76187c77, 0x315ec617), STCP(0x75eef6ce, 0x31c1a43b), + STCP(0x75c51e61, 0x32245f72), STCP(0x759af34c, 0x3286f779), STCP(0x757075ac, 0x32e96c09), + STCP(0x7545a5a0, 0x334bbcde), STCP(0x751a8346, 0x33ade9b3), STCP(0x74ef0ebc, 0x340ff242), + STCP(0x74c34820, 0x3471d647), STCP(0x74972f92, 0x34d3957e), STCP(0x746ac52f, 0x35352fa1), + STCP(0x743e0918, 0x3596a46c), STCP(0x7410fb6b, 0x35f7f39c), STCP(0x73e39c49, 0x36591cea), + STCP(0x73b5ebd1, 0x36ba2014), STCP(0x7387ea23, 0x371afcd5), STCP(0x73599760, 0x377bb2e9), + STCP(0x732af3a7, 0x37dc420c), STCP(0x72fbff1b, 0x383ca9fb), STCP(0x72ccb9db, 0x389cea72), + STCP(0x729d2409, 0x38fd032d), STCP(0x726d3dc6, 0x395cf3e9), STCP(0x723d0734, 0x39bcbc63), + STCP(0x720c8075, 0x3a1c5c57), STCP(0x71dba9ab, 0x3a7bd382), STCP(0x71aa82f7, 0x3adb21a1), + STCP(0x71790c7e, 0x3b3a4672), STCP(0x71474660, 0x3b9941b1), STCP(0x711530c2, 0x3bf8131c), + STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70b01790, 0x3cb5376b), STCP(0x707d1443, 0x3d1389cb), + STCP(0x7049c203, 0x3d71b14d), STCP(0x701620f5, 0x3dcfadb0), STCP(0x6fe2313c, 0x3e2d7eb1), + STCP(0x6fadf2fc, 0x3e8b240e), STCP(0x6f79665b, 0x3ee89d86), STCP(0x6f448b7e, 0x3f45ead8), + STCP(0x6f0f6289, 0x3fa30bc1), STCP(0x6ed9eba1, 0x40000000), STCP(0x6ea426ed, 0x405cc754), + STCP(0x6e6e1492, 0x40b9617d), STCP(0x6e37b4b6, 0x4115ce38), STCP(0x6e010780, 0x41720d46), + STCP(0x6dca0d14, 0x41ce1e65), STCP(0x6d92c59b, 0x422a0154), STCP(0x6d5b313b, 0x4285b5d4), + STCP(0x6d23501b, 0x42e13ba4), STCP(0x6ceb2261, 0x433c9283), STCP(0x6cb2a837, 0x4397ba32), + STCP(0x6c79e1c2, 0x43f2b271), STCP(0x6c40cf2c, 0x444d7aff), STCP(0x6c07709b, 0x44a8139e), + STCP(0x6bcdc639, 0x45027c0c), STCP(0x6b93d02e, 0x455cb40c), STCP(0x6b598ea3, 0x45b6bb5e), + STCP(0x6b1f01c0, 0x461091c2), STCP(0x6ae429ae, 0x466a36f9), STCP(0x6aa90697, 0x46c3aac5), + STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a31e000, 0x4775fd1f), STCP(0x69f5dcd3, 0x47cedb31), + STCP(0x69b98f48, 0x482786dc), STCP(0x697cf78a, 0x487fffe4), STCP(0x694015c3, 0x48d84609), + STCP(0x6902ea1d, 0x4930590f), STCP(0x68c574c4, 0x498838b6), STCP(0x6887b5e2, 0x49dfe4c2), + STCP(0x6849ada3, 0x4a375cf5), STCP(0x680b5c33, 0x4a8ea111), STCP(0x67ccc1be, 0x4ae5b0da), + STCP(0x678dde6e, 0x4b3c8c12), STCP(0x674eb271, 0x4b93327c), STCP(0x670f3df3, 0x4be9a3db), + STCP(0x66cf8120, 0x4c3fdff4), STCP(0x668f7c25, 0x4c95e688), STCP(0x664f2f2e, 0x4cebb75c), + STCP(0x660e9a6a, 0x4d415234), STCP(0x65cdbe05, 0x4d96b6d3), STCP(0x658c9a2d, 0x4debe4fe), + STCP(0x654b2f10, 0x4e40dc79), STCP(0x65097cdb, 0x4e959d08), STCP(0x64c783bd, 0x4eea2670), + STCP(0x648543e4, 0x4f3e7875), STCP(0x6442bd7e, 0x4f9292dc), STCP(0x63fff0ba, 0x4fe6756a), + STCP(0x63bcddc7, 0x503a1fe5), STCP(0x637984d4, 0x508d9211), STCP(0x6335e611, 0x50e0cbb4), + STCP(0x62f201ac, 0x5133cc94), STCP(0x62add7d6, 0x51869476), STCP(0x626968be, 0x51d92321), + STCP(0x6224b495, 0x522b7859), STCP(0x61dfbb8a, 0x527d93e6), STCP(0x619a7dce, 0x52cf758f), + STCP(0x6154fb91, 0x53211d18), STCP(0x610f3505, 0x53728a4a), STCP(0x60c92a5a, 0x53c3bcea), + STCP(0x6082dbc1, 0x5414b4c1), STCP(0x603c496c, 0x54657194), STCP(0x5ff5738d, 0x54b5f32c), + STCP(0x5fae5a55, 0x55063951), STCP(0x5f66fdf5, 0x555643c8), STCP(0x5f1f5ea1, 0x55a6125c), + STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e8f57e2, 0x5644faf4), STCP(0x5e46f0dd, 0x5694148b), + STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5db55c86, 0x57319135), STCP(0x5d6c2f99, 0x577ff3da), + STCP(0x5d22c11c, 0x57ce1917), STCP(0x5cd91140, 0x581c00b3), STCP(0x5c8f203b, 0x5869aa79), + STCP(0x5c44ee40, 0x58b71632), STCP(0x5bfa7b82, 0x590443a7), STCP(0x5bafc837, 0x595132a2), + STCP(0x5b64d492, 0x599de2ee), STCP(0x5b19a0c8, 0x59ea5454), STCP(0x5ace2d0f, 0x5a36869f), + STCP(0x5a82799a, 0x5a82799a), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineTable360[] = { +# else +const PWord16 SineTable360[] = { +# endif + STCP(0x7fffffff, 0x00000000), STCP(0x7fffb025, 0x008efa17), STCP(0x7ffec095, 0x011df37c), + STCP(0x7ffd3153, 0x01aceb7c), STCP(0x7ffb025f, 0x023be165), STCP(0x7ff833bc, 0x02cad485), + STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff0b779, 0x03e8af9e), STCP(0x7fec09e2, 0x04779632), + STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe0cfe6, 0x059551f1), STCP(0x7fda4390, 0x062425b6), + STCP(0x7fd317b3, 0x06b2f1d2), STCP(0x7fcb4c5a, 0x0741b592), STCP(0x7fc2e18d, 0x07d07044), + STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb02dc5, 0x08edc7b7), STCP(0x7fa5e4e0, 0x097c6313), + STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f8f7558, 0x0a997597), STCP(0x7f834ecf, 0x0b27eb5c), + STCP(0x7f76892e, 0x0bb65336), STCP(0x7f692482, 0x0c44ac72), STCP(0x7f5b20de, 0x0cd2f660), + STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f3d3cf3, 0x0def5989), STCP(0x7f2d5cd0, 0x0e7d7162), + STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f0bc096, 0x0f996a26), STCP(0x7efa04a7, 0x102749ae), + STCP(0x7ee7aa4b, 0x10b5150f), STCP(0x7ed4b197, 0x1142cb98), STCP(0x7ec11aa4, 0x11d06c96), + STCP(0x7eace589, 0x125df75b), STCP(0x7e981261, 0x12eb6b35), STCP(0x7e82a145, 0x1378c774), + STCP(0x7e6c9250, 0x14060b68), STCP(0x7e55e59d, 0x1493365f), STCP(0x7e3e9b49, 0x152047ab), + STCP(0x7e26b370, 0x15ad3e9a), STCP(0x7e0e2e31, 0x163a1a7e), STCP(0x7df50baa, 0x16c6daa6), + STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dc0ef43, 0x17e00505), STCP(0x7da5f5a4, 0x186c6ddd), + STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d6e2c36, 0x1984e373), STCP(0x7d515cae, 0x1a10eed2), + STCP(0x7d33f0c9, 0x1a9cd9ac), STCP(0x7d15e8ac, 0x1b28a351), STCP(0x7cf7447e, 0x1bb44b13), + STCP(0x7cd80464, 0x1c3fd045), STCP(0x7cb82884, 0x1ccb3237), STCP(0x7c97b108, 0x1d56703b), + STCP(0x7c769e17, 0x1de189a5), STCP(0x7c54efdb, 0x1e6c7dc7), STCP(0x7c32a67d, 0x1ef74bf3), + STCP(0x7c0fc229, 0x1f81f37b), STCP(0x7bec430a, 0x200c73b4), STCP(0x7bc8294c, 0x2096cbf0), + STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b7e26a9, 0x21ab01c0), STCP(0x7b583e20, 0x2234ddfa), + STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b0a9f8d, 0x234815ba), STCP(0x7ae2e9e3, 0x23d16fe8), + STCP(0x7aba9ae5, 0x245a9d64), STCP(0x7a91b2c6, 0x24e39d85), STCP(0x7a6831b9, 0x256c6f9f), + STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a1365a4, 0x267d8713), STCP(0x79e81b05, 0x2705cb19), + STCP(0x79bc384c, 0x278dde6e), STCP(0x798fbdaf, 0x2815c069), STCP(0x7962ab66, 0x289d7061), + STCP(0x793501a8, 0x2924edab), STCP(0x7906c0af, 0x29ac37a0), STCP(0x78d7e8b5, 0x2a334d95), + STCP(0x78a879f3, 0x2aba2ee3), STCP(0x787874a6, 0x2b40dae2), STCP(0x7847d908, 0x2bc750e9), + STCP(0x7816a758, 0x2c4d9050), STCP(0x77e4dfd1, 0x2cd39870), STCP(0x77b282b3, 0x2d5968a2), + STCP(0x777f903b, 0x2ddf003f), STCP(0x774c08aa, 0x2e645ea0), STCP(0x7717ec40, 0x2ee9831f), + STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76adf5e5, 0x2ff31bdd), STCP(0x76781c79, 0x30778ed2), + STCP(0x7641af3c, 0x30fbc54d), STCP(0x760aae72, 0x317fbeaa), STCP(0x75d31a60, 0x32037a45), + STCP(0x759af34b, 0x3286f778), STCP(0x75623979, 0x330a35a1), STCP(0x7528ed31, 0x338d341a), + STCP(0x74ef0ebb, 0x340ff242), STCP(0x74b49e5f, 0x34926f74), STCP(0x74799c65, 0x3514ab0d), + STCP(0x743e0917, 0x3596a46c), STCP(0x7401e4c0, 0x36185aee), STCP(0x73c52faa, 0x3699cdf1), + STCP(0x7387ea22, 0x371afcd4), STCP(0x734a1474, 0x379be6f6), STCP(0x730baeec, 0x381c8bb5), + STCP(0x72ccb9da, 0x389cea71), STCP(0x728d358b, 0x391d028b), STCP(0x724d224e, 0x399cd362), + STCP(0x720c8074, 0x3a1c5c56), STCP(0x71cb504d, 0x3a9b9cc9), STCP(0x7189922b, 0x3b1a941c), + STCP(0x7147465f, 0x3b9941b0), STCP(0x71046d3d, 0x3c17a4e8), STCP(0x70c10717, 0x3c95bd25), + STCP(0x707d1442, 0x3d1389cb), STCP(0x70389513, 0x3d910a3c), STCP(0x6ff389de, 0x3e0e3ddb), + STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f67d0c0, 0x3f07bc37), STCP(0x6f212384, 0x3f8405bb), + STCP(0x6ed9eba1, 0x3fffffff), STCP(0x6e92296d, 0x407baa69), STCP(0x6e49dd44, 0x40f7045f), + STCP(0x6e01077f, 0x41720d45), STCP(0x6db7a879, 0x41ecc483), STCP(0x6d6dc08e, 0x42672980), + STCP(0x6d23501a, 0x42e13ba3), STCP(0x6cd85779, 0x435afa54), STCP(0x6c8cd70a, 0x43d464fa), + STCP(0x6c40cf2b, 0x444d7aff), STCP(0x6bf4403a, 0x44c63bca), STCP(0x6ba72a97, 0x453ea6c7), + STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b0b6cbc, 0x462e78f8), STCP(0x6abcc546, 0x46a5df02), + STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a1de736, 0x4793a210), STCP(0x69cdb161, 0x4809fdeb), + STCP(0x697cf789, 0x487fffe3), STCP(0x692bba13, 0x48f5a767), STCP(0x68d9f964, 0x496af3e1), + STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x6834eff2, 0x4a547975), STCP(0x67e1a7ff, 0x4ac8b16b), + STCP(0x678dde6e, 0x4b3c8c11), STCP(0x673993a8, 0x4bb008d8), STCP(0x66e4c817, 0x4c23272f), + STCP(0x668f7c24, 0x4c95e687), STCP(0x6639b03a, 0x4d084651), STCP(0x65e364c3, 0x4d7a45fd), + STCP(0x658c9a2d, 0x4debe4fe), STCP(0x653550e1, 0x4e5d22c5), STCP(0x64dd894f, 0x4ecdfec6), + STCP(0x648543e3, 0x4f3e7874), STCP(0x642c810b, 0x4fae8f42), STCP(0x63d34136, 0x501e42a5), + STCP(0x637984d4, 0x508d9211), STCP(0x631f4c54, 0x50fc7cfa), STCP(0x62c49826, 0x516b02d8), + STCP(0x626968be, 0x51d92320), STCP(0x620dbe8a, 0x5246dd48), STCP(0x61b19a00, 0x52b430c8), + STCP(0x6154fb90, 0x53211d17), STCP(0x60f7e3b0, 0x538da1ae), STCP(0x609a52d2, 0x53f9be04), + STCP(0x603c496c, 0x54657194), STCP(0x5fddc7f3, 0x54d0bbd6), STCP(0x5f7ecedd, 0x553b9c45), + STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5ebf77b4, 0x56101d94), STCP(0x5e5f1a90, 0x5679bd6b), + STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5d9cff82, 0x574bb8e6), STCP(0x5d3b428b, 0x57b41383), + STCP(0x5cd91140, 0x581c00b3), STCP(0x5c766c1c, 0x58837ff3), STCP(0x5c13539a, 0x58ea90c3), + STCP(0x5bafc836, 0x595132a2), STCP(0x5b4bca6c, 0x59b7650f), STCP(0x5ae75ab8, 0x5a1d278c), + STCP(0x5a827999, 0x5a827999), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineTable320[] = { +# else +const PWord16 SineTable320[] = { +# endif + STCP(0x7fffffff, 0x00000000), STCP(0x7fff9aef, 0x00a0d951), STCP(0x7ffe6bbf, 0x0141b1a5), + STCP(0x7ffc726f, 0x01e287fc), STCP(0x7ff9af04, 0x02835b5a), STCP(0x7ff62182, 0x03242abf), + STCP(0x7ff1c9ef, 0x03c4f52f), STCP(0x7feca851, 0x0465b9aa), STCP(0x7fe6bcb0, 0x05067734), + STCP(0x7fe00716, 0x05a72ccf), STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd03e23, 0x06e87c3f), + STCP(0x7fc72ae2, 0x07891418), STCP(0x7fbd4dda, 0x0829a00c), STCP(0x7fb2a71b, 0x08ca1f1b), + STCP(0x7fa736b4, 0x096a9049), STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f8df93c, 0x0aab450d), + STCP(0x7f802c52, 0x0b4b86a8), STCP(0x7f719611, 0x0bebb66c), STCP(0x7f62368f, 0x0c8bd35e), + STCP(0x7f520de6, 0x0d2bdc80), STCP(0x7f411c2f, 0x0dcbd0d5), STCP(0x7f2f6183, 0x0e6baf61), + STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7f0991c4, 0x0fab272b), STCP(0x7ef57cea, 0x104abe71), + STCP(0x7ee09f95, 0x10ea3bfd), STCP(0x7ecaf9e5, 0x11899ed3), STCP(0x7eb48bfb, 0x1228e5f8), + STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e85580c, 0x13671d3d), STCP(0x7e6c9251, 0x14060b68), + STCP(0x7e5304f2, 0x14a4d9f4), STCP(0x7e38b017, 0x154387e6), STCP(0x7e1d93ea, 0x15e21445), + STCP(0x7e01b096, 0x16807e15), STCP(0x7de50646, 0x171ec45c), STCP(0x7dc79529, 0x17bce621), + STCP(0x7da95d6c, 0x185ae269), STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d6a9ad5, 0x199666a0), + STCP(0x7d4a105d, 0x1a33ec9c), STCP(0x7d28c00c, 0x1ad14938), STCP(0x7d06aa16, 0x1b6e7b7a), + STCP(0x7ce3ceb2, 0x1c0b826a), STCP(0x7cc02e15, 0x1ca85d12), STCP(0x7c9bc87a, 0x1d450a78), + STCP(0x7c769e18, 0x1de189a6), STCP(0x7c50af2b, 0x1e7dd9a4), STCP(0x7c29fbee, 0x1f19f97b), + STCP(0x7c02849f, 0x1fb5e836), STCP(0x7bda497d, 0x2051a4dd), STCP(0x7bb14ac5, 0x20ed2e7b), + STCP(0x7b8788ba, 0x2188841a), STCP(0x7b5d039e, 0x2223a4c5), STCP(0x7b31bbb2, 0x22be8f87), + STCP(0x7b05b13d, 0x2359436c), STCP(0x7ad8e482, 0x23f3bf7e), STCP(0x7aab55ca, 0x248e02cb), + STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a4df380, 0x25c1db44), STCP(0x7a1e2082, 0x265b6e8a), + STCP(0x79ed8cad, 0x26f4c53e), STCP(0x79bc384d, 0x278dde6e), STCP(0x798a23b1, 0x2826b928), + STCP(0x79574f28, 0x28bf547b), STCP(0x7923bb01, 0x2957af74), STCP(0x78ef678f, 0x29efc925), + STCP(0x78ba5524, 0x2a87a09d), STCP(0x78848414, 0x2b1f34eb), STCP(0x784df4b3, 0x2bb68522), + STCP(0x7816a759, 0x2c4d9050), STCP(0x77de9c5b, 0x2ce45589), STCP(0x77a5d413, 0x2d7ad3de), + STCP(0x776c4edb, 0x2e110a62), STCP(0x77320d0d, 0x2ea6f827), STCP(0x76f70f05, 0x2f3c9c40), + STCP(0x76bb5521, 0x2fd1f5c1), STCP(0x767edfbe, 0x306703bf), STCP(0x7641af3d, 0x30fbc54d), + STCP(0x7603c3fd, 0x31903982), STCP(0x75c51e61, 0x32245f72), STCP(0x7585becb, 0x32b83634), + STCP(0x7545a5a0, 0x334bbcde), STCP(0x7504d345, 0x33def287), STCP(0x74c34820, 0x3471d647), + STCP(0x74810499, 0x35046736), STCP(0x743e0918, 0x3596a46c), STCP(0x73fa5607, 0x36288d03), + STCP(0x73b5ebd1, 0x36ba2014), STCP(0x7370cae2, 0x374b5cb9), STCP(0x732af3a7, 0x37dc420c), + STCP(0x72e4668f, 0x386ccf2a), STCP(0x729d2409, 0x38fd032d), STCP(0x72552c85, 0x398cdd32), + STCP(0x720c8075, 0x3a1c5c57), STCP(0x71c3204c, 0x3aab7fb7), STCP(0x71790c7e, 0x3b3a4672), + STCP(0x712e457f, 0x3bc8afa5), STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70969fca, 0x3ce465f3), + STCP(0x7049c203, 0x3d71b14d), STCP(0x6ffc32eb, 0x3dfe9ba1), STCP(0x6fadf2fc, 0x3e8b240e), + STCP(0x6f5f02b2, 0x3f1749b8), STCP(0x6f0f6289, 0x3fa30bc1), STCP(0x6ebf12ff, 0x402e694c), + STCP(0x6e6e1492, 0x40b9617d), STCP(0x6e1c67c4, 0x4143f379), STCP(0x6dca0d14, 0x41ce1e65), + STCP(0x6d770506, 0x4257e166), STCP(0x6d23501b, 0x42e13ba4), STCP(0x6cceeed8, 0x436a2c45), + STCP(0x6c79e1c2, 0x43f2b271), STCP(0x6c242960, 0x447acd50), STCP(0x6bcdc639, 0x45027c0c), + STCP(0x6b76b8d6, 0x4589bdcf), STCP(0x6b1f01c0, 0x461091c2), STCP(0x6ac6a180, 0x4696f710), + STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a13e7b8, 0x47a27271), STCP(0x69b98f48, 0x482786dc), + STCP(0x695e8fe5, 0x48ac2957), STCP(0x6902ea1d, 0x4930590f), STCP(0x68a69e81, 0x49b41533), + STCP(0x6849ada3, 0x4a375cf5), STCP(0x67ec1817, 0x4aba2f84), STCP(0x678dde6e, 0x4b3c8c12), + STCP(0x672f013f, 0x4bbe71d1), STCP(0x66cf8120, 0x4c3fdff4), STCP(0x666f5ea6, 0x4cc0d5ae), + STCP(0x660e9a6a, 0x4d415234), STCP(0x65ad3505, 0x4dc154bb), STCP(0x654b2f10, 0x4e40dc79), + STCP(0x64e88926, 0x4ebfe8a5), STCP(0x648543e4, 0x4f3e7875), STCP(0x64215fe5, 0x4fbc8b22), + STCP(0x63bcddc7, 0x503a1fe5), STCP(0x6357be2a, 0x50b735f8), STCP(0x62f201ac, 0x5133cc94), + STCP(0x628ba8ef, 0x51afe2f6), STCP(0x6224b495, 0x522b7859), STCP(0x61bd253f, 0x52a68bfb), + STCP(0x6154fb91, 0x53211d18), STCP(0x60ec3830, 0x539b2af0), STCP(0x6082dbc1, 0x5414b4c1), + STCP(0x6018e6eb, 0x548db9cb), STCP(0x5fae5a55, 0x55063951), STCP(0x5f4336a7, 0x557e3292), + STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e6b2ca8, 0x566c8f55), STCP(0x5dfe47ad, 0x56e2f15d), + STCP(0x5d90ce45, 0x5758ca31), STCP(0x5d22c11c, 0x57ce1917), STCP(0x5cb420e0, 0x5842dd54), + STCP(0x5c44ee40, 0x58b71632), STCP(0x5bd529eb, 0x592ac2f7), STCP(0x5b64d492, 0x599de2ee), + STCP(0x5af3eee6, 0x5a107561), STCP(0x5a82799a, 0x5a82799a), +}; + + +# ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS + const PWord32 SineTable720[] = { + STCP(0x7fffffff, 0x00000000), STCP(0x7fffec08, 0x00477d17), STCP(0x7fffb025, 0x008efa17), + STCP(0x7fff4c53, 0x00d676eb), STCP(0x7ffec095, 0x011df37c), STCP(0x7ffe0cea, 0x01656fb4), + STCP(0x7ffd3153, 0x01aceb7c), STCP(0x7ffc2dcf, 0x01f466bf), STCP(0x7ffb025f, 0x023be165), + STCP(0x7ff9af03, 0x02835b59), STCP(0x7ff833bc, 0x02cad485), STCP(0x7ff6908a, 0x03124cd1), + STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff2d268, 0x03a13a74), STCP(0x7ff0b779, 0x03e8af9e), + STCP(0x7fee74a1, 0x0430238f), STCP(0x7fec09e2, 0x04779632), STCP(0x7fe9773c, 0x04bf0771), + STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe3da3d, 0x054de566), STCP(0x7fe0cfe6, 0x059551f1), + STCP(0x7fdd9dac, 0x05dcbcbe), STCP(0x7fda4390, 0x062425b6), STCP(0x7fd6c192, 0x066b8cc5), + STCP(0x7fd317b3, 0x06b2f1d2), STCP(0x7fcf45f6, 0x06fa54c9), STCP(0x7fcb4c5a, 0x0741b592), + STCP(0x7fc72ae1, 0x07891418), STCP(0x7fc2e18d, 0x07d07044), STCP(0x7fbe705f, 0x0817ca01), + STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb51679, 0x08a675d0), STCP(0x7fb02dc5, 0x08edc7b7), + STCP(0x7fab1d3c, 0x093516d4), STCP(0x7fa5e4e0, 0x097c6313), STCP(0x7fa084b4, 0x09c3ac5c), + STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f954cee, 0x0a5235b4), STCP(0x7f8f7558, 0x0a997597), + STCP(0x7f8975f8, 0x0ae0b22c), STCP(0x7f834ecf, 0x0b27eb5c), STCP(0x7f7cffe1, 0x0b6f2112), + STCP(0x7f76892e, 0x0bb65336), STCP(0x7f6feab8, 0x0bfd81b3), STCP(0x7f692482, 0x0c44ac72), + STCP(0x7f62368e, 0x0c8bd35e), STCP(0x7f5b20de, 0x0cd2f660), STCP(0x7f53e374, 0x0d1a1562), + STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f44f17c, 0x0da8470d), STCP(0x7f3d3cf3, 0x0def5989), + STCP(0x7f3560b8, 0x0e3667ad), STCP(0x7f2d5cd0, 0x0e7d7162), STCP(0x7f25313c, 0x0ec47692), + STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f14631c, 0x0f52730a), STCP(0x7f0bc096, 0x0f996a26), + STCP(0x7f02f66e, 0x0fe05c64), STCP(0x7efa04a7, 0x102749ae), STCP(0x7ef0eb45, 0x106e31ef), + STCP(0x7ee7aa4b, 0x10b5150f), STCP(0x7ede41ba, 0x10fbf2fa), STCP(0x7ed4b197, 0x1142cb98), + STCP(0x7ecaf9e4, 0x11899ed3), STCP(0x7ec11aa4, 0x11d06c96), STCP(0x7eb713da, 0x121734cb), + STCP(0x7eace589, 0x125df75b), STCP(0x7ea28fb5, 0x12a4b431), STCP(0x7e981261, 0x12eb6b35), + STCP(0x7e8d6d90, 0x13321c53), STCP(0x7e82a145, 0x1378c774), STCP(0x7e77ad84, 0x13bf6c82), + STCP(0x7e6c9250, 0x14060b68), STCP(0x7e614fac, 0x144ca40e), STCP(0x7e55e59d, 0x1493365f), + STCP(0x7e4a5425, 0x14d9c245), STCP(0x7e3e9b49, 0x152047ab), STCP(0x7e32bb0b, 0x1566c679), + STCP(0x7e26b370, 0x15ad3e9a), STCP(0x7e1a847b, 0x15f3aff8), STCP(0x7e0e2e31, 0x163a1a7e), + STCP(0x7e01b095, 0x16807e14), STCP(0x7df50baa, 0x16c6daa6), STCP(0x7de83f76, 0x170d301d), + STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dce313e, 0x1799c562), STCP(0x7dc0ef43, 0x17e00505), + STCP(0x7db3860e, 0x18263d35), STCP(0x7da5f5a4, 0x186c6ddd), STCP(0x7d983e08, 0x18b296e7), + STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d7c594d, 0x193ed1c8), STCP(0x7d6e2c36, 0x1984e373), + STCP(0x7d5fd800, 0x19caed28), STCP(0x7d515cae, 0x1a10eed2), STCP(0x7d42ba45, 0x1a56e85b), + STCP(0x7d33f0c9, 0x1a9cd9ac), STCP(0x7d25003f, 0x1ae2c2b0), STCP(0x7d15e8ac, 0x1b28a351), + STCP(0x7d06aa15, 0x1b6e7b7a), STCP(0x7cf7447e, 0x1bb44b13), STCP(0x7ce7b7ec, 0x1bfa1209), + STCP(0x7cd80464, 0x1c3fd045), STCP(0x7cc829ea, 0x1c8585b0), STCP(0x7cb82884, 0x1ccb3237), + STCP(0x7ca80037, 0x1d10d5c1), STCP(0x7c97b108, 0x1d56703b), STCP(0x7c873afb, 0x1d9c018f), + STCP(0x7c769e17, 0x1de189a5), STCP(0x7c65da60, 0x1e27086a), STCP(0x7c54efdb, 0x1e6c7dc7), + STCP(0x7c43de8d, 0x1eb1e9a6), STCP(0x7c32a67d, 0x1ef74bf3), STCP(0x7c2147af, 0x1f3ca496), + STCP(0x7c0fc229, 0x1f81f37b), STCP(0x7bfe15f0, 0x1fc7388d), STCP(0x7bec430a, 0x200c73b4), + STCP(0x7bda497c, 0x2051a4dd), STCP(0x7bc8294c, 0x2096cbf0), STCP(0x7bb5e27f, 0x20dbe8da), + STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b90e128, 0x216603d7), STCP(0x7b7e26a9, 0x21ab01c0), + STCP(0x7b6b45a4, 0x21eff528), STCP(0x7b583e20, 0x2234ddfa), STCP(0x7b451022, 0x2279bc21), + STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b1e40d3, 0x23035817), STCP(0x7b0a9f8d, 0x234815ba), + STCP(0x7af6d7e5, 0x238cc85c), STCP(0x7ae2e9e3, 0x23d16fe8), STCP(0x7aced58b, 0x24160c47), + STCP(0x7aba9ae5, 0x245a9d64), STCP(0x7aa639f7, 0x249f232b), STCP(0x7a91b2c6, 0x24e39d85), + STCP(0x7a7d055a, 0x25280c5d), STCP(0x7a6831b9, 0x256c6f9f), STCP(0x7a5337e9, 0x25b0c734), + STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a28d1d8, 0x26395303), STCP(0x7a1365a4, 0x267d8713), + STCP(0x79fdd35b, 0x26c1af21), STCP(0x79e81b05, 0x2705cb19), STCP(0x79d23ca9, 0x2749dae4), + STCP(0x79bc384c, 0x278dde6e), STCP(0x79a60df7, 0x27d1d5a2), STCP(0x798fbdaf, 0x2815c069), + STCP(0x7979477c, 0x28599eb0), STCP(0x7962ab66, 0x289d7061), STCP(0x794be972, 0x28e13566), + STCP(0x793501a8, 0x2924edab), STCP(0x791df40f, 0x2968991b), STCP(0x7906c0af, 0x29ac37a0), + STCP(0x78ef678e, 0x29efc925), STCP(0x78d7e8b5, 0x2a334d95), STCP(0x78c04429, 0x2a76c4dc), + STCP(0x78a879f3, 0x2aba2ee3), STCP(0x78908a1a, 0x2afd8b97), STCP(0x787874a6, 0x2b40dae2), + STCP(0x7860399d, 0x2b841caf), STCP(0x7847d908, 0x2bc750e9), STCP(0x782f52ef, 0x2c0a777b), + STCP(0x7816a758, 0x2c4d9050), STCP(0x77fdd64b, 0x2c909b54), STCP(0x77e4dfd1, 0x2cd39870), + STCP(0x77cbc3f1, 0x2d168792), STCP(0x77b282b3, 0x2d5968a2), STCP(0x77991c1e, 0x2d9c3b8e), + STCP(0x777f903b, 0x2ddf003f), STCP(0x7765df12, 0x2e21b6a2), STCP(0x774c08aa, 0x2e645ea0), + STCP(0x77320d0c, 0x2ea6f826), STCP(0x7717ec40, 0x2ee9831f), STCP(0x76fda64e, 0x2f2bff76), + STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76c8ab18, 0x2fb0cbea), STCP(0x76adf5e5, 0x2ff31bdd), + STCP(0x76931bae, 0x30355cdc), STCP(0x76781c79, 0x30778ed2), STCP(0x765cf850, 0x30b9b1a9), + STCP(0x7641af3c, 0x30fbc54d), STCP(0x76264144, 0x313dc9aa), STCP(0x760aae72, 0x317fbeaa), + STCP(0x75eef6ce, 0x31c1a43a), STCP(0x75d31a60, 0x32037a45), STCP(0x75b71931, 0x324540b6), + STCP(0x759af34b, 0x3286f778), STCP(0x757ea8b5, 0x32c89e78), STCP(0x75623979, 0x330a35a1), + STCP(0x7545a59f, 0x334bbcde), STCP(0x7528ed31, 0x338d341a), STCP(0x750c1038, 0x33ce9b42), + STCP(0x74ef0ebb, 0x340ff242), STCP(0x74d1e8c5, 0x34513903), STCP(0x74b49e5f, 0x34926f74), + STCP(0x74972f91, 0x34d3957e), STCP(0x74799c65, 0x3514ab0d), STCP(0x745be4e4, 0x3555b00e), + STCP(0x743e0917, 0x3596a46c), STCP(0x74200908, 0x35d78813), STCP(0x7401e4c0, 0x36185aee), + STCP(0x73e39c48, 0x36591cea), STCP(0x73c52faa, 0x3699cdf1), STCP(0x73a69ef0, 0x36da6df1), + STCP(0x7387ea22, 0x371afcd4), STCP(0x7369114b, 0x375b7a87), STCP(0x734a1474, 0x379be6f6), + STCP(0x732af3a6, 0x37dc420c), STCP(0x730baeec, 0x381c8bb5), STCP(0x72ec4650, 0x385cc3de), + STCP(0x72ccb9da, 0x389cea71), STCP(0x72ad0995, 0x38dcff5d), STCP(0x728d358b, 0x391d028b), + STCP(0x726d3dc5, 0x395cf3e9), STCP(0x724d224e, 0x399cd362), STCP(0x722ce330, 0x39dca0e2), + STCP(0x720c8074, 0x3a1c5c56), STCP(0x71ebfa25, 0x3a5c05aa), STCP(0x71cb504d, 0x3a9b9cc9), + STCP(0x71aa82f6, 0x3adb21a0), STCP(0x7189922b, 0x3b1a941c), STCP(0x71687df5, 0x3b59f428), + STCP(0x7147465f, 0x3b9941b0), STCP(0x7125eb74, 0x3bd87ca1), STCP(0x71046d3d, 0x3c17a4e8), + STCP(0x70e2cbc5, 0x3c56ba70), STCP(0x70c10717, 0x3c95bd25), STCP(0x709f1f3d, 0x3cd4acf5), + STCP(0x707d1442, 0x3d1389cb), STCP(0x705ae630, 0x3d525394), STCP(0x70389513, 0x3d910a3c), + STCP(0x701620f4, 0x3dcfadaf), STCP(0x6ff389de, 0x3e0e3ddb), STCP(0x6fd0cfdd, 0x3e4cbaac), + STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f8af343, 0x3ec979ed), STCP(0x6f67d0c0, 0x3f07bc37), + STCP(0x6f448b7d, 0x3f45ead7), STCP(0x6f212384, 0x3f8405bb), STCP(0x6efd98e2, 0x3fc20ccf), + STCP(0x6ed9eba1, 0x3fffffff), STCP(0x6eb61bcb, 0x403ddf39), STCP(0x6e92296d, 0x407baa69), + STCP(0x6e6e1492, 0x40b9617c), STCP(0x6e49dd44, 0x40f7045f), STCP(0x6e25838f, 0x413492fd), + STCP(0x6e01077f, 0x41720d45), STCP(0x6ddc691e, 0x41af7323), STCP(0x6db7a879, 0x41ecc483), + STCP(0x6d92c59a, 0x422a0154), STCP(0x6d6dc08e, 0x42672980), STCP(0x6d48995f, 0x42a43cf7), + STCP(0x6d23501a, 0x42e13ba3), STCP(0x6cfde4c9, 0x431e2573), STCP(0x6cd85779, 0x435afa54), + STCP(0x6cb2a836, 0x4397ba32), STCP(0x6c8cd70a, 0x43d464fa), STCP(0x6c66e403, 0x4410fa9a), + STCP(0x6c40cf2b, 0x444d7aff), STCP(0x6c1a988f, 0x4489e615), STCP(0x6bf4403a, 0x44c63bca), + STCP(0x6bcdc639, 0x45027c0c), STCP(0x6ba72a97, 0x453ea6c7), STCP(0x6b806d61, 0x457abbe8), + STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b328e67, 0x45f2a513), STCP(0x6b0b6cbc, 0x462e78f8), + STCP(0x6ae429ad, 0x466a36f9), STCP(0x6abcc546, 0x46a5df02), STCP(0x6a953f94, 0x46e17102), + STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a45d080, 0x4758529c), STCP(0x6a1de736, 0x4793a210), + STCP(0x69f5dcd2, 0x47cedb30), STCP(0x69cdb161, 0x4809fdeb), STCP(0x69a564ef, 0x48450a2d), + STCP(0x697cf789, 0x487fffe3), STCP(0x6954693b, 0x48badefd), STCP(0x692bba13, 0x48f5a767), + STCP(0x6902ea1c, 0x4930590e), STCP(0x68d9f964, 0x496af3e1), STCP(0x68b0e7f6, 0x49a577ce), + STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x685e6331, 0x4a1a3aaa), STCP(0x6834eff2, 0x4a547975), + STCP(0x680b5c33, 0x4a8ea111), STCP(0x67e1a7ff, 0x4ac8b16b), STCP(0x67b7d363, 0x4b02aa71), + STCP(0x678dde6e, 0x4b3c8c11), STCP(0x6763c92b, 0x4b76563a), STCP(0x673993a8, 0x4bb008d8), + STCP(0x670f3df2, 0x4be9a3db), STCP(0x66e4c817, 0x4c23272f), STCP(0x66ba3223, 0x4c5c92c4), + STCP(0x668f7c24, 0x4c95e687), STCP(0x6664a627, 0x4ccf2267), STCP(0x6639b03a, 0x4d084651), + STCP(0x660e9a69, 0x4d415233), STCP(0x65e364c3, 0x4d7a45fd), STCP(0x65b80f55, 0x4db3219c), + STCP(0x658c9a2d, 0x4debe4fe), STCP(0x65610557, 0x4e249011), STCP(0x653550e1, 0x4e5d22c5), + STCP(0x65097cda, 0x4e959d07), STCP(0x64dd894f, 0x4ecdfec6), STCP(0x64b1764d, 0x4f0647f0), + STCP(0x648543e3, 0x4f3e7874), STCP(0x6458f21d, 0x4f769040), STCP(0x642c810b, 0x4fae8f42), + STCP(0x63fff0b9, 0x4fe6756a), STCP(0x63d34136, 0x501e42a5), STCP(0x63a6728f, 0x5055f6e2), + STCP(0x637984d4, 0x508d9211), STCP(0x634c7810, 0x50c5141e), STCP(0x631f4c54, 0x50fc7cfa), + STCP(0x62f201ac, 0x5133cc94), STCP(0x62c49826, 0x516b02d8), STCP(0x62970fd2, 0x51a21fb7), + STCP(0x626968be, 0x51d92320), STCP(0x623ba2f6, 0x52100d01), STCP(0x620dbe8a, 0x5246dd48), + STCP(0x61dfbb89, 0x527d93e6), STCP(0x61b19a00, 0x52b430c8), STCP(0x618359fd, 0x52eab3de), + STCP(0x6154fb90, 0x53211d17), STCP(0x61267ec7, 0x53576c62), STCP(0x60f7e3b0, 0x538da1ae), + STCP(0x60c92a59, 0x53c3bce9), STCP(0x609a52d2, 0x53f9be04), STCP(0x606b5d28, 0x542fa4ed), + STCP(0x603c496c, 0x54657194), STCP(0x600d17aa, 0x549b23e7), STCP(0x5fddc7f3, 0x54d0bbd6), + STCP(0x5fae5a54, 0x55063950), STCP(0x5f7ecedd, 0x553b9c45), STCP(0x5f4f259c, 0x5570e4a3), + STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5eef79f8, 0x55db255b), STCP(0x5ebf77b4, 0x56101d94), + STCP(0x5e8f57e2, 0x5644faf4), STCP(0x5e5f1a90, 0x5679bd6b), STCP(0x5e2ebfcf, 0x56ae64e9), + STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5dcdb239, 0x571762b6), STCP(0x5d9cff82, 0x574bb8e6), + STCP(0x5d6c2f99, 0x577ff3da), STCP(0x5d3b428b, 0x57b41383), STCP(0x5d0a3868, 0x57e817d1), + STCP(0x5cd91140, 0x581c00b3), STCP(0x5ca7cd21, 0x584fce19), STCP(0x5c766c1c, 0x58837ff3), + STCP(0x5c44ee3f, 0x58b71631), STCP(0x5c13539a, 0x58ea90c3), STCP(0x5be19c3c, 0x591def98), + STCP(0x5bafc836, 0x595132a2), STCP(0x5b7dd796, 0x598459ce), STCP(0x5b4bca6c, 0x59b7650f), + STCP(0x5b19a0c7, 0x59ea5454), STCP(0x5ae75ab8, 0x5a1d278c), STCP(0x5ab4f84f, 0x5a4fdea9), + STCP(0x5a827999, 0x5a827999) +}; +#endif +const PWord32 SineTable960[] = { + STCP(0x7fffffff, 0x00000000), STCP(0x7ffff4c4, 0x00359dd2), STCP(0x7fffd314, 0x006b3b9b), + STCP(0x7fff9aee, 0x00a0d951), STCP(0x7fff4c53, 0x00d676eb), STCP(0x7ffee743, 0x010c1460), + STCP(0x7ffe6bbe, 0x0141b1a5), STCP(0x7ffdd9c3, 0x01774eb2), STCP(0x7ffd3153, 0x01aceb7c), + STCP(0x7ffc726e, 0x01e287fc), STCP(0x7ffb9d14, 0x02182427), STCP(0x7ffab146, 0x024dbff4), + STCP(0x7ff9af03, 0x02835b59), STCP(0x7ff8964c, 0x02b8f64e), STCP(0x7ff76720, 0x02ee90c8), + STCP(0x7ff62181, 0x03242abf), STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff352e7, 0x038f5cfb), + STCP(0x7ff1c9ee, 0x03c4f52e), STCP(0x7ff02a81, 0x03fa8cb8), STCP(0x7fee74a1, 0x0430238f), + STCP(0x7feca850, 0x0465b9aa), STCP(0x7feac58c, 0x049b4f00), STCP(0x7fe8cc56, 0x04d0e386), + STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe49697, 0x053c0a01), STCP(0x7fe25a0e, 0x05719be2), + STCP(0x7fe00715, 0x05a72ccf), STCP(0x7fdd9dac, 0x05dcbcbe), STCP(0x7fdb1dd4, 0x06124ba5), + STCP(0x7fd8878d, 0x0647d97c), STCP(0x7fd5dad7, 0x067d6639), STCP(0x7fd317b3, 0x06b2f1d2), + STCP(0x7fd03e22, 0x06e87c3f), STCP(0x7fcd4e23, 0x071e0575), STCP(0x7fca47b8, 0x07538d6b), + STCP(0x7fc72ae1, 0x07891418), STCP(0x7fc3f79f, 0x07be9973), STCP(0x7fc0adf1, 0x07f41d72), + STCP(0x7fbd4dd9, 0x0829a00b), STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb64a6d, 0x0894a0e9), + STCP(0x7fb2a71a, 0x08ca1f1b), STCP(0x7faeed5e, 0x08ff9bc2), STCP(0x7fab1d3c, 0x093516d4), + STCP(0x7fa736b3, 0x096a9049), STCP(0x7fa339c4, 0x09a00817), STCP(0x7f9f2670, 0x09d57e35), + STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f96bc9b, 0x0a40653a), STCP(0x7f92661c, 0x0a75d60e), + STCP(0x7f8df93b, 0x0aab450d), STCP(0x7f8975f8, 0x0ae0b22c), STCP(0x7f84dc54, 0x0b161d63), + STCP(0x7f802c51, 0x0b4b86a8), STCP(0x7f7b65ee, 0x0b80edf1), STCP(0x7f76892e, 0x0bb65336), + STCP(0x7f719610, 0x0bebb66c), STCP(0x7f6c8c95, 0x0c21178c), STCP(0x7f676cbf, 0x0c56768a), + STCP(0x7f62368e, 0x0c8bd35e), STCP(0x7f5cea04, 0x0cc12dff), STCP(0x7f578720, 0x0cf68662), + STCP(0x7f520de5, 0x0d2bdc80), STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f46d86b, 0x0d9681c2), + STCP(0x7f411c2e, 0x0dcbd0d5), STCP(0x7f3b499c, 0x0e011d7c), STCP(0x7f3560b8, 0x0e3667ad), + STCP(0x7f2f6182, 0x0e6baf61), STCP(0x7f294bfc, 0x0ea0f48c), STCP(0x7f232025, 0x0ed63727), + STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f16858d, 0x0f40b483), STCP(0x7f1016cd, 0x0f75ef32), + STCP(0x7f0991c3, 0x0fab272b), STCP(0x7f02f66e, 0x0fe05c64), STCP(0x7efc44cf, 0x10158ed4), + STCP(0x7ef57cea, 0x104abe71), STCP(0x7eee9ebd, 0x107feb33), STCP(0x7ee7aa4b, 0x10b5150f), + STCP(0x7ee09f94, 0x10ea3bfd), STCP(0x7ed97e9b, 0x111f5ff3), STCP(0x7ed24760, 0x115480e9), + STCP(0x7ecaf9e4, 0x11899ed3), STCP(0x7ec39629, 0x11beb9aa), STCP(0x7ebc1c30, 0x11f3d164), + STCP(0x7eb48bfa, 0x1228e5f7), STCP(0x7eace589, 0x125df75b), STCP(0x7ea528df, 0x12930586), + STCP(0x7e9d55fb, 0x12c8106e), STCP(0x7e956ce0, 0x12fd180b), STCP(0x7e8d6d90, 0x13321c53), + STCP(0x7e85580b, 0x13671d3d), STCP(0x7e7d2c53, 0x139c1abf), STCP(0x7e74ea69, 0x13d114d0), + STCP(0x7e6c9250, 0x14060b68), STCP(0x7e642407, 0x143afe7b), STCP(0x7e5b9f92, 0x146fee02), + STCP(0x7e5304f1, 0x14a4d9f3), STCP(0x7e4a5425, 0x14d9c245), STCP(0x7e418d31, 0x150ea6ef), + STCP(0x7e38b016, 0x154387e6), STCP(0x7e2fbcd5, 0x15786522), STCP(0x7e26b370, 0x15ad3e9a), + STCP(0x7e1d93e9, 0x15e21444), STCP(0x7e145e41, 0x1616e618), STCP(0x7e0b1279, 0x164bb40b), + STCP(0x7e01b095, 0x16807e14), STCP(0x7df83894, 0x16b5442b), STCP(0x7deeaa79, 0x16ea0646), + STCP(0x7de50645, 0x171ec45c), STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dd17b9b, 0x17883452), + STCP(0x7dc79528, 0x17bce621), STCP(0x7dbd98a3, 0x17f193c5), STCP(0x7db3860e, 0x18263d35), + STCP(0x7da95d6b, 0x185ae269), STCP(0x7d9f1ebc, 0x188f8357), STCP(0x7d94ca02, 0x18c41ff6), + STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d7fde75, 0x192d4c21), STCP(0x7d7547a6, 0x1961db9b), + STCP(0x7d6a9ad4, 0x199666a0), STCP(0x7d5fd800, 0x19caed28), STCP(0x7d54ff2d, 0x19ff6f2a), + STCP(0x7d4a105c, 0x1a33ec9c), STCP(0x7d3f0b8f, 0x1a686575), STCP(0x7d33f0c9, 0x1a9cd9ac), + STCP(0x7d28c00b, 0x1ad14938), STCP(0x7d1d7957, 0x1b05b40e), STCP(0x7d121caf, 0x1b3a1a27), + STCP(0x7d06aa15, 0x1b6e7b7a), STCP(0x7cfb218b, 0x1ba2d7fc), STCP(0x7cef8314, 0x1bd72fa4), + STCP(0x7ce3ceb1, 0x1c0b826a), STCP(0x7cd80464, 0x1c3fd045), STCP(0x7ccc242f, 0x1c74192a), + STCP(0x7cc02e14, 0x1ca85d12), STCP(0x7cb42216, 0x1cdc9bf2), STCP(0x7ca80037, 0x1d10d5c1), + STCP(0x7c9bc879, 0x1d450a78), STCP(0x7c8f7add, 0x1d793a0b), STCP(0x7c831766, 0x1dad6473), + STCP(0x7c769e17, 0x1de189a5), STCP(0x7c6a0ef1, 0x1e15a99a), STCP(0x7c5d69f6, 0x1e49c447), + STCP(0x7c50af2a, 0x1e7dd9a3), STCP(0x7c43de8d, 0x1eb1e9a6), STCP(0x7c36f823, 0x1ee5f447), + STCP(0x7c29fbed, 0x1f19f97b), STCP(0x7c1ce9ee, 0x1f4df93a), STCP(0x7c0fc229, 0x1f81f37b), + STCP(0x7c02849f, 0x1fb5e835), STCP(0x7bf53152, 0x1fe9d75f), STCP(0x7be7c846, 0x201dc0ef), + STCP(0x7bda497c, 0x2051a4dd), STCP(0x7bccb4f7, 0x2085831e), STCP(0x7bbf0ab9, 0x20b95bac), + STCP(0x7bb14ac4, 0x20ed2e7b), STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b9589c2, 0x2154c2bb), + STCP(0x7b8788b9, 0x2188841a), STCP(0x7b797204, 0x21bc3f97), STCP(0x7b6b45a4, 0x21eff528), + STCP(0x7b5d039d, 0x2223a4c5), STCP(0x7b4eabf0, 0x22574e65), STCP(0x7b403ea1, 0x228af1fe), + STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b232324, 0x22f226f8), STCP(0x7b1474fc, 0x2325b847), + STCP(0x7b05b13c, 0x2359436c), STCP(0x7af6d7e5, 0x238cc85c), STCP(0x7ae7e8fb, 0x23c04710), + STCP(0x7ad8e481, 0x23f3bf7e), STCP(0x7ac9ca79, 0x2427319d), STCP(0x7aba9ae5, 0x245a9d64), + STCP(0x7aab55c9, 0x248e02ca), STCP(0x7a9bfb26, 0x24c161c7), STCP(0x7a8c8b00, 0x24f4ba50), + STCP(0x7a7d055a, 0x25280c5d), STCP(0x7a6d6a36, 0x255b57e6), STCP(0x7a5db997, 0x258e9ce0), + STCP(0x7a4df37f, 0x25c1db43), STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a2e26f1, 0x26284421), + STCP(0x7a1e2081, 0x265b6e8a), STCP(0x7a0e04a3, 0x268e9238), STCP(0x79fdd35b, 0x26c1af21), + STCP(0x79ed8cac, 0x26f4c53e), STCP(0x79dd3097, 0x2727d485), STCP(0x79ccbf21, 0x275adcee), + STCP(0x79bc384c, 0x278dde6e), STCP(0x79ab9c1b, 0x27c0d8fe), STCP(0x799aea91, 0x27f3cc94), + STCP(0x798a23b0, 0x2826b928), STCP(0x7979477c, 0x28599eb0), STCP(0x796855f8, 0x288c7d24), + STCP(0x79574f27, 0x28bf547a), STCP(0x7946330b, 0x28f224aa), STCP(0x793501a8, 0x2924edab), + STCP(0x7923bb00, 0x2957af74), STCP(0x79125f18, 0x298a69fc), STCP(0x7900edf1, 0x29bd1d3a), + STCP(0x78ef678e, 0x29efc925), STCP(0x78ddcbf4, 0x2a226db4), STCP(0x78cc1b25, 0x2a550adf), + STCP(0x78ba5523, 0x2a87a09c), STCP(0x78a879f3, 0x2aba2ee3), STCP(0x78968997, 0x2aecb5ab), + STCP(0x78848413, 0x2b1f34eb), STCP(0x78726969, 0x2b51ac9a), STCP(0x7860399d, 0x2b841caf), + STCP(0x784df4b2, 0x2bb68521), STCP(0x783b9aac, 0x2be8e5e8), STCP(0x78292b8c, 0x2c1b3efb), + STCP(0x7816a758, 0x2c4d9050), STCP(0x78040e11, 0x2c7fd9df), STCP(0x77f15fbb, 0x2cb21ba0), + STCP(0x77de9c5a, 0x2ce45589), STCP(0x77cbc3f1, 0x2d168792), STCP(0x77b8d683, 0x2d48b1b1), + STCP(0x77a5d413, 0x2d7ad3de), STCP(0x7792bca4, 0x2dacee10), STCP(0x777f903b, 0x2ddf003f), + STCP(0x776c4eda, 0x2e110a62), STCP(0x7758f885, 0x2e430c6f), STCP(0x77458d3f, 0x2e75065e), + STCP(0x77320d0c, 0x2ea6f826), STCP(0x771e77ef, 0x2ed8e1bf), STCP(0x770acdeb, 0x2f0ac320), + STCP(0x76f70f04, 0x2f3c9c3f), STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76cf529b, 0x2fa03599), + STCP(0x76bb5520, 0x2fd1f5c1), STCP(0x76a742d0, 0x3003ad85), STCP(0x76931bae, 0x30355cdc), + STCP(0x767edfbd, 0x306703be), STCP(0x766a8f03, 0x3098a222), STCP(0x76562981, 0x30ca37ff), + STCP(0x7641af3c, 0x30fbc54d), STCP(0x762d2037, 0x312d4a02), STCP(0x76187c76, 0x315ec617), + STCP(0x7603c3fc, 0x31903982), STCP(0x75eef6ce, 0x31c1a43a), STCP(0x75da14ee, 0x31f30638), + STCP(0x75c51e60, 0x32245f72), STCP(0x75b01329, 0x3255afe0), STCP(0x759af34b, 0x3286f778), + STCP(0x7585beca, 0x32b83634), STCP(0x757075ab, 0x32e96c09), STCP(0x755b17f1, 0x331a98ef), + STCP(0x7545a59f, 0x334bbcde), STCP(0x75301eba, 0x337cd7cc), STCP(0x751a8345, 0x33ade9b2), + STCP(0x7504d344, 0x33def287), STCP(0x74ef0ebb, 0x340ff242), STCP(0x74d935ad, 0x3440e8da), + STCP(0x74c3481f, 0x3471d647), STCP(0x74ad4614, 0x34a2ba80), STCP(0x74972f91, 0x34d3957e), + STCP(0x74810498, 0x35046736), STCP(0x746ac52e, 0x35352fa1), STCP(0x74547157, 0x3565eeb6), + STCP(0x743e0917, 0x3596a46c), STCP(0x74278c71, 0x35c750bb), STCP(0x7410fb6a, 0x35f7f39b), + STCP(0x73fa5606, 0x36288d03), STCP(0x73e39c48, 0x36591cea), STCP(0x73ccce35, 0x3689a347), + STCP(0x73b5ebd0, 0x36ba2013), STCP(0x739ef51e, 0x36ea9345), STCP(0x7387ea22, 0x371afcd4), + STCP(0x7370cae1, 0x374b5cb8), STCP(0x7359975f, 0x377bb2e8), STCP(0x73424f9f, 0x37abff5c), + STCP(0x732af3a6, 0x37dc420c), STCP(0x73138379, 0x380c7aee), STCP(0x72fbff1a, 0x383ca9fb), + STCP(0x72e4668e, 0x386ccf29), STCP(0x72ccb9da, 0x389cea71), STCP(0x72b4f901, 0x38ccfbcb), + STCP(0x729d2408, 0x38fd032d), STCP(0x72853af2, 0x392d008f), STCP(0x726d3dc5, 0x395cf3e9), + STCP(0x72552c84, 0x398cdd32), STCP(0x723d0733, 0x39bcbc62), STCP(0x7224cdd7, 0x39ec9171), + STCP(0x720c8074, 0x3a1c5c56), STCP(0x71f41f0e, 0x3a4c1d09), STCP(0x71dba9aa, 0x3a7bd381), + STCP(0x71c3204b, 0x3aab7fb6), STCP(0x71aa82f6, 0x3adb21a0), STCP(0x7191d1b0, 0x3b0ab937), + STCP(0x71790c7d, 0x3b3a4671), STCP(0x71603360, 0x3b69c947), STCP(0x7147465f, 0x3b9941b0), + STCP(0x712e457e, 0x3bc8afa4), STCP(0x711530c1, 0x3bf8131b), STCP(0x70fc082d, 0x3c276c0c), + STCP(0x70e2cbc5, 0x3c56ba70), STCP(0x70c97b8f, 0x3c85fe3c), STCP(0x70b0178f, 0x3cb5376b), + STCP(0x70969fc9, 0x3ce465f2), STCP(0x707d1442, 0x3d1389cb), STCP(0x706374fe, 0x3d42a2ec), + STCP(0x7049c202, 0x3d71b14d), STCP(0x702ffb53, 0x3da0b4e6), STCP(0x701620f4, 0x3dcfadaf), + STCP(0x6ffc32ea, 0x3dfe9ba0), STCP(0x6fe2313b, 0x3e2d7eb0), STCP(0x6fc81be9, 0x3e5c56d8), + STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f93b675, 0x3eb9e64b), STCP(0x6f79665a, 0x3ee89d86), + STCP(0x6f5f02b1, 0x3f1749b7), STCP(0x6f448b7d, 0x3f45ead7), STCP(0x6f2a00c3, 0x3f7480dd), + STCP(0x6f0f6288, 0x3fa30bc0), STCP(0x6ef4b0d0, 0x3fd18b79), STCP(0x6ed9eba1, 0x3fffffff), + STCP(0x6ebf12fe, 0x402e694b), STCP(0x6ea426ed, 0x405cc754), STCP(0x6e892772, 0x408b1a12), + STCP(0x6e6e1492, 0x40b9617c), STCP(0x6e52ee51, 0x40e79d8c), STCP(0x6e37b4b6, 0x4115ce38), + STCP(0x6e1c67c3, 0x4143f378), STCP(0x6e01077f, 0x41720d45), STCP(0x6de593ed, 0x41a01b96), + STCP(0x6dca0d14, 0x41ce1e64), STCP(0x6dae72f6, 0x41fc15a6), STCP(0x6d92c59a, 0x422a0154), + STCP(0x6d770505, 0x4257e166), STCP(0x6d5b313a, 0x4285b5d4), STCP(0x6d3f4a3f, 0x42b37e95), + STCP(0x6d23501a, 0x42e13ba3), STCP(0x6d0742ce, 0x430eecf5), STCP(0x6ceb2260, 0x433c9283), + STCP(0x6cceeed7, 0x436a2c44), STCP(0x6cb2a836, 0x4397ba32), STCP(0x6c964e82, 0x43c53c43), + STCP(0x6c79e1c1, 0x43f2b270), STCP(0x6c5d61f8, 0x44201cb2), STCP(0x6c40cf2b, 0x444d7aff), + STCP(0x6c24295f, 0x447acd50), STCP(0x6c07709b, 0x44a8139d), STCP(0x6beaa4e1, 0x44d54dde), + STCP(0x6bcdc639, 0x45027c0c), STCP(0x6bb0d4a6, 0x452f9e1e), STCP(0x6b93d02d, 0x455cb40c), + STCP(0x6b76b8d5, 0x4589bdce), STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b3c5199, 0x45e3acb1), + STCP(0x6b1f01bf, 0x461091c1), STCP(0x6b019f19, 0x463d6a86), STCP(0x6ae429ad, 0x466a36f9), + STCP(0x6ac6a180, 0x4696f710), STCP(0x6aa90696, 0x46c3aac5), STCP(0x6a8b58f6, 0x46f0520f), + STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a4fc5a5, 0x47497b44), STCP(0x6a31dfff, 0x4775fd1f), + STCP(0x6a13e7b7, 0x47a27270), STCP(0x69f5dcd2, 0x47cedb30), STCP(0x69d7bf56, 0x47fb3757), + STCP(0x69b98f47, 0x482786dc), STCP(0x699b4cac, 0x4853c9b8), STCP(0x697cf789, 0x487fffe3), + STCP(0x695e8fe4, 0x48ac2956), STCP(0x694015c2, 0x48d84609), STCP(0x69218928, 0x490455f3), + STCP(0x6902ea1c, 0x4930590e), STCP(0x68e438a3, 0x495c4f51), STCP(0x68c574c3, 0x498838b6), + STCP(0x68a69e80, 0x49b41533), STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x6868baeb, 0x4a0ba75a), + STCP(0x6849ada3, 0x4a375cf4), STCP(0x682a8e0e, 0x4a630589), STCP(0x680b5c33, 0x4a8ea111), + STCP(0x67ec1816, 0x4aba2f83), STCP(0x67ccc1bd, 0x4ae5b0d9), STCP(0x67ad592e, 0x4b11250b), + STCP(0x678dde6e, 0x4b3c8c11), STCP(0x676e5182, 0x4b67e5e4), STCP(0x674eb270, 0x4b93327b), + STCP(0x672f013f, 0x4bbe71d0), STCP(0x670f3df2, 0x4be9a3db), STCP(0x66ef6890, 0x4c14c894), + STCP(0x66cf811f, 0x4c3fdff3), STCP(0x66af87a4, 0x4c6ae9f1), STCP(0x668f7c24, 0x4c95e687), + STCP(0x666f5ea5, 0x4cc0d5ad), STCP(0x664f2f2e, 0x4cebb75c), STCP(0x662eedc2, 0x4d168b8b), + STCP(0x660e9a69, 0x4d415233), STCP(0x65ee3528, 0x4d6c0b4e), STCP(0x65cdbe05, 0x4d96b6d3), + STCP(0x65ad3504, 0x4dc154bb), STCP(0x658c9a2d, 0x4debe4fe), STCP(0x656bed84, 0x4e166795), + STCP(0x654b2f0f, 0x4e40dc78), STCP(0x652a5ed5, 0x4e6b43a1), STCP(0x65097cda, 0x4e959d07), + STCP(0x64e88925, 0x4ebfe8a4), STCP(0x64c783bc, 0x4eea266f), STCP(0x64a66ca4, 0x4f145662), + STCP(0x648543e3, 0x4f3e7874), STCP(0x6464097e, 0x4f688c9f), STCP(0x6442bd7d, 0x4f9292db), + STCP(0x64215fe4, 0x4fbc8b21), STCP(0x63fff0b9, 0x4fe6756a), STCP(0x63de7003, 0x501051ad), + STCP(0x63bcddc6, 0x503a1fe4), STCP(0x639b3a0a, 0x5063e008), STCP(0x637984d4, 0x508d9211), + STCP(0x6357be29, 0x50b735f7), STCP(0x6335e610, 0x50e0cbb4), STCP(0x6313fc8f, 0x510a5340), + STCP(0x62f201ac, 0x5133cc94), STCP(0x62cff56c, 0x515d37a8), STCP(0x62add7d5, 0x51869476), + STCP(0x628ba8ef, 0x51afe2f5), STCP(0x626968be, 0x51d92320), STCP(0x62471748, 0x520254ee), + STCP(0x6224b494, 0x522b7859), STCP(0x620240a8, 0x52548d58), STCP(0x61dfbb89, 0x527d93e6), + STCP(0x61bd253e, 0x52a68bfa), STCP(0x619a7dcd, 0x52cf758e), STCP(0x6177c53c, 0x52f8509a), + STCP(0x6154fb90, 0x53211d17), STCP(0x613220d1, 0x5349daff), STCP(0x610f3504, 0x53728a49), + STCP(0x60ec382f, 0x539b2aef), STCP(0x60c92a59, 0x53c3bce9), STCP(0x60a60b87, 0x53ec4032), + STCP(0x6082dbc0, 0x5414b4c0), STCP(0x605f9b0b, 0x543d1a8e), STCP(0x603c496c, 0x54657194), + STCP(0x6018e6ea, 0x548db9cb), STCP(0x5ff5738c, 0x54b5f32c), STCP(0x5fd1ef58, 0x54de1db0), + STCP(0x5fae5a54, 0x55063950), STCP(0x5f8ab486, 0x552e4605), STCP(0x5f66fdf4, 0x555643c8), + STCP(0x5f4336a6, 0x557e3291), STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5efb75ea, 0x55cde31d), + STCP(0x5ed77c89, 0x55f5a4d2), STCP(0x5eb37284, 0x561d5771), STCP(0x5e8f57e2, 0x5644faf4), + STCP(0x5e6b2ca8, 0x566c8f54), STCP(0x5e46f0dc, 0x5694148a), STCP(0x5e22a487, 0x56bb8a8f), + STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5dd9da55, 0x570a48eb), STCP(0x5db55c85, 0x57319134), + STCP(0x5d90ce44, 0x5758ca31), STCP(0x5d6c2f99, 0x577ff3da), STCP(0x5d478089, 0x57a70e29), + STCP(0x5d22c11b, 0x57ce1916), STCP(0x5cfdf156, 0x57f5149c), STCP(0x5cd91140, 0x581c00b3), + STCP(0x5cb420df, 0x5842dd54), STCP(0x5c8f203a, 0x5869aa78), STCP(0x5c6a0f58, 0x5890681a), + STCP(0x5c44ee3f, 0x58b71631), STCP(0x5c1fbcf5, 0x58ddb4b7), STCP(0x5bfa7b81, 0x590443a6), + STCP(0x5bd529ea, 0x592ac2f6), STCP(0x5bafc836, 0x595132a2), STCP(0x5b8a566b, 0x597792a1), + STCP(0x5b64d491, 0x599de2ed), STCP(0x5b3f42ae, 0x59c42380), STCP(0x5b19a0c7, 0x59ea5454), + STCP(0x5af3eee5, 0x5a107560), STCP(0x5ace2d0e, 0x5a36869f), STCP(0x5aa85b48, 0x5a5c8809), + STCP(0x5a827999, 0x5a827999), +}; +# endif + +/* + Sine windows + */ + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow20[10] = { +# else +const PWord16 SineWindow20[10] = { +# endif + WTCP(0x7fe6bcaf, 0x5067734), WTCP(0x7f1cde00, 0xf0b7727), WTCP(0x7d8a5f3f, 0x18f8b83c), + WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x743e0917, 0x3596a46c), + WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x648543e3, 0x4f3e7874), + WTCP(0x5dfe47ad, 0x56e2f15d), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow40[20] = { +# else +const PWord16 SineWindow40[20] = { +# endif + WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7f62368f, 0x0c8bd35e), + WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7e01b096, 0x16807e15), WTCP(0x7d06aa16, 0x1b6e7b7a), + WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x78ef678f, 0x29efc925), + WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x732af3a7, 0x37dc420c), + WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6bcdc639, 0x45027c0c), + WTCP(0x6902ea1d, 0x4930590f), WTCP(0x660e9a6a, 0x4d415234), WTCP(0x62f201ac, 0x5133cc94), + WTCP(0x5fae5a55, 0x55063951), WTCP(0x5c44ee40, 0x58b71632), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow60[30] = { +# else +const PWord16 SineWindow60[30] = { +# endif + WTCP(0x7ffd3153, 0x1aceb7c), WTCP(0x7fe6bcaf, 0x5067734), WTCP(0x7fb9d758, 0x85f2136), + WTCP(0x7f76892e, 0xbb65336), WTCP(0x7f1cde00, 0xf0b7727), WTCP(0x7eace589, 0x125df75b), + WTCP(0x7e26b370, 0x15ad3e9a), WTCP(0x7d8a5f3f, 0x18f8b83c), WTCP(0x7cd80464, 0x1c3fd045), + WTCP(0x7c0fc229, 0x1f81f37b), WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7a3e17f1, 0x25f51307), + WTCP(0x793501a8, 0x2924edab), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x76e33b3e, 0x2f6e6d15), + WTCP(0x759af34b, 0x3286f778), WTCP(0x743e0917, 0x3596a46c), WTCP(0x72ccb9da, 0x389cea71), + WTCP(0x7147465f, 0x3b9941b0), WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6e01077f, 0x41720d45), + WTCP(0x6c40cf2b, 0x444d7aff), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x6887b5e1, 0x49dfe4c2), + WTCP(0x668f7c24, 0x4c95e687), WTCP(0x648543e3, 0x4f3e7874), WTCP(0x626968be, 0x51d92320), + WTCP(0x603c496c, 0x54657194), WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5bafc836, 0x595132a2), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow80[40] = { +# else +const PWord16 SineWindow80[40] = { +# endif + WTCP(0x7ffe6bbf, 0x0141b1a5), WTCP(0x7ff1c9ef, 0x03c4f52f), WTCP(0x7fd8878e, 0x0647d97c), + WTCP(0x7fb2a71b, 0x08ca1f1b), WTCP(0x7f802c52, 0x0b4b86a8), WTCP(0x7f411c2f, 0x0dcbd0d5), + WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e38b017, 0x154387e6), + WTCP(0x7dc79529, 0x17bce621), WTCP(0x7d4a105d, 0x1a33ec9c), WTCP(0x7cc02e15, 0x1ca85d12), + WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7b8788ba, 0x2188841a), WTCP(0x7ad8e482, 0x23f3bf7e), + WTCP(0x7a1e2082, 0x265b6e8a), WTCP(0x79574f28, 0x28bf547b), WTCP(0x78848414, 0x2b1f34eb), + WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x76bb5521, 0x2fd1f5c1), WTCP(0x75c51e61, 0x32245f72), + WTCP(0x74c34820, 0x3471d647), WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x729d2409, 0x38fd032d), + WTCP(0x71790c7e, 0x3b3a4672), WTCP(0x7049c203, 0x3d71b14d), WTCP(0x6f0f6289, 0x3fa30bc1), + WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6c79e1c2, 0x43f2b271), WTCP(0x6b1f01c0, 0x461091c2), + WTCP(0x69b98f48, 0x482786dc), WTCP(0x6849ada3, 0x4a375cf5), WTCP(0x66cf8120, 0x4c3fdff4), + WTCP(0x654b2f10, 0x4e40dc79), WTCP(0x63bcddc7, 0x503a1fe5), WTCP(0x6224b495, 0x522b7859), + WTCP(0x6082dbc1, 0x5414b4c1), WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5d22c11c, 0x57ce1917), + WTCP(0x5b64d492, 0x599de2ee), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow120[60] = { +# else +const PWord16 SineWindow120[60] = { +# endif + WTCP(0x7fff4c54, 0x00d676eb), WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fee74a2, 0x0430238f), + WTCP(0x7fdd9dad, 0x05dcbcbe), WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7fab1d3d, 0x093516d4), + WTCP(0x7f8975f9, 0x0ae0b22c), WTCP(0x7f62368f, 0x0c8bd35e), WTCP(0x7f3560b9, 0x0e3667ad), + WTCP(0x7f02f66f, 0x0fe05c64), WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7e8d6d91, 0x13321c53), + WTCP(0x7e4a5426, 0x14d9c245), WTCP(0x7e01b096, 0x16807e15), WTCP(0x7db3860f, 0x18263d36), + WTCP(0x7d5fd801, 0x19caed29), WTCP(0x7d06aa16, 0x1b6e7b7a), WTCP(0x7ca80038, 0x1d10d5c2), + WTCP(0x7c43de8e, 0x1eb1e9a7), WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7b6b45a5, 0x21eff528), + WTCP(0x7af6d7e6, 0x238cc85d), WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x79fdd35c, 0x26c1af22), + WTCP(0x7979477d, 0x28599eb0), WTCP(0x78ef678f, 0x29efc925), WTCP(0x7860399e, 0x2b841caf), + WTCP(0x77cbc3f2, 0x2d168792), WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x76931bae, 0x30355cdd), + WTCP(0x75eef6ce, 0x31c1a43b), WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x74972f92, 0x34d3957e), + WTCP(0x73e39c49, 0x36591cea), WTCP(0x732af3a7, 0x37dc420c), WTCP(0x726d3dc6, 0x395cf3e9), + WTCP(0x71aa82f7, 0x3adb21a1), WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x701620f5, 0x3dcfadb0), + WTCP(0x6f448b7e, 0x3f45ead8), WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6d92c59b, 0x422a0154), + WTCP(0x6cb2a837, 0x4397ba32), WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6ae429ae, 0x466a36f9), + WTCP(0x69f5dcd3, 0x47cedb31), WTCP(0x6902ea1d, 0x4930590f), WTCP(0x680b5c33, 0x4a8ea111), + WTCP(0x670f3df3, 0x4be9a3db), WTCP(0x660e9a6a, 0x4d415234), WTCP(0x65097cdb, 0x4e959d08), + WTCP(0x63fff0ba, 0x4fe6756a), WTCP(0x62f201ac, 0x5133cc94), WTCP(0x61dfbb8a, 0x527d93e6), + WTCP(0x60c92a5a, 0x53c3bcea), WTCP(0x5fae5a55, 0x55063951), WTCP(0x5e8f57e2, 0x5644faf4), + WTCP(0x5d6c2f99, 0x577ff3da), WTCP(0x5c44ee40, 0x58b71632), WTCP(0x5b19a0c8, 0x59ea5454), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow160[80] = { +# else +const PWord16 SineWindow160[80] = { +# endif + WTCP(0x7fff9aef, 0x00a0d951), WTCP(0x7ffc726f, 0x01e287fc), WTCP(0x7ff62182, 0x03242abf), + WTCP(0x7feca851, 0x0465b9aa), WTCP(0x7fe00716, 0x05a72ccf), WTCP(0x7fd03e23, 0x06e87c3f), + WTCP(0x7fbd4dda, 0x0829a00c), WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f8df93c, 0x0aab450d), + WTCP(0x7f719611, 0x0bebb66c), WTCP(0x7f520de6, 0x0d2bdc80), WTCP(0x7f2f6183, 0x0e6baf61), + WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7ee09f95, 0x10ea3bfd), WTCP(0x7eb48bfb, 0x1228e5f8), + WTCP(0x7e85580c, 0x13671d3d), WTCP(0x7e5304f2, 0x14a4d9f4), WTCP(0x7e1d93ea, 0x15e21445), + WTCP(0x7de50646, 0x171ec45c), WTCP(0x7da95d6c, 0x185ae269), WTCP(0x7d6a9ad5, 0x199666a0), + WTCP(0x7d28c00c, 0x1ad14938), WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7c9bc87a, 0x1d450a78), + WTCP(0x7c50af2b, 0x1e7dd9a4), WTCP(0x7c02849f, 0x1fb5e836), WTCP(0x7bb14ac5, 0x20ed2e7b), + WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7b05b13d, 0x2359436c), WTCP(0x7aab55ca, 0x248e02cb), + WTCP(0x7a4df380, 0x25c1db44), WTCP(0x79ed8cad, 0x26f4c53e), WTCP(0x798a23b1, 0x2826b928), + WTCP(0x7923bb01, 0x2957af74), WTCP(0x78ba5524, 0x2a87a09d), WTCP(0x784df4b3, 0x2bb68522), + WTCP(0x77de9c5b, 0x2ce45589), WTCP(0x776c4edb, 0x2e110a62), WTCP(0x76f70f05, 0x2f3c9c40), + WTCP(0x767edfbe, 0x306703bf), WTCP(0x7603c3fd, 0x31903982), WTCP(0x7585becb, 0x32b83634), + WTCP(0x7504d345, 0x33def287), WTCP(0x74810499, 0x35046736), WTCP(0x73fa5607, 0x36288d03), + WTCP(0x7370cae2, 0x374b5cb9), WTCP(0x72e4668f, 0x386ccf2a), WTCP(0x72552c85, 0x398cdd32), + WTCP(0x71c3204c, 0x3aab7fb7), WTCP(0x712e457f, 0x3bc8afa5), WTCP(0x70969fca, 0x3ce465f3), + WTCP(0x6ffc32eb, 0x3dfe9ba1), WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6ebf12ff, 0x402e694c), + WTCP(0x6e1c67c4, 0x4143f379), WTCP(0x6d770506, 0x4257e166), WTCP(0x6cceeed8, 0x436a2c45), + WTCP(0x6c242960, 0x447acd50), WTCP(0x6b76b8d6, 0x4589bdcf), WTCP(0x6ac6a180, 0x4696f710), + WTCP(0x6a13e7b8, 0x47a27271), WTCP(0x695e8fe5, 0x48ac2957), WTCP(0x68a69e81, 0x49b41533), + WTCP(0x67ec1817, 0x4aba2f84), WTCP(0x672f013f, 0x4bbe71d1), WTCP(0x666f5ea6, 0x4cc0d5ae), + WTCP(0x65ad3505, 0x4dc154bb), WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x64215fe5, 0x4fbc8b22), + WTCP(0x6357be2a, 0x50b735f8), WTCP(0x628ba8ef, 0x51afe2f6), WTCP(0x61bd253f, 0x52a68bfb), + WTCP(0x60ec3830, 0x539b2af0), WTCP(0x6018e6eb, 0x548db9cb), WTCP(0x5f4336a7, 0x557e3292), + WTCP(0x5e6b2ca8, 0x566c8f55), WTCP(0x5d90ce45, 0x5758ca31), WTCP(0x5cb420e0, 0x5842dd54), + WTCP(0x5bd529eb, 0x592ac2f7), WTCP(0x5af3eee6, 0x5a107561), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow180[90] = { +# else +const PWord16 SineWindow180[90] = { +# endif + WTCP(0x7fffb025, 0x008efa17), WTCP(0x7ffd3153, 0x01aceb7c), WTCP(0x7ff833bc, 0x02cad485), + WTCP(0x7ff0b779, 0x03e8af9e), WTCP(0x7fe6bcaf, 0x05067734), WTCP(0x7fda4390, 0x062425b6), + WTCP(0x7fcb4c5a, 0x0741b592), WTCP(0x7fb9d758, 0x085f2136), WTCP(0x7fa5e4e0, 0x097c6313), + WTCP(0x7f8f7558, 0x0a997597), WTCP(0x7f76892e, 0x0bb65336), WTCP(0x7f5b20de, 0x0cd2f660), + WTCP(0x7f3d3cf3, 0x0def5989), WTCP(0x7f1cde00, 0x0f0b7727), WTCP(0x7efa04a7, 0x102749ae), + WTCP(0x7ed4b197, 0x1142cb98), WTCP(0x7eace589, 0x125df75b), WTCP(0x7e82a145, 0x1378c774), + WTCP(0x7e55e59d, 0x1493365f), WTCP(0x7e26b370, 0x15ad3e9a), WTCP(0x7df50baa, 0x16c6daa6), + WTCP(0x7dc0ef43, 0x17e00505), WTCP(0x7d8a5f3f, 0x18f8b83c), WTCP(0x7d515cae, 0x1a10eed2), + WTCP(0x7d15e8ac, 0x1b28a351), WTCP(0x7cd80464, 0x1c3fd045), WTCP(0x7c97b108, 0x1d56703b), + WTCP(0x7c54efdb, 0x1e6c7dc7), WTCP(0x7c0fc229, 0x1f81f37b), WTCP(0x7bc8294c, 0x2096cbf0), + WTCP(0x7b7e26a9, 0x21ab01c0), WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7ae2e9e3, 0x23d16fe8), + WTCP(0x7a91b2c6, 0x24e39d85), WTCP(0x7a3e17f1, 0x25f51307), WTCP(0x79e81b05, 0x2705cb19), + WTCP(0x798fbdaf, 0x2815c069), WTCP(0x793501a8, 0x2924edab), WTCP(0x78d7e8b5, 0x2a334d95), + WTCP(0x787874a6, 0x2b40dae2), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x77b282b3, 0x2d5968a2), + WTCP(0x774c08aa, 0x2e645ea0), WTCP(0x76e33b3e, 0x2f6e6d15), WTCP(0x76781c79, 0x30778ed2), + WTCP(0x760aae72, 0x317fbeaa), WTCP(0x759af34b, 0x3286f778), WTCP(0x7528ed31, 0x338d341a), + WTCP(0x74b49e5f, 0x34926f74), WTCP(0x743e0917, 0x3596a46c), WTCP(0x73c52faa, 0x3699cdf1), + WTCP(0x734a1474, 0x379be6f6), WTCP(0x72ccb9da, 0x389cea71), WTCP(0x724d224e, 0x399cd362), + WTCP(0x71cb504d, 0x3a9b9cc9), WTCP(0x7147465f, 0x3b9941b0), WTCP(0x70c10717, 0x3c95bd25), + WTCP(0x70389513, 0x3d910a3c), WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6f212384, 0x3f8405bb), + WTCP(0x6e92296d, 0x407baa69), WTCP(0x6e01077f, 0x41720d45), WTCP(0x6d6dc08e, 0x42672980), + WTCP(0x6cd85779, 0x435afa54), WTCP(0x6c40cf2b, 0x444d7aff), WTCP(0x6ba72a97, 0x453ea6c7), + WTCP(0x6b0b6cbc, 0x462e78f8), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x69cdb161, 0x4809fdeb), + WTCP(0x692bba13, 0x48f5a767), WTCP(0x6887b5e1, 0x49dfe4c2), WTCP(0x67e1a7ff, 0x4ac8b16b), + WTCP(0x673993a8, 0x4bb008d8), WTCP(0x668f7c24, 0x4c95e687), WTCP(0x65e364c3, 0x4d7a45fd), + WTCP(0x653550e1, 0x4e5d22c5), WTCP(0x648543e3, 0x4f3e7874), WTCP(0x63d34136, 0x501e42a5), + WTCP(0x631f4c54, 0x50fc7cfa), WTCP(0x626968be, 0x51d92320), WTCP(0x61b19a00, 0x52b430c8), + WTCP(0x60f7e3b0, 0x538da1ae), WTCP(0x603c496c, 0x54657194), WTCP(0x5f7ecedd, 0x553b9c45), + WTCP(0x5ebf77b4, 0x56101d94), WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5d3b428b, 0x57b41383), + WTCP(0x5c766c1c, 0x58837ff3), WTCP(0x5bafc836, 0x595132a2), WTCP(0x5ae75ab8, 0x5a1d278c), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow240[120] = { +# else +const PWord16 SineWindow240[120] = { +# endif + WTCP(0x7fffd315, 0x006b3b9b), WTCP(0x7ffe6bbf, 0x0141b1a5), WTCP(0x7ffb9d15, 0x02182427), + WTCP(0x7ff76721, 0x02ee90c8), WTCP(0x7ff1c9ef, 0x03c4f52f), WTCP(0x7feac58d, 0x049b4f00), + WTCP(0x7fe25a0f, 0x05719be2), WTCP(0x7fd8878e, 0x0647d97c), WTCP(0x7fcd4e24, 0x071e0575), + WTCP(0x7fc0adf2, 0x07f41d72), WTCP(0x7fb2a71b, 0x08ca1f1b), WTCP(0x7fa339c5, 0x09a00817), + WTCP(0x7f92661d, 0x0a75d60e), WTCP(0x7f802c52, 0x0b4b86a8), WTCP(0x7f6c8c96, 0x0c21178c), + WTCP(0x7f578721, 0x0cf68662), WTCP(0x7f411c2f, 0x0dcbd0d5), WTCP(0x7f294bfd, 0x0ea0f48c), + WTCP(0x7f1016ce, 0x0f75ef33), WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7ed97e9c, 0x111f5ff4), + WTCP(0x7ebc1c31, 0x11f3d164), WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e7d2c54, 0x139c1abf), + WTCP(0x7e5b9f93, 0x146fee03), WTCP(0x7e38b017, 0x154387e6), WTCP(0x7e145e42, 0x1616e618), + WTCP(0x7deeaa7a, 0x16ea0646), WTCP(0x7dc79529, 0x17bce621), WTCP(0x7d9f1ebd, 0x188f8357), + WTCP(0x7d7547a7, 0x1961db9b), WTCP(0x7d4a105d, 0x1a33ec9c), WTCP(0x7d1d7958, 0x1b05b40f), + WTCP(0x7cef8315, 0x1bd72fa4), WTCP(0x7cc02e15, 0x1ca85d12), WTCP(0x7c8f7ade, 0x1d793a0b), + WTCP(0x7c5d69f7, 0x1e49c447), WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7bf53153, 0x1fe9d75f), + WTCP(0x7bbf0aba, 0x20b95bac), WTCP(0x7b8788ba, 0x2188841a), WTCP(0x7b4eabf1, 0x22574e65), + WTCP(0x7b1474fd, 0x2325b847), WTCP(0x7ad8e482, 0x23f3bf7e), WTCP(0x7a9bfb27, 0x24c161c7), + WTCP(0x7a5db997, 0x258e9ce0), WTCP(0x7a1e2082, 0x265b6e8a), WTCP(0x79dd3098, 0x2727d486), + WTCP(0x799aea92, 0x27f3cc94), WTCP(0x79574f28, 0x28bf547b), WTCP(0x79125f19, 0x298a69fc), + WTCP(0x78cc1b26, 0x2a550adf), WTCP(0x78848414, 0x2b1f34eb), WTCP(0x783b9aad, 0x2be8e5e8), + WTCP(0x77f15fbc, 0x2cb21ba0), WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x7758f886, 0x2e430c6f), + WTCP(0x770acdec, 0x2f0ac320), WTCP(0x76bb5521, 0x2fd1f5c1), WTCP(0x766a8f04, 0x3098a223), + WTCP(0x76187c77, 0x315ec617), WTCP(0x75c51e61, 0x32245f72), WTCP(0x757075ac, 0x32e96c09), + WTCP(0x751a8346, 0x33ade9b3), WTCP(0x74c34820, 0x3471d647), WTCP(0x746ac52f, 0x35352fa1), + WTCP(0x7410fb6b, 0x35f7f39c), WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x73599760, 0x377bb2e9), + WTCP(0x72fbff1b, 0x383ca9fb), WTCP(0x729d2409, 0x38fd032d), WTCP(0x723d0734, 0x39bcbc63), + WTCP(0x71dba9ab, 0x3a7bd382), WTCP(0x71790c7e, 0x3b3a4672), WTCP(0x711530c2, 0x3bf8131c), + WTCP(0x70b01790, 0x3cb5376b), WTCP(0x7049c203, 0x3d71b14d), WTCP(0x6fe2313c, 0x3e2d7eb1), + WTCP(0x6f79665b, 0x3ee89d86), WTCP(0x6f0f6289, 0x3fa30bc1), WTCP(0x6ea426ed, 0x405cc754), + WTCP(0x6e37b4b6, 0x4115ce38), WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6d5b313b, 0x4285b5d4), + WTCP(0x6ceb2261, 0x433c9283), WTCP(0x6c79e1c2, 0x43f2b271), WTCP(0x6c07709b, 0x44a8139e), + WTCP(0x6b93d02e, 0x455cb40c), WTCP(0x6b1f01c0, 0x461091c2), WTCP(0x6aa90697, 0x46c3aac5), + WTCP(0x6a31e000, 0x4775fd1f), WTCP(0x69b98f48, 0x482786dc), WTCP(0x694015c3, 0x48d84609), + WTCP(0x68c574c4, 0x498838b6), WTCP(0x6849ada3, 0x4a375cf5), WTCP(0x67ccc1be, 0x4ae5b0da), + WTCP(0x674eb271, 0x4b93327c), WTCP(0x66cf8120, 0x4c3fdff4), WTCP(0x664f2f2e, 0x4cebb75c), + WTCP(0x65cdbe05, 0x4d96b6d3), WTCP(0x654b2f10, 0x4e40dc79), WTCP(0x64c783bd, 0x4eea2670), + WTCP(0x6442bd7e, 0x4f9292dc), WTCP(0x63bcddc7, 0x503a1fe5), WTCP(0x6335e611, 0x50e0cbb4), + WTCP(0x62add7d6, 0x51869476), WTCP(0x6224b495, 0x522b7859), WTCP(0x619a7dce, 0x52cf758f), + WTCP(0x610f3505, 0x53728a4a), WTCP(0x6082dbc1, 0x5414b4c1), WTCP(0x5ff5738d, 0x54b5f32c), + WTCP(0x5f66fdf5, 0x555643c8), WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5e46f0dd, 0x5694148b), + WTCP(0x5db55c86, 0x57319135), WTCP(0x5d22c11c, 0x57ce1917), WTCP(0x5c8f203b, 0x5869aa79), + WTCP(0x5bfa7b82, 0x590443a7), WTCP(0x5b64d492, 0x599de2ee), WTCP(0x5ace2d0f, 0x5a36869f), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow320[160] = { +# else +const PWord16 SineWindow320[160] = { +# endif + WTCP(0x7fffe6bc, 0x00506cb9), WTCP(0x7fff1c9b, 0x00f145ab), WTCP(0x7ffd885a, 0x01921d20), + WTCP(0x7ffb29fd, 0x0232f21a), WTCP(0x7ff80186, 0x02d3c39b), WTCP(0x7ff40efa, 0x037490a5), + WTCP(0x7fef5260, 0x0415583b), WTCP(0x7fe9cbc0, 0x04b6195d), WTCP(0x7fe37b22, 0x0556d30f), + WTCP(0x7fdc608f, 0x05f78453), WTCP(0x7fd47c14, 0x06982c2b), WTCP(0x7fcbcdbc, 0x0738c998), + WTCP(0x7fc25596, 0x07d95b9e), WTCP(0x7fb813b0, 0x0879e140), WTCP(0x7fad081b, 0x091a597e), + WTCP(0x7fa132e8, 0x09bac35d), WTCP(0x7f949429, 0x0a5b1dde), WTCP(0x7f872bf3, 0x0afb6805), + WTCP(0x7f78fa5b, 0x0b9ba0d5), WTCP(0x7f69ff76, 0x0c3bc74f), WTCP(0x7f5a3b5e, 0x0cdbda79), + WTCP(0x7f49ae2a, 0x0d7bd954), WTCP(0x7f3857f6, 0x0e1bc2e4), WTCP(0x7f2638db, 0x0ebb962c), + WTCP(0x7f1350f8, 0x0f5b5231), WTCP(0x7effa069, 0x0ffaf5f6), WTCP(0x7eeb274d, 0x109a807e), + WTCP(0x7ed5e5c6, 0x1139f0cf), WTCP(0x7ebfdbf5, 0x11d945eb), WTCP(0x7ea909fc, 0x12787ed8), + WTCP(0x7e917000, 0x13179a9b), WTCP(0x7e790e25, 0x13b69836), WTCP(0x7e5fe493, 0x145576b1), + WTCP(0x7e45f371, 0x14f43510), WTCP(0x7e2b3ae8, 0x1592d257), WTCP(0x7e0fbb22, 0x16314d8e), + WTCP(0x7df3744b, 0x16cfa5b9), WTCP(0x7dd6668f, 0x176dd9de), WTCP(0x7db8921c, 0x180be904), + WTCP(0x7d99f721, 0x18a9d231), WTCP(0x7d7a95cf, 0x1947946c), WTCP(0x7d5a6e57, 0x19e52ebb), + WTCP(0x7d3980ec, 0x1a82a026), WTCP(0x7d17cdc2, 0x1b1fe7b3), WTCP(0x7cf5550e, 0x1bbd046c), + WTCP(0x7cd21707, 0x1c59f557), WTCP(0x7cae13e4, 0x1cf6b97c), WTCP(0x7c894bde, 0x1d934fe5), + WTCP(0x7c63bf2f, 0x1e2fb79a), WTCP(0x7c3d6e13, 0x1ecbefa4), WTCP(0x7c1658c5, 0x1f67f70b), + WTCP(0x7bee7f85, 0x2003ccdb), WTCP(0x7bc5e290, 0x209f701c), WTCP(0x7b9c8226, 0x213adfda), + WTCP(0x7b725e8a, 0x21d61b1e), WTCP(0x7b4777fe, 0x227120f3), WTCP(0x7b1bcec4, 0x230bf065), + WTCP(0x7aef6323, 0x23a6887f), WTCP(0x7ac23561, 0x2440e84d), WTCP(0x7a9445c5, 0x24db0edb), + WTCP(0x7a659496, 0x2574fb36), WTCP(0x7a362220, 0x260eac6a), WTCP(0x7a05eead, 0x26a82186), + WTCP(0x79d4fa89, 0x27415996), WTCP(0x79a34602, 0x27da53a9), WTCP(0x7970d165, 0x28730ecd), + WTCP(0x793d9d03, 0x290b8a12), WTCP(0x7909a92d, 0x29a3c485), WTCP(0x78d4f634, 0x2a3bbd37), + WTCP(0x789f846b, 0x2ad37338), WTCP(0x78695428, 0x2b6ae598), WTCP(0x783265c0, 0x2c021369), + WTCP(0x77fab989, 0x2c98fbba), WTCP(0x77c24fdb, 0x2d2f9d9f), WTCP(0x77892910, 0x2dc5f829), + WTCP(0x774f4581, 0x2e5c0a6b), WTCP(0x7714a58b, 0x2ef1d377), WTCP(0x76d94989, 0x2f875262), + WTCP(0x769d31d9, 0x301c863f), WTCP(0x76605edb, 0x30b16e23), WTCP(0x7622d0ef, 0x31460922), + WTCP(0x75e48874, 0x31da5651), WTCP(0x75a585cf, 0x326e54c7), WTCP(0x7565c962, 0x3302039b), + WTCP(0x75255392, 0x339561e1), WTCP(0x74e424c5, 0x34286eb3), WTCP(0x74a23d62, 0x34bb2927), + WTCP(0x745f9dd1, 0x354d9057), WTCP(0x741c467b, 0x35dfa35a), WTCP(0x73d837ca, 0x3671614b), + WTCP(0x7393722a, 0x3702c942), WTCP(0x734df607, 0x3793da5b), WTCP(0x7307c3d0, 0x382493b0), + WTCP(0x72c0dbf3, 0x38b4f45d), WTCP(0x72793edf, 0x3944fb7e), WTCP(0x7230ed07, 0x39d4a82f), + WTCP(0x71e7e6dc, 0x3a63f98d), WTCP(0x719e2cd2, 0x3af2eeb7), WTCP(0x7153bf5d, 0x3b8186ca), + WTCP(0x71089ef2, 0x3c0fc0e6), WTCP(0x70bccc09, 0x3c9d9c28), WTCP(0x70704718, 0x3d2b17b3), + WTCP(0x7023109a, 0x3db832a6), WTCP(0x6fd52907, 0x3e44ec22), WTCP(0x6f8690db, 0x3ed14349), + WTCP(0x6f374891, 0x3f5d373e), WTCP(0x6ee750a8, 0x3fe8c724), WTCP(0x6e96a99d, 0x4073f21d), + WTCP(0x6e4553ef, 0x40feb74f), WTCP(0x6df35020, 0x418915de), WTCP(0x6da09eb1, 0x42130cf0), + WTCP(0x6d4d4023, 0x429c9bab), WTCP(0x6cf934fc, 0x4325c135), WTCP(0x6ca47dbf, 0x43ae7cb7), + WTCP(0x6c4f1af2, 0x4436cd58), WTCP(0x6bf90d1d, 0x44beb240), WTCP(0x6ba254c7, 0x45462a9a), + WTCP(0x6b4af279, 0x45cd358f), WTCP(0x6af2e6bc, 0x4653d24b), WTCP(0x6a9a321d, 0x46d9fff8), + WTCP(0x6a40d527, 0x475fbdc3), WTCP(0x69e6d067, 0x47e50ad8), WTCP(0x698c246c, 0x4869e665), + WTCP(0x6930d1c4, 0x48ee4f98), WTCP(0x68d4d900, 0x497245a1), WTCP(0x68783ab1, 0x49f5c7ae), + WTCP(0x681af76a, 0x4a78d4f0), WTCP(0x67bd0fbd, 0x4afb6c98), WTCP(0x675e843e, 0x4b7d8dd8), + WTCP(0x66ff5584, 0x4bff37e2), WTCP(0x669f8425, 0x4c8069ea), WTCP(0x663f10b7, 0x4d012324), + WTCP(0x65ddfbd3, 0x4d8162c4), WTCP(0x657c4613, 0x4e012800), WTCP(0x6519f010, 0x4e80720e), + WTCP(0x64b6fa66, 0x4eff4025), WTCP(0x645365b2, 0x4f7d917c), WTCP(0x63ef3290, 0x4ffb654d), + WTCP(0x638a619e, 0x5078bad1), WTCP(0x6324f37d, 0x50f59141), WTCP(0x62bee8cc, 0x5171e7d9), + WTCP(0x6258422c, 0x51edbdd4), WTCP(0x61f1003f, 0x5269126e), WTCP(0x618923a9, 0x52e3e4e6), + WTCP(0x6120ad0d, 0x535e3479), WTCP(0x60b79d10, 0x53d80065), WTCP(0x604df459, 0x545147eb), + WTCP(0x5fe3b38d, 0x54ca0a4b), WTCP(0x5f78db56, 0x554246c6), WTCP(0x5f0d6c5b, 0x55b9fc9e), + WTCP(0x5ea16747, 0x56312b17), WTCP(0x5e34ccc3, 0x56a7d174), WTCP(0x5dc79d7c, 0x571deefa), + WTCP(0x5d59da1e, 0x579382ee), WTCP(0x5ceb8355, 0x58088c96), WTCP(0x5c7c99d1, 0x587d0b3b), + WTCP(0x5c0d1e41, 0x58f0fe23), WTCP(0x5b9d1154, 0x59646498), WTCP(0x5b2c73bb, 0x59d73de3), + WTCP(0x5abb4629, 0x5a498950), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow360[180] = { +# else +const PWord16 SineWindow360[180] = { +# endif + WTCP(0x7fffec08, 0x00477d17), WTCP(0x7fff4c53, 0x00d676eb), WTCP(0x7ffe0cea, 0x01656fb4), + WTCP(0x7ffc2dcf, 0x01f466bf), WTCP(0x7ff9af03, 0x02835b59), WTCP(0x7ff6908a, 0x03124cd1), + WTCP(0x7ff2d268, 0x03a13a74), WTCP(0x7fee74a1, 0x0430238f), WTCP(0x7fe9773c, 0x04bf0771), + WTCP(0x7fe3da3d, 0x054de566), WTCP(0x7fdd9dac, 0x05dcbcbe), WTCP(0x7fd6c192, 0x066b8cc5), + WTCP(0x7fcf45f6, 0x06fa54c9), WTCP(0x7fc72ae1, 0x07891418), WTCP(0x7fbe705f, 0x0817ca01), + WTCP(0x7fb51679, 0x08a675d0), WTCP(0x7fab1d3c, 0x093516d4), WTCP(0x7fa084b4, 0x09c3ac5c), + WTCP(0x7f954cee, 0x0a5235b4), WTCP(0x7f8975f8, 0x0ae0b22c), WTCP(0x7f7cffe1, 0x0b6f2112), + WTCP(0x7f6feab8, 0x0bfd81b3), WTCP(0x7f62368e, 0x0c8bd35e), WTCP(0x7f53e374, 0x0d1a1562), + WTCP(0x7f44f17c, 0x0da8470d), WTCP(0x7f3560b8, 0x0e3667ad), WTCP(0x7f25313c, 0x0ec47692), + WTCP(0x7f14631c, 0x0f52730a), WTCP(0x7f02f66e, 0x0fe05c64), WTCP(0x7ef0eb45, 0x106e31ef), + WTCP(0x7ede41ba, 0x10fbf2fa), WTCP(0x7ecaf9e4, 0x11899ed3), WTCP(0x7eb713da, 0x121734cb), + WTCP(0x7ea28fb5, 0x12a4b431), WTCP(0x7e8d6d90, 0x13321c53), WTCP(0x7e77ad84, 0x13bf6c82), + WTCP(0x7e614fac, 0x144ca40e), WTCP(0x7e4a5425, 0x14d9c245), WTCP(0x7e32bb0b, 0x1566c679), + WTCP(0x7e1a847b, 0x15f3aff8), WTCP(0x7e01b095, 0x16807e14), WTCP(0x7de83f76, 0x170d301d), + WTCP(0x7dce313e, 0x1799c562), WTCP(0x7db3860e, 0x18263d35), WTCP(0x7d983e08, 0x18b296e7), + WTCP(0x7d7c594d, 0x193ed1c8), WTCP(0x7d5fd800, 0x19caed28), WTCP(0x7d42ba45, 0x1a56e85b), + WTCP(0x7d25003f, 0x1ae2c2b0), WTCP(0x7d06aa15, 0x1b6e7b7a), WTCP(0x7ce7b7ec, 0x1bfa1209), + WTCP(0x7cc829ea, 0x1c8585b0), WTCP(0x7ca80037, 0x1d10d5c1), WTCP(0x7c873afb, 0x1d9c018f), + WTCP(0x7c65da60, 0x1e27086a), WTCP(0x7c43de8d, 0x1eb1e9a6), WTCP(0x7c2147af, 0x1f3ca496), + WTCP(0x7bfe15f0, 0x1fc7388d), WTCP(0x7bda497c, 0x2051a4dd), WTCP(0x7bb5e27f, 0x20dbe8da), + WTCP(0x7b90e128, 0x216603d7), WTCP(0x7b6b45a4, 0x21eff528), WTCP(0x7b451022, 0x2279bc21), + WTCP(0x7b1e40d3, 0x23035817), WTCP(0x7af6d7e5, 0x238cc85c), WTCP(0x7aced58b, 0x24160c47), + WTCP(0x7aa639f7, 0x249f232b), WTCP(0x7a7d055a, 0x25280c5d), WTCP(0x7a5337e9, 0x25b0c734), + WTCP(0x7a28d1d8, 0x26395303), WTCP(0x79fdd35b, 0x26c1af21), WTCP(0x79d23ca9, 0x2749dae4), + WTCP(0x79a60df7, 0x27d1d5a2), WTCP(0x7979477c, 0x28599eb0), WTCP(0x794be972, 0x28e13566), + WTCP(0x791df40f, 0x2968991b), WTCP(0x78ef678e, 0x29efc925), WTCP(0x78c04429, 0x2a76c4dc), + WTCP(0x78908a1a, 0x2afd8b97), WTCP(0x7860399d, 0x2b841caf), WTCP(0x782f52ef, 0x2c0a777b), + WTCP(0x77fdd64b, 0x2c909b54), WTCP(0x77cbc3f1, 0x2d168792), WTCP(0x77991c1e, 0x2d9c3b8e), + WTCP(0x7765df12, 0x2e21b6a2), WTCP(0x77320d0c, 0x2ea6f826), WTCP(0x76fda64e, 0x2f2bff76), + WTCP(0x76c8ab18, 0x2fb0cbea), WTCP(0x76931bae, 0x30355cdc), WTCP(0x765cf850, 0x30b9b1a9), + WTCP(0x76264144, 0x313dc9aa), WTCP(0x75eef6ce, 0x31c1a43a), WTCP(0x75b71931, 0x324540b6), + WTCP(0x757ea8b5, 0x32c89e78), WTCP(0x7545a59f, 0x334bbcde), WTCP(0x750c1038, 0x33ce9b42), + WTCP(0x74d1e8c5, 0x34513903), WTCP(0x74972f91, 0x34d3957e), WTCP(0x745be4e4, 0x3555b00e), + WTCP(0x74200908, 0x35d78813), WTCP(0x73e39c48, 0x36591cea), WTCP(0x73a69ef0, 0x36da6df1), + WTCP(0x7369114b, 0x375b7a87), WTCP(0x732af3a6, 0x37dc420c), WTCP(0x72ec4650, 0x385cc3de), + WTCP(0x72ad0995, 0x38dcff5d), WTCP(0x726d3dc5, 0x395cf3e9), WTCP(0x722ce330, 0x39dca0e2), + WTCP(0x71ebfa25, 0x3a5c05aa), WTCP(0x71aa82f6, 0x3adb21a0), WTCP(0x71687df5, 0x3b59f428), + WTCP(0x7125eb74, 0x3bd87ca1), WTCP(0x70e2cbc5, 0x3c56ba70), WTCP(0x709f1f3d, 0x3cd4acf5), + WTCP(0x705ae630, 0x3d525394), WTCP(0x701620f4, 0x3dcfadaf), WTCP(0x6fd0cfdd, 0x3e4cbaac), + WTCP(0x6f8af343, 0x3ec979ed), WTCP(0x6f448b7d, 0x3f45ead7), WTCP(0x6efd98e2, 0x3fc20ccf), + WTCP(0x6eb61bcb, 0x403ddf39), WTCP(0x6e6e1492, 0x40b9617c), WTCP(0x6e25838f, 0x413492fd), + WTCP(0x6ddc691e, 0x41af7323), WTCP(0x6d92c59a, 0x422a0154), WTCP(0x6d48995f, 0x42a43cf7), + WTCP(0x6cfde4c9, 0x431e2573), WTCP(0x6cb2a836, 0x4397ba32), WTCP(0x6c66e403, 0x4410fa9a), + WTCP(0x6c1a988f, 0x4489e615), WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6b806d61, 0x457abbe8), + WTCP(0x6b328e67, 0x45f2a513), WTCP(0x6ae429ad, 0x466a36f9), WTCP(0x6a953f94, 0x46e17102), + WTCP(0x6a45d080, 0x4758529c), WTCP(0x69f5dcd2, 0x47cedb30), WTCP(0x69a564ef, 0x48450a2d), + WTCP(0x6954693b, 0x48badefd), WTCP(0x6902ea1c, 0x4930590e), WTCP(0x68b0e7f6, 0x49a577ce), + WTCP(0x685e6331, 0x4a1a3aaa), WTCP(0x680b5c33, 0x4a8ea111), WTCP(0x67b7d363, 0x4b02aa71), + WTCP(0x6763c92b, 0x4b76563a), WTCP(0x670f3df2, 0x4be9a3db), WTCP(0x66ba3223, 0x4c5c92c4), + WTCP(0x6664a627, 0x4ccf2267), WTCP(0x660e9a69, 0x4d415233), WTCP(0x65b80f55, 0x4db3219c), + WTCP(0x65610557, 0x4e249011), WTCP(0x65097cda, 0x4e959d07), WTCP(0x64b1764d, 0x4f0647f0), + WTCP(0x6458f21d, 0x4f769040), WTCP(0x63fff0b9, 0x4fe6756a), WTCP(0x63a6728f, 0x5055f6e2), + WTCP(0x634c7810, 0x50c5141e), WTCP(0x62f201ac, 0x5133cc94), WTCP(0x62970fd2, 0x51a21fb7), + WTCP(0x623ba2f6, 0x52100d01), WTCP(0x61dfbb89, 0x527d93e6), WTCP(0x618359fd, 0x52eab3de), + WTCP(0x61267ec7, 0x53576c62), WTCP(0x60c92a59, 0x53c3bce9), WTCP(0x606b5d28, 0x542fa4ed), + WTCP(0x600d17aa, 0x549b23e7), WTCP(0x5fae5a54, 0x55063950), WTCP(0x5f4f259c, 0x5570e4a3), + WTCP(0x5eef79f8, 0x55db255b), WTCP(0x5e8f57e2, 0x5644faf4), WTCP(0x5e2ebfcf, 0x56ae64e9), + WTCP(0x5dcdb239, 0x571762b6), WTCP(0x5d6c2f99, 0x577ff3da), WTCP(0x5d0a3868, 0x57e817d1), + WTCP(0x5ca7cd21, 0x584fce19), WTCP(0x5c44ee3f, 0x58b71631), WTCP(0x5be19c3c, 0x591def98), + WTCP(0x5b7dd796, 0x598459ce), WTCP(0x5b19a0c7, 0x59ea5454), WTCP(0x5ab4f84f, 0x5a4fdea9), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow480[240] = { +# else +const PWord16 SineWindow480[240] = { +# endif + WTCP(0x7ffff4c5, 0x00359dd2), WTCP(0x7fff9aef, 0x00a0d951), WTCP(0x7ffee744, 0x010c1460), + WTCP(0x7ffdd9c4, 0x01774eb2), WTCP(0x7ffc726f, 0x01e287fc), WTCP(0x7ffab147, 0x024dbff4), + WTCP(0x7ff8964d, 0x02b8f64e), WTCP(0x7ff62182, 0x03242abf), WTCP(0x7ff352e8, 0x038f5cfb), + WTCP(0x7ff02a82, 0x03fa8cb8), WTCP(0x7feca851, 0x0465b9aa), WTCP(0x7fe8cc57, 0x04d0e386), + WTCP(0x7fe49698, 0x053c0a01), WTCP(0x7fe00716, 0x05a72ccf), WTCP(0x7fdb1dd5, 0x06124ba5), + WTCP(0x7fd5dad8, 0x067d6639), WTCP(0x7fd03e23, 0x06e87c3f), WTCP(0x7fca47b9, 0x07538d6b), + WTCP(0x7fc3f7a0, 0x07be9973), WTCP(0x7fbd4dda, 0x0829a00c), WTCP(0x7fb64a6e, 0x0894a0ea), + WTCP(0x7faeed5f, 0x08ff9bc2), WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f9f2671, 0x09d57e35), + WTCP(0x7f96bc9c, 0x0a40653a), WTCP(0x7f8df93c, 0x0aab450d), WTCP(0x7f84dc55, 0x0b161d63), + WTCP(0x7f7b65ef, 0x0b80edf1), WTCP(0x7f719611, 0x0bebb66c), WTCP(0x7f676cc0, 0x0c56768a), + WTCP(0x7f5cea05, 0x0cc12dff), WTCP(0x7f520de6, 0x0d2bdc80), WTCP(0x7f46d86c, 0x0d9681c2), + WTCP(0x7f3b499d, 0x0e011d7c), WTCP(0x7f2f6183, 0x0e6baf61), WTCP(0x7f232026, 0x0ed63727), + WTCP(0x7f16858e, 0x0f40b483), WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7efc44d0, 0x10158ed4), + WTCP(0x7eee9ebe, 0x107feb33), WTCP(0x7ee09f95, 0x10ea3bfd), WTCP(0x7ed24761, 0x115480e9), + WTCP(0x7ec3962a, 0x11beb9aa), WTCP(0x7eb48bfb, 0x1228e5f8), WTCP(0x7ea528e0, 0x12930586), + WTCP(0x7e956ce1, 0x12fd180b), WTCP(0x7e85580c, 0x13671d3d), WTCP(0x7e74ea6a, 0x13d114d0), + WTCP(0x7e642408, 0x143afe7b), WTCP(0x7e5304f2, 0x14a4d9f4), WTCP(0x7e418d32, 0x150ea6ef), + WTCP(0x7e2fbcd6, 0x15786522), WTCP(0x7e1d93ea, 0x15e21445), WTCP(0x7e0b127a, 0x164bb40b), + WTCP(0x7df83895, 0x16b5442b), WTCP(0x7de50646, 0x171ec45c), WTCP(0x7dd17b9c, 0x17883452), + WTCP(0x7dbd98a4, 0x17f193c5), WTCP(0x7da95d6c, 0x185ae269), WTCP(0x7d94ca03, 0x18c41ff6), + WTCP(0x7d7fde76, 0x192d4c21), WTCP(0x7d6a9ad5, 0x199666a0), WTCP(0x7d54ff2e, 0x19ff6f2a), + WTCP(0x7d3f0b90, 0x1a686575), WTCP(0x7d28c00c, 0x1ad14938), WTCP(0x7d121cb0, 0x1b3a1a28), + WTCP(0x7cfb218c, 0x1ba2d7fc), WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7ccc2430, 0x1c74192a), + WTCP(0x7cb42217, 0x1cdc9bf2), WTCP(0x7c9bc87a, 0x1d450a78), WTCP(0x7c831767, 0x1dad6473), + WTCP(0x7c6a0ef2, 0x1e15a99a), WTCP(0x7c50af2b, 0x1e7dd9a4), WTCP(0x7c36f824, 0x1ee5f447), + WTCP(0x7c1ce9ef, 0x1f4df93a), WTCP(0x7c02849f, 0x1fb5e836), WTCP(0x7be7c847, 0x201dc0ef), + WTCP(0x7bccb4f8, 0x2085831f), WTCP(0x7bb14ac5, 0x20ed2e7b), WTCP(0x7b9589c3, 0x2154c2bb), + WTCP(0x7b797205, 0x21bc3f97), WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7b403ea2, 0x228af1fe), + WTCP(0x7b232325, 0x22f226f8), WTCP(0x7b05b13d, 0x2359436c), WTCP(0x7ae7e8fc, 0x23c04710), + WTCP(0x7ac9ca7a, 0x2427319d), WTCP(0x7aab55ca, 0x248e02cb), WTCP(0x7a8c8b01, 0x24f4ba50), + WTCP(0x7a6d6a37, 0x255b57e6), WTCP(0x7a4df380, 0x25c1db44), WTCP(0x7a2e26f2, 0x26284422), + WTCP(0x7a0e04a4, 0x268e9238), WTCP(0x79ed8cad, 0x26f4c53e), WTCP(0x79ccbf22, 0x275adcee), + WTCP(0x79ab9c1c, 0x27c0d8fe), WTCP(0x798a23b1, 0x2826b928), WTCP(0x796855f9, 0x288c7d24), + WTCP(0x7946330c, 0x28f224ab), WTCP(0x7923bb01, 0x2957af74), WTCP(0x7900edf2, 0x29bd1d3a), + WTCP(0x78ddcbf5, 0x2a226db5), WTCP(0x78ba5524, 0x2a87a09d), WTCP(0x78968998, 0x2aecb5ac), + WTCP(0x7872696a, 0x2b51ac9a), WTCP(0x784df4b3, 0x2bb68522), WTCP(0x78292b8d, 0x2c1b3efb), + WTCP(0x78040e12, 0x2c7fd9e0), WTCP(0x77de9c5b, 0x2ce45589), WTCP(0x77b8d683, 0x2d48b1b1), + WTCP(0x7792bca5, 0x2dacee11), WTCP(0x776c4edb, 0x2e110a62), WTCP(0x77458d40, 0x2e75065e), + WTCP(0x771e77f0, 0x2ed8e1c0), WTCP(0x76f70f05, 0x2f3c9c40), WTCP(0x76cf529c, 0x2fa03599), + WTCP(0x76a742d1, 0x3003ad85), WTCP(0x767edfbe, 0x306703bf), WTCP(0x76562982, 0x30ca3800), + WTCP(0x762d2038, 0x312d4a03), WTCP(0x7603c3fd, 0x31903982), WTCP(0x75da14ef, 0x31f30638), + WTCP(0x75b01329, 0x3255afe0), WTCP(0x7585becb, 0x32b83634), WTCP(0x755b17f2, 0x331a98ef), + WTCP(0x75301ebb, 0x337cd7cd), WTCP(0x7504d345, 0x33def287), WTCP(0x74d935ae, 0x3440e8da), + WTCP(0x74ad4615, 0x34a2ba81), WTCP(0x74810499, 0x35046736), WTCP(0x74547158, 0x3565eeb6), + WTCP(0x74278c72, 0x35c750bc), WTCP(0x73fa5607, 0x36288d03), WTCP(0x73ccce36, 0x3689a348), + WTCP(0x739ef51f, 0x36ea9346), WTCP(0x7370cae2, 0x374b5cb9), WTCP(0x73424fa0, 0x37abff5d), + WTCP(0x73138379, 0x380c7aee), WTCP(0x72e4668f, 0x386ccf2a), WTCP(0x72b4f902, 0x38ccfbcb), + WTCP(0x72853af3, 0x392d008f), WTCP(0x72552c85, 0x398cdd32), WTCP(0x7224cdd8, 0x39ec9172), + WTCP(0x71f41f0f, 0x3a4c1d09), WTCP(0x71c3204c, 0x3aab7fb7), WTCP(0x7191d1b1, 0x3b0ab937), + WTCP(0x71603361, 0x3b69c947), WTCP(0x712e457f, 0x3bc8afa5), WTCP(0x70fc082d, 0x3c276c0d), + WTCP(0x70c97b90, 0x3c85fe3d), WTCP(0x70969fca, 0x3ce465f3), WTCP(0x706374ff, 0x3d42a2ec), + WTCP(0x702ffb54, 0x3da0b4e7), WTCP(0x6ffc32eb, 0x3dfe9ba1), WTCP(0x6fc81bea, 0x3e5c56d8), + WTCP(0x6f93b676, 0x3eb9e64b), WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6f2a00c4, 0x3f7480dd), + WTCP(0x6ef4b0d1, 0x3fd18b7a), WTCP(0x6ebf12ff, 0x402e694c), WTCP(0x6e892772, 0x408b1a12), + WTCP(0x6e52ee52, 0x40e79d8c), WTCP(0x6e1c67c4, 0x4143f379), WTCP(0x6de593ee, 0x41a01b97), + WTCP(0x6dae72f7, 0x41fc15a6), WTCP(0x6d770506, 0x4257e166), WTCP(0x6d3f4a40, 0x42b37e96), + WTCP(0x6d0742cf, 0x430eecf6), WTCP(0x6cceeed8, 0x436a2c45), WTCP(0x6c964e83, 0x43c53c44), + WTCP(0x6c5d61f9, 0x44201cb2), WTCP(0x6c242960, 0x447acd50), WTCP(0x6beaa4e2, 0x44d54ddf), + WTCP(0x6bb0d4a7, 0x452f9e1e), WTCP(0x6b76b8d6, 0x4589bdcf), WTCP(0x6b3c519a, 0x45e3acb1), + WTCP(0x6b019f1a, 0x463d6a87), WTCP(0x6ac6a180, 0x4696f710), WTCP(0x6a8b58f6, 0x46f0520f), + WTCP(0x6a4fc5a6, 0x47497b44), WTCP(0x6a13e7b8, 0x47a27271), WTCP(0x69d7bf57, 0x47fb3757), + WTCP(0x699b4cad, 0x4853c9b9), WTCP(0x695e8fe5, 0x48ac2957), WTCP(0x69218929, 0x490455f4), + WTCP(0x68e438a4, 0x495c4f52), WTCP(0x68a69e81, 0x49b41533), WTCP(0x6868baec, 0x4a0ba75b), + WTCP(0x682a8e0f, 0x4a63058a), WTCP(0x67ec1817, 0x4aba2f84), WTCP(0x67ad592f, 0x4b11250c), + WTCP(0x676e5183, 0x4b67e5e4), WTCP(0x672f013f, 0x4bbe71d1), WTCP(0x66ef6891, 0x4c14c894), + WTCP(0x66af87a4, 0x4c6ae9f2), WTCP(0x666f5ea6, 0x4cc0d5ae), WTCP(0x662eedc3, 0x4d168b8b), + WTCP(0x65ee3529, 0x4d6c0b4e), WTCP(0x65ad3505, 0x4dc154bb), WTCP(0x656bed84, 0x4e166795), + WTCP(0x652a5ed6, 0x4e6b43a2), WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x64a66ca5, 0x4f145662), + WTCP(0x6464097f, 0x4f688ca0), WTCP(0x64215fe5, 0x4fbc8b22), WTCP(0x63de7003, 0x501051ae), + WTCP(0x639b3a0b, 0x5063e008), WTCP(0x6357be2a, 0x50b735f8), WTCP(0x6313fc90, 0x510a5340), + WTCP(0x62cff56c, 0x515d37a9), WTCP(0x628ba8ef, 0x51afe2f6), WTCP(0x62471749, 0x520254ef), + WTCP(0x620240a8, 0x52548d59), WTCP(0x61bd253f, 0x52a68bfb), WTCP(0x6177c53c, 0x52f8509b), + WTCP(0x613220d2, 0x5349daff), WTCP(0x60ec3830, 0x539b2af0), WTCP(0x60a60b88, 0x53ec4032), + WTCP(0x605f9b0b, 0x543d1a8e), WTCP(0x6018e6eb, 0x548db9cb), WTCP(0x5fd1ef59, 0x54de1db1), + WTCP(0x5f8ab487, 0x552e4605), WTCP(0x5f4336a7, 0x557e3292), WTCP(0x5efb75ea, 0x55cde31e), + WTCP(0x5eb37285, 0x561d5771), WTCP(0x5e6b2ca8, 0x566c8f55), WTCP(0x5e22a487, 0x56bb8a90), + WTCP(0x5dd9da55, 0x570a48ec), WTCP(0x5d90ce45, 0x5758ca31), WTCP(0x5d47808a, 0x57a70e29), + WTCP(0x5cfdf157, 0x57f5149d), WTCP(0x5cb420e0, 0x5842dd54), WTCP(0x5c6a0f59, 0x5890681a), + WTCP(0x5c1fbcf6, 0x58ddb4b8), WTCP(0x5bd529eb, 0x592ac2f7), WTCP(0x5b8a566c, 0x597792a1), + WTCP(0x5b3f42ae, 0x59c42381), WTCP(0x5af3eee6, 0x5a107561), WTCP(0x5aa85b48, 0x5a5c880a), +}; + +# ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS +const PWord32 SineWindow720[360] = { + WTCP(0x7ffffb01, 0x0023be8d), WTCP(0x7fffd314, 0x006b3b9b), WTCP(0x7fff833a, 0x00b2b888), + WTCP(0x7fff0b72, 0x00fa353e), WTCP(0x7ffe6bbe, 0x0141b1a5), WTCP(0x7ffda41c, 0x01892da8), + WTCP(0x7ffcb48e, 0x01d0a930), WTCP(0x7ffb9d14, 0x02182427), WTCP(0x7ffa5dae, 0x025f9e77), + WTCP(0x7ff8f65d, 0x02a7180a), WTCP(0x7ff76720, 0x02ee90c8), WTCP(0x7ff5aff9, 0x0336089d), + WTCP(0x7ff3d0e8, 0x037d7f71), WTCP(0x7ff1c9ee, 0x03c4f52e), WTCP(0x7fef9b0a, 0x040c69bf), + WTCP(0x7fed443f, 0x0453dd0c), WTCP(0x7feac58c, 0x049b4f00), WTCP(0x7fe81ef2, 0x04e2bf83), + WTCP(0x7fe55073, 0x052a2e81), WTCP(0x7fe25a0e, 0x05719be2), WTCP(0x7fdf3bc6, 0x05b90791), + WTCP(0x7fdbf59a, 0x06007176), WTCP(0x7fd8878d, 0x0647d97c), WTCP(0x7fd4f19f, 0x068f3f8d), + WTCP(0x7fd133d0, 0x06d6a392), WTCP(0x7fcd4e23, 0x071e0575), WTCP(0x7fc94099, 0x0765651f), + WTCP(0x7fc50b33, 0x07acc27b), WTCP(0x7fc0adf1, 0x07f41d72), WTCP(0x7fbc28d6, 0x083b75ee), + WTCP(0x7fb77be3, 0x0882cbd8), WTCP(0x7fb2a71a, 0x08ca1f1b), WTCP(0x7fadaa7b, 0x09116fa0), + WTCP(0x7fa88608, 0x0958bd51), WTCP(0x7fa339c4, 0x09a00817), WTCP(0x7f9dc5b0, 0x09e74fdd), + WTCP(0x7f9829cc, 0x0a2e948c), WTCP(0x7f92661c, 0x0a75d60e), WTCP(0x7f8c7aa1, 0x0abd144d), + WTCP(0x7f86675c, 0x0b044f32), WTCP(0x7f802c51, 0x0b4b86a8), WTCP(0x7f79c980, 0x0b92ba97), + WTCP(0x7f733eeb, 0x0bd9eaeb), WTCP(0x7f6c8c95, 0x0c21178c), WTCP(0x7f65b280, 0x0c684064), + WTCP(0x7f5eb0ae, 0x0caf655e), WTCP(0x7f578720, 0x0cf68662), WTCP(0x7f5035da, 0x0d3da35c), + WTCP(0x7f48bcde, 0x0d84bc34), WTCP(0x7f411c2e, 0x0dcbd0d5), WTCP(0x7f3953cb, 0x0e12e128), + WTCP(0x7f3163ba, 0x0e59ed17), WTCP(0x7f294bfc, 0x0ea0f48c), WTCP(0x7f210c93, 0x0ee7f771), + WTCP(0x7f18a583, 0x0f2ef5b0), WTCP(0x7f1016cd, 0x0f75ef32), WTCP(0x7f076075, 0x0fbce3e2), + WTCP(0x7efe827e, 0x1003d3a9), WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7eec4fbb, 0x1091a424), + WTCP(0x7ee2faf5, 0x10d884ad), WTCP(0x7ed97e9b, 0x111f5ff3), WTCP(0x7ecfdaaf, 0x116635e3), + WTCP(0x7ec60f35, 0x11ad0665), WTCP(0x7ebc1c30, 0x11f3d164), WTCP(0x7eb201a2, 0x123a96c9), + WTCP(0x7ea7bf90, 0x1281567f), WTCP(0x7e9d55fb, 0x12c8106e), WTCP(0x7e92c4e8, 0x130ec482), + WTCP(0x7e880c5a, 0x135572a5), WTCP(0x7e7d2c53, 0x139c1abf), WTCP(0x7e7224d8, 0x13e2bcbb), + WTCP(0x7e66f5ec, 0x14295884), WTCP(0x7e5b9f92, 0x146fee02), WTCP(0x7e5021ce, 0x14b67d21), + WTCP(0x7e447ca3, 0x14fd05c9), WTCP(0x7e38b016, 0x154387e6), WTCP(0x7e2cbc29, 0x158a0360), + WTCP(0x7e20a0e1, 0x15d07823), WTCP(0x7e145e41, 0x1616e618), WTCP(0x7e07f44d, 0x165d4d28), + WTCP(0x7dfb6309, 0x16a3ad3f), WTCP(0x7deeaa79, 0x16ea0646), WTCP(0x7de1caa1, 0x17305827), + WTCP(0x7dd4c384, 0x1776a2cd), WTCP(0x7dc79528, 0x17bce621), WTCP(0x7dba3f90, 0x1803220d), + WTCP(0x7dacc2c0, 0x1849567c), WTCP(0x7d9f1ebc, 0x188f8357), WTCP(0x7d915389, 0x18d5a889), + WTCP(0x7d83612b, 0x191bc5fc), WTCP(0x7d7547a6, 0x1961db9b), WTCP(0x7d6706ff, 0x19a7e94e), + WTCP(0x7d589f3a, 0x19edef00), WTCP(0x7d4a105c, 0x1a33ec9c), WTCP(0x7d3b5a69, 0x1a79e20c), + WTCP(0x7d2c7d66, 0x1abfcf39), WTCP(0x7d1d7957, 0x1b05b40e), WTCP(0x7d0e4e41, 0x1b4b9076), + WTCP(0x7cfefc29, 0x1b91645a), WTCP(0x7cef8314, 0x1bd72fa4), WTCP(0x7cdfe306, 0x1c1cf23f), + WTCP(0x7cd01c05, 0x1c62ac16), WTCP(0x7cc02e14, 0x1ca85d12), WTCP(0x7cb0193a, 0x1cee051d), + WTCP(0x7c9fdd7b, 0x1d33a422), WTCP(0x7c8f7add, 0x1d793a0b), WTCP(0x7c7ef164, 0x1dbec6c3), + WTCP(0x7c6e4115, 0x1e044a33), WTCP(0x7c5d69f6, 0x1e49c447), WTCP(0x7c4c6c0d, 0x1e8f34e8), + WTCP(0x7c3b475d, 0x1ed49c00), WTCP(0x7c29fbed, 0x1f19f97b), WTCP(0x7c1889c3, 0x1f5f4d42), + WTCP(0x7c06f0e2, 0x1fa49740), WTCP(0x7bf53152, 0x1fe9d75f), WTCP(0x7be34b17, 0x202f0d8a), + WTCP(0x7bd13e38, 0x207439aa), WTCP(0x7bbf0ab9, 0x20b95bac), WTCP(0x7bacb0a0, 0x20fe7378), + WTCP(0x7b9a2ff4, 0x214380f9), WTCP(0x7b8788b9, 0x2188841a), WTCP(0x7b74baf7, 0x21cd7cc5), + WTCP(0x7b61c6b2, 0x22126ae5), WTCP(0x7b4eabf0, 0x22574e65), WTCP(0x7b3b6ab8, 0x229c272e), + WTCP(0x7b28030f, 0x22e0f52b), WTCP(0x7b1474fc, 0x2325b847), WTCP(0x7b00c085, 0x236a706d), + WTCP(0x7aece5af, 0x23af1d86), WTCP(0x7ad8e481, 0x23f3bf7e), WTCP(0x7ac4bd02, 0x2438563f), + WTCP(0x7ab06f36, 0x247ce1b4), WTCP(0x7a9bfb26, 0x24c161c7), WTCP(0x7a8760d7, 0x2505d663), + WTCP(0x7a72a050, 0x254a3f72), WTCP(0x7a5db997, 0x258e9ce0), WTCP(0x7a48acb2, 0x25d2ee97), + WTCP(0x7a3379a8, 0x26173481), WTCP(0x7a1e2081, 0x265b6e8a), WTCP(0x7a08a141, 0x269f9c9c), + WTCP(0x79f2fbf1, 0x26e3bea1), WTCP(0x79dd3097, 0x2727d485), WTCP(0x79c73f3a, 0x276bde33), + WTCP(0x79b127e0, 0x27afdb94), WTCP(0x799aea91, 0x27f3cc94), WTCP(0x79848753, 0x2837b11e), + WTCP(0x796dfe2d, 0x287b891c), WTCP(0x79574f27, 0x28bf547a), WTCP(0x79407a47, 0x29031322), + WTCP(0x79297f95, 0x2946c4ff), WTCP(0x79125f18, 0x298a69fc), WTCP(0x78fb18d6, 0x29ce0204), + WTCP(0x78e3acd8, 0x2a118d01), WTCP(0x78cc1b25, 0x2a550adf), WTCP(0x78b463c3, 0x2a987b89), + WTCP(0x789c86bb, 0x2adbdee9), WTCP(0x78848413, 0x2b1f34eb), WTCP(0x786c5bd4, 0x2b627d79), + WTCP(0x78540e04, 0x2ba5b87f), WTCP(0x783b9aac, 0x2be8e5e8), WTCP(0x782301d2, 0x2c2c059e), + WTCP(0x780a4380, 0x2c6f178d), WTCP(0x77f15fbb, 0x2cb21ba0), WTCP(0x77d8568d, 0x2cf511c2), + WTCP(0x77bf27fd, 0x2d37f9dd), WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x778c5ad6, 0x2dbd9faf), + WTCP(0x7772bc4f, 0x2e005d3c), WTCP(0x7758f885, 0x2e430c6f), WTCP(0x773f0f81, 0x2e85ad34), + WTCP(0x7725014b, 0x2ec83f76), WTCP(0x770acdeb, 0x2f0ac320), WTCP(0x76f07569, 0x2f4d381e), + WTCP(0x76d5f7cd, 0x2f8f9e5a), WTCP(0x76bb5520, 0x2fd1f5c1), WTCP(0x76a08d6a, 0x30143e3d), + WTCP(0x7685a0b2, 0x305677ba), WTCP(0x766a8f03, 0x3098a222), WTCP(0x764f5863, 0x30dabd63), + WTCP(0x7633fcdc, 0x311cc966), WTCP(0x76187c76, 0x315ec617), WTCP(0x75fcd739, 0x31a0b362), + WTCP(0x75e10d2f, 0x31e29131), WTCP(0x75c51e60, 0x32245f72), WTCP(0x75a90ad4, 0x32661e0e), + WTCP(0x758cd295, 0x32a7ccf2), WTCP(0x757075ab, 0x32e96c09), WTCP(0x7553f41f, 0x332afb3e), + WTCP(0x75374dfa, 0x336c7a7d), WTCP(0x751a8345, 0x33ade9b2), WTCP(0x74fd9409, 0x33ef48c8), + WTCP(0x74e0804f, 0x343097ab), WTCP(0x74c3481f, 0x3471d647), WTCP(0x74a5eb84, 0x34b30487), + WTCP(0x74886a86, 0x34f42256), WTCP(0x746ac52e, 0x35352fa1), WTCP(0x744cfb86, 0x35762c53), + WTCP(0x742f0d97, 0x35b71858), WTCP(0x7410fb6a, 0x35f7f39b), WTCP(0x73f2c509, 0x3638be09), + WTCP(0x73d46a7d, 0x3679778d), WTCP(0x73b5ebd0, 0x36ba2013), WTCP(0x7397490b, 0x36fab787), + WTCP(0x73788237, 0x373b3dd5), WTCP(0x7359975f, 0x377bb2e8), WTCP(0x733a888b, 0x37bc16ad), + WTCP(0x731b55c6, 0x37fc690f), WTCP(0x72fbff1a, 0x383ca9fb), WTCP(0x72dc848f, 0x387cd95b), + WTCP(0x72bce631, 0x38bcf71d), WTCP(0x729d2408, 0x38fd032d), WTCP(0x727d3e1f, 0x393cfd75), + WTCP(0x725d347f, 0x397ce5e3), WTCP(0x723d0733, 0x39bcbc62), WTCP(0x721cb645, 0x39fc80df), + WTCP(0x71fc41be, 0x3a3c3345), WTCP(0x71dba9aa, 0x3a7bd381), WTCP(0x71baee11, 0x3abb617f), + WTCP(0x719a0eff, 0x3afadd2b), WTCP(0x71790c7d, 0x3b3a4671), WTCP(0x7157e696, 0x3b799d3e), + WTCP(0x71369d54, 0x3bb8e17d), WTCP(0x711530c1, 0x3bf8131b), WTCP(0x70f3a0e8, 0x3c373205), + WTCP(0x70d1edd4, 0x3c763e26), WTCP(0x70b0178f, 0x3cb5376b), WTCP(0x708e1e23, 0x3cf41dc0), + WTCP(0x706c019b, 0x3d32f112), WTCP(0x7049c202, 0x3d71b14d), WTCP(0x70275f63, 0x3db05e5d), + WTCP(0x7004d9c7, 0x3deef830), WTCP(0x6fe2313b, 0x3e2d7eb0), WTCP(0x6fbf65c8, 0x3e6bf1cc), + WTCP(0x6f9c7779, 0x3eaa516f), WTCP(0x6f79665a, 0x3ee89d86), WTCP(0x6f563276, 0x3f26d5fd), + WTCP(0x6f32dbd7, 0x3f64fac2), WTCP(0x6f0f6288, 0x3fa30bc0), WTCP(0x6eebc694, 0x3fe108e5), + WTCP(0x6ec80808, 0x401ef21d), WTCP(0x6ea426ed, 0x405cc754), WTCP(0x6e80234e, 0x409a8878), + WTCP(0x6e5bfd38, 0x40d83575), WTCP(0x6e37b4b6, 0x4115ce38), WTCP(0x6e1349d2, 0x415352ad), + WTCP(0x6deebc98, 0x4190c2c3), WTCP(0x6dca0d14, 0x41ce1e64), WTCP(0x6da53b50, 0x420b657f), + WTCP(0x6d804759, 0x42489800), WTCP(0x6d5b313a, 0x4285b5d4), WTCP(0x6d35f8ff, 0x42c2bee7), + WTCP(0x6d109eb2, 0x42ffb328), WTCP(0x6ceb2260, 0x433c9283), WTCP(0x6cc58415, 0x43795ce4), + WTCP(0x6c9fc3dc, 0x43b6123a), WTCP(0x6c79e1c1, 0x43f2b270), WTCP(0x6c53ddd0, 0x442f3d75), + WTCP(0x6c2db815, 0x446bb335), WTCP(0x6c07709b, 0x44a8139d), WTCP(0x6be1076e, 0x44e45e9b), + WTCP(0x6bba7c9b, 0x4520941b), WTCP(0x6b93d02d, 0x455cb40c), WTCP(0x6b6d0232, 0x4598be59), + WTCP(0x6b4612b3, 0x45d4b2f1), WTCP(0x6b1f01bf, 0x461091c1), WTCP(0x6af7cf60, 0x464c5ab6), + WTCP(0x6ad07ba4, 0x46880dbd), WTCP(0x6aa90696, 0x46c3aac5), WTCP(0x6a817043, 0x46ff31b9), + WTCP(0x6a59b8b7, 0x473aa288), WTCP(0x6a31dfff, 0x4775fd1f), WTCP(0x6a09e626, 0x47b1416c), + WTCP(0x69e1cb3a, 0x47ec6f5b), WTCP(0x69b98f47, 0x482786dc), WTCP(0x6991325a, 0x486287da), + WTCP(0x6968b47e, 0x489d7245), WTCP(0x694015c2, 0x48d84609), WTCP(0x69175630, 0x49130314), + WTCP(0x68ee75d7, 0x494da953), WTCP(0x68c574c3, 0x498838b6), WTCP(0x689c5300, 0x49c2b128), + WTCP(0x6873109c, 0x49fd1298), WTCP(0x6849ada3, 0x4a375cf4), WTCP(0x68202a22, 0x4a71902a), + WTCP(0x67f68626, 0x4aabac27), WTCP(0x67ccc1bd, 0x4ae5b0d9), WTCP(0x67a2dcf3, 0x4b1f9e2f), + WTCP(0x6778d7d5, 0x4b597416), WTCP(0x674eb270, 0x4b93327b), WTCP(0x67246cd3, 0x4bccd94e), + WTCP(0x66fa0708, 0x4c06687c), WTCP(0x66cf811f, 0x4c3fdff3), WTCP(0x66a4db24, 0x4c793fa1), + WTCP(0x667a1524, 0x4cb28775), WTCP(0x664f2f2e, 0x4cebb75c), WTCP(0x6624294d, 0x4d24cf44), + WTCP(0x65f90390, 0x4d5dcf1c), WTCP(0x65cdbe05, 0x4d96b6d3), WTCP(0x65a258b7, 0x4dcf8655), + WTCP(0x6576d3b6, 0x4e083d93), WTCP(0x654b2f0f, 0x4e40dc78), WTCP(0x651f6acf, 0x4e7962f6), + WTCP(0x64f38704, 0x4eb1d0f8), WTCP(0x64c783bc, 0x4eea266f), WTCP(0x649b6104, 0x4f226348), + WTCP(0x646f1eeb, 0x4f5a8772), WTCP(0x6442bd7d, 0x4f9292db), WTCP(0x64163cc9, 0x4fca8572), + WTCP(0x63e99cdd, 0x50025f26), WTCP(0x63bcddc6, 0x503a1fe4), WTCP(0x638fff93, 0x5071c79c), + WTCP(0x63630252, 0x50a9563d), WTCP(0x6335e610, 0x50e0cbb4), WTCP(0x6308aadc, 0x511827f0), + WTCP(0x62db50c4, 0x514f6ae1), WTCP(0x62add7d5, 0x51869476), WTCP(0x6280401f, 0x51bda49c), + WTCP(0x625289af, 0x51f49b42), WTCP(0x6224b494, 0x522b7859), WTCP(0x61f6c0dc, 0x52623bcd), + WTCP(0x61c8ae94, 0x5298e58f), WTCP(0x619a7dcd, 0x52cf758e), WTCP(0x616c2e93, 0x5305ebb8), + WTCP(0x613dc0f6, 0x533c47fc), WTCP(0x610f3504, 0x53728a49), WTCP(0x60e08acb, 0x53a8b28f), + WTCP(0x60b1c25b, 0x53dec0bc), WTCP(0x6082dbc0, 0x5414b4c0), WTCP(0x6053d70c, 0x544a8e8a), + WTCP(0x6024b44b, 0x54804e09), WTCP(0x5ff5738c, 0x54b5f32c), WTCP(0x5fc614df, 0x54eb7de2), + WTCP(0x5f969852, 0x5520ee1c), WTCP(0x5f66fdf4, 0x555643c8), WTCP(0x5f3745d4, 0x558b7ed5), + WTCP(0x5f077001, 0x55c09f33), WTCP(0x5ed77c89, 0x55f5a4d2), WTCP(0x5ea76b7c, 0x562a8fa0), + WTCP(0x5e773ce8, 0x565f5f8e), WTCP(0x5e46f0dc, 0x5694148a), WTCP(0x5e168769, 0x56c8ae85), + WTCP(0x5de6009c, 0x56fd2d6e), WTCP(0x5db55c85, 0x57319134), WTCP(0x5d849b33, 0x5765d9c8), + WTCP(0x5d53bcb5, 0x579a0719), WTCP(0x5d22c11b, 0x57ce1916), WTCP(0x5cf1a874, 0x58020fb0), + WTCP(0x5cc072ce, 0x5835ead6), WTCP(0x5c8f203a, 0x5869aa78), WTCP(0x5c5db0c7, 0x589d4e87), + WTCP(0x5c2c2484, 0x58d0d6f0), WTCP(0x5bfa7b81, 0x590443a6), WTCP(0x5bc8b5cd, 0x59379497), + WTCP(0x5b96d378, 0x596ac9b5), WTCP(0x5b64d491, 0x599de2ed), WTCP(0x5b32b928, 0x59d0e032), + WTCP(0x5b00814c, 0x5a03c172), WTCP(0x5ace2d0e, 0x5a36869f), WTCP(0x5a9bbc7c, 0x5a692fa7) +}; +#endif + +const PWord32 SineWindow960[480] = { + WTCP(0x7ffffd30, 0x001aceea), WTCP(0x7fffe6bb, 0x00506cb9), WTCP(0x7fffb9d0, 0x00860a79), + WTCP(0x7fff7670, 0x00bba822), WTCP(0x7fff1c9a, 0x00f145ab), WTCP(0x7ffeac4f, 0x0126e309), + WTCP(0x7ffe258f, 0x015c8033), WTCP(0x7ffd8859, 0x01921d20), WTCP(0x7ffcd4af, 0x01c7b9c6), + WTCP(0x7ffc0a90, 0x01fd561d), WTCP(0x7ffb29fc, 0x0232f21a), WTCP(0x7ffa32f3, 0x02688db4), + WTCP(0x7ff92576, 0x029e28e2), WTCP(0x7ff80185, 0x02d3c39b), WTCP(0x7ff6c71f, 0x03095dd5), + WTCP(0x7ff57646, 0x033ef786), WTCP(0x7ff40ef9, 0x037490a5), WTCP(0x7ff29139, 0x03aa292a), + WTCP(0x7ff0fd06, 0x03dfc109), WTCP(0x7fef525f, 0x0415583b), WTCP(0x7fed9147, 0x044aeeb5), + WTCP(0x7febb9bc, 0x0480846e), WTCP(0x7fe9cbbf, 0x04b6195d), WTCP(0x7fe7c751, 0x04ebad79), + WTCP(0x7fe5ac71, 0x052140b7), WTCP(0x7fe37b21, 0x0556d30f), WTCP(0x7fe13360, 0x058c6478), + WTCP(0x7fded52f, 0x05c1f4e7), WTCP(0x7fdc608e, 0x05f78453), WTCP(0x7fd9d57e, 0x062d12b3), + WTCP(0x7fd73400, 0x06629ffe), WTCP(0x7fd47c13, 0x06982c2b), WTCP(0x7fd1adb8, 0x06cdb72f), + WTCP(0x7fcec8f0, 0x07034101), WTCP(0x7fcbcdbb, 0x0738c998), WTCP(0x7fc8bc1a, 0x076e50eb), + WTCP(0x7fc5940d, 0x07a3d6f0), WTCP(0x7fc25595, 0x07d95b9e), WTCP(0x7fbf00b2, 0x080edeec), + WTCP(0x7fbb9566, 0x084460cf), WTCP(0x7fb813af, 0x0879e140), WTCP(0x7fb47b90, 0x08af6033), + WTCP(0x7fb0cd09, 0x08e4dda0), WTCP(0x7fad081a, 0x091a597e), WTCP(0x7fa92cc4, 0x094fd3c3), + WTCP(0x7fa53b08, 0x09854c66), WTCP(0x7fa132e7, 0x09bac35d), WTCP(0x7f9d1460, 0x09f0389f), + WTCP(0x7f98df76, 0x0a25ac22), WTCP(0x7f949428, 0x0a5b1dde), WTCP(0x7f903278, 0x0a908dc9), + WTCP(0x7f8bba65, 0x0ac5fbd9), WTCP(0x7f872bf2, 0x0afb6805), WTCP(0x7f82871e, 0x0b30d244), + WTCP(0x7f7dcbeb, 0x0b663a8c), WTCP(0x7f78fa5a, 0x0b9ba0d5), WTCP(0x7f74126a, 0x0bd10513), + WTCP(0x7f6f141e, 0x0c06673f), WTCP(0x7f69ff75, 0x0c3bc74f), WTCP(0x7f64d472, 0x0c71253a), + WTCP(0x7f5f9314, 0x0ca680f5), WTCP(0x7f5a3b5d, 0x0cdbda79), WTCP(0x7f54cd4e, 0x0d1131ba), + WTCP(0x7f4f48e7, 0x0d4686b1), WTCP(0x7f49ae29, 0x0d7bd954), WTCP(0x7f43fd17, 0x0db12998), + WTCP(0x7f3e35af, 0x0de67776), WTCP(0x7f3857f5, 0x0e1bc2e4), WTCP(0x7f3263e8, 0x0e510bd7), + WTCP(0x7f2c5989, 0x0e865248), WTCP(0x7f2638da, 0x0ebb962c), WTCP(0x7f2001dc, 0x0ef0d77b), + WTCP(0x7f19b490, 0x0f26162a), WTCP(0x7f1350f7, 0x0f5b5231), WTCP(0x7f0cd711, 0x0f908b86), + WTCP(0x7f0646e1, 0x0fc5c220), WTCP(0x7effa068, 0x0ffaf5f6), WTCP(0x7ef8e3a5, 0x103026fe), + WTCP(0x7ef2109c, 0x1065552e), WTCP(0x7eeb274c, 0x109a807e), WTCP(0x7ee427b8, 0x10cfa8e5), + WTCP(0x7edd11e0, 0x1104ce58), WTCP(0x7ed5e5c5, 0x1139f0cf), WTCP(0x7ecea36a, 0x116f1040), + WTCP(0x7ec74ace, 0x11a42ca2), WTCP(0x7ebfdbf4, 0x11d945eb), WTCP(0x7eb856dd, 0x120e5c13), + WTCP(0x7eb0bb89, 0x12436f10), WTCP(0x7ea909fb, 0x12787ed8), WTCP(0x7ea14234, 0x12ad8b63), + WTCP(0x7e996435, 0x12e294a7), WTCP(0x7e916fff, 0x13179a9a), WTCP(0x7e896594, 0x134c9d34), + WTCP(0x7e8144f5, 0x13819c6b), WTCP(0x7e790e24, 0x13b69836), WTCP(0x7e70c123, 0x13eb908c), + WTCP(0x7e685df1, 0x14208562), WTCP(0x7e5fe492, 0x145576b1), WTCP(0x7e575507, 0x148a646e), + WTCP(0x7e4eaf50, 0x14bf4e91), WTCP(0x7e45f370, 0x14f43510), WTCP(0x7e3d2168, 0x152917e1), + WTCP(0x7e34393a, 0x155df6fc), WTCP(0x7e2b3ae7, 0x1592d257), WTCP(0x7e222671, 0x15c7a9ea), + WTCP(0x7e18fbd9, 0x15fc7da9), WTCP(0x7e0fbb21, 0x16314d8e), WTCP(0x7e06644b, 0x1666198d), + WTCP(0x7dfcf758, 0x169ae19f), WTCP(0x7df3744a, 0x16cfa5b9), WTCP(0x7de9db22, 0x170465d2), + WTCP(0x7de02be3, 0x173921e2), WTCP(0x7dd6668e, 0x176dd9de), WTCP(0x7dcc8b24, 0x17a28dbe), + WTCP(0x7dc299a8, 0x17d73d79), WTCP(0x7db8921b, 0x180be904), WTCP(0x7dae747f, 0x18409058), + WTCP(0x7da440d5, 0x1875336a), WTCP(0x7d99f720, 0x18a9d231), WTCP(0x7d8f9761, 0x18de6ca5), + WTCP(0x7d85219b, 0x191302bb), WTCP(0x7d7a95ce, 0x1947946c), WTCP(0x7d6ff3fd, 0x197c21ac), + WTCP(0x7d653c2a, 0x19b0aa75), WTCP(0x7d5a6e56, 0x19e52ebb), WTCP(0x7d4f8a84, 0x1a19ae76), + WTCP(0x7d4490b5, 0x1a4e299c), WTCP(0x7d3980eb, 0x1a82a025), WTCP(0x7d2e5b29, 0x1ab71208), + WTCP(0x7d231f6f, 0x1aeb7f3a), WTCP(0x7d17cdc1, 0x1b1fe7b3), WTCP(0x7d0c6620, 0x1b544b6a), + WTCP(0x7d00e88e, 0x1b88aa55), WTCP(0x7cf5550d, 0x1bbd046c), WTCP(0x7ce9aba0, 0x1bf159a4), + WTCP(0x7cddec47, 0x1c25a9f5), WTCP(0x7cd21706, 0x1c59f557), WTCP(0x7cc62bde, 0x1c8e3bbe), + WTCP(0x7cba2ad2, 0x1cc27d23), WTCP(0x7cae13e3, 0x1cf6b97c), WTCP(0x7ca1e714, 0x1d2af0c0), + WTCP(0x7c95a466, 0x1d5f22e6), WTCP(0x7c894bdd, 0x1d934fe5), WTCP(0x7c7cdd7a, 0x1dc777b3), + WTCP(0x7c70593f, 0x1dfb9a48), WTCP(0x7c63bf2e, 0x1e2fb79a), WTCP(0x7c570f4a, 0x1e63cfa0), + WTCP(0x7c4a4995, 0x1e97e251), WTCP(0x7c3d6e12, 0x1ecbefa3), WTCP(0x7c307cc1, 0x1efff78f), + WTCP(0x7c2375a7, 0x1f33fa0a), WTCP(0x7c1658c4, 0x1f67f70b), WTCP(0x7c09261c, 0x1f9bee8a), + WTCP(0x7bfbddb0, 0x1fcfe07d), WTCP(0x7bee7f84, 0x2003ccdb), WTCP(0x7be10b98, 0x2037b39b), + WTCP(0x7bd381f0, 0x206b94b4), WTCP(0x7bc5e28f, 0x209f701c), WTCP(0x7bb82d75, 0x20d345cb), + WTCP(0x7baa62a7, 0x210715b8), WTCP(0x7b9c8225, 0x213adfda), WTCP(0x7b8e8bf4, 0x216ea426), + WTCP(0x7b808014, 0x21a26295), WTCP(0x7b725e89, 0x21d61b1d), WTCP(0x7b642755, 0x2209cdb6), + WTCP(0x7b55da7b, 0x223d7a55), WTCP(0x7b4777fd, 0x227120f3), WTCP(0x7b38ffdd, 0x22a4c185), + WTCP(0x7b2a721e, 0x22d85c03), WTCP(0x7b1bcec3, 0x230bf064), WTCP(0x7b0d15cf, 0x233f7e9f), + WTCP(0x7afe4743, 0x237306ab), WTCP(0x7aef6323, 0x23a6887e), WTCP(0x7ae06970, 0x23da0410), + WTCP(0x7ad15a2f, 0x240d7958), WTCP(0x7ac23560, 0x2440e84c), WTCP(0x7ab2fb08, 0x247450e4), + WTCP(0x7aa3ab28, 0x24a7b316), WTCP(0x7a9445c4, 0x24db0eda), WTCP(0x7a84cadd, 0x250e6427), + WTCP(0x7a753a78, 0x2541b2f3), WTCP(0x7a659495, 0x2574fb35), WTCP(0x7a55d939, 0x25a83ce5), + WTCP(0x7a460867, 0x25db77fa), WTCP(0x7a36221f, 0x260eac6a), WTCP(0x7a262667, 0x2641da2c), + WTCP(0x7a16153f, 0x26750139), WTCP(0x7a05eeac, 0x26a82185), WTCP(0x79f5b2b0, 0x26db3b0a), + WTCP(0x79e5614e, 0x270e4dbd), WTCP(0x79d4fa88, 0x27415996), WTCP(0x79c47e62, 0x27745e8b), + WTCP(0x79b3ecdf, 0x27a75c95), WTCP(0x79a34601, 0x27da53a9), WTCP(0x799289cb, 0x280d43bf), + WTCP(0x7981b841, 0x28402cce), WTCP(0x7970d164, 0x28730ecd), WTCP(0x795fd539, 0x28a5e9b3), + WTCP(0x794ec3c2, 0x28d8bd78), WTCP(0x793d9d02, 0x290b8a11), WTCP(0x792c60fd, 0x293e4f77), + WTCP(0x791b0fb4, 0x29710da1), WTCP(0x7909a92c, 0x29a3c485), WTCP(0x78f82d67, 0x29d6741a), + WTCP(0x78e69c68, 0x2a091c59), WTCP(0x78d4f633, 0x2a3bbd37), WTCP(0x78c33aca, 0x2a6e56ac), + WTCP(0x78b16a31, 0x2aa0e8af), WTCP(0x789f846a, 0x2ad37338), WTCP(0x788d897a, 0x2b05f63d), + WTCP(0x787b7963, 0x2b3871b5), WTCP(0x78695427, 0x2b6ae598), WTCP(0x785719cb, 0x2b9d51dd), + WTCP(0x7844ca52, 0x2bcfb67b), WTCP(0x783265bf, 0x2c021368), WTCP(0x781fec14, 0x2c34689e), + WTCP(0x780d5d56, 0x2c66b611), WTCP(0x77fab988, 0x2c98fbba), WTCP(0x77e800ac, 0x2ccb3990), + WTCP(0x77d532c6, 0x2cfd6f8a), WTCP(0x77c24fda, 0x2d2f9d9f), WTCP(0x77af57eb, 0x2d61c3c6), + WTCP(0x779c4afb, 0x2d93e1f7), WTCP(0x7789290f, 0x2dc5f829), WTCP(0x7775f229, 0x2df80653), + WTCP(0x7762a64e, 0x2e2a0c6b), WTCP(0x774f4580, 0x2e5c0a6b), WTCP(0x773bcfc3, 0x2e8e0047), + WTCP(0x7728451b, 0x2ebfedf9), WTCP(0x7714a58a, 0x2ef1d377), WTCP(0x7700f114, 0x2f23b0b8), + WTCP(0x76ed27bd, 0x2f5585b4), WTCP(0x76d94988, 0x2f875262), WTCP(0x76c55679, 0x2fb916b9), + WTCP(0x76b14e92, 0x2fead2b0), WTCP(0x769d31d9, 0x301c863f), WTCP(0x7689004f, 0x304e315d), + WTCP(0x7674b9f9, 0x307fd401), WTCP(0x76605eda, 0x30b16e22), WTCP(0x764beef7, 0x30e2ffb9), + WTCP(0x76376a51, 0x311488bb), WTCP(0x7622d0ee, 0x31460921), WTCP(0x760e22d0, 0x317780e2), + WTCP(0x75f95ffb, 0x31a8eff5), WTCP(0x75e48874, 0x31da5651), WTCP(0x75cf9c3c, 0x320bb3ee), + WTCP(0x75ba9b59, 0x323d08c3), WTCP(0x75a585ce, 0x326e54c7), WTCP(0x75905b9f, 0x329f97f2), + WTCP(0x757b1ccf, 0x32d0d23b), WTCP(0x7565c961, 0x3302039a), WTCP(0x7550615b, 0x33332c06), + WTCP(0x753ae4bf, 0x33644b76), WTCP(0x75255392, 0x339561e1), WTCP(0x750fadd6, 0x33c66f3f), + WTCP(0x74f9f390, 0x33f77388), WTCP(0x74e424c5, 0x34286eb3), WTCP(0x74ce4176, 0x345960b6), + WTCP(0x74b849a9, 0x348a498b), WTCP(0x74a23d61, 0x34bb2927), WTCP(0x748c1ca3, 0x34ebff83), + WTCP(0x7475e771, 0x351ccc95), WTCP(0x745f9dd0, 0x354d9056), WTCP(0x74493fc4, 0x357e4abd), + WTCP(0x7432cd51, 0x35aefbc1), WTCP(0x741c467a, 0x35dfa35a), WTCP(0x7405ab44, 0x3610417e), + WTCP(0x73eefbb2, 0x3640d627), WTCP(0x73d837c9, 0x3671614a), WTCP(0x73c15f8c, 0x36a1e2e0), + WTCP(0x73aa7300, 0x36d25ae0), WTCP(0x73937229, 0x3702c942), WTCP(0x737c5d0a, 0x37332dfc), + WTCP(0x736533a8, 0x37638907), WTCP(0x734df606, 0x3793da5a), WTCP(0x7336a42a, 0x37c421ed), + WTCP(0x731f3e16, 0x37f45fb7), WTCP(0x7307c3cf, 0x382493b0), WTCP(0x72f03559, 0x3854bdce), + WTCP(0x72d892b9, 0x3884de0b), WTCP(0x72c0dbf2, 0x38b4f45d), WTCP(0x72a91108, 0x38e500bb), + WTCP(0x72913200, 0x3915031e), WTCP(0x72793edf, 0x3944fb7d), WTCP(0x726137a7, 0x3974e9d0), + WTCP(0x72491c5d, 0x39a4ce0e), WTCP(0x7230ed06, 0x39d4a82e), WTCP(0x7218a9a6, 0x3a047829), + WTCP(0x72005241, 0x3a343df6), WTCP(0x71e7e6db, 0x3a63f98d), WTCP(0x71cf6779, 0x3a93aae5), + WTCP(0x71b6d41f, 0x3ac351f5), WTCP(0x719e2cd1, 0x3af2eeb7), WTCP(0x71857194, 0x3b228120), + WTCP(0x716ca26b, 0x3b520929), WTCP(0x7153bf5c, 0x3b8186ca), WTCP(0x713ac86a, 0x3bb0f9f9), + WTCP(0x7121bd9b, 0x3be062b0), WTCP(0x71089ef1, 0x3c0fc0e5), WTCP(0x70ef6c73, 0x3c3f1490), + WTCP(0x70d62624, 0x3c6e5da9), WTCP(0x70bccc08, 0x3c9d9c28), WTCP(0x70a35e25, 0x3cccd004), + WTCP(0x7089dc7e, 0x3cfbf935), WTCP(0x70704718, 0x3d2b17b3), WTCP(0x70569df7, 0x3d5a2b75), + WTCP(0x703ce121, 0x3d893473), WTCP(0x70231099, 0x3db832a5), WTCP(0x70092c64, 0x3de72603), + WTCP(0x6fef3487, 0x3e160e85), WTCP(0x6fd52906, 0x3e44ec22), WTCP(0x6fbb09e6, 0x3e73bed1), + WTCP(0x6fa0d72b, 0x3ea2868c), WTCP(0x6f8690da, 0x3ed14349), WTCP(0x6f6c36f7, 0x3efff500), + WTCP(0x6f51c988, 0x3f2e9baa), WTCP(0x6f374890, 0x3f5d373e), WTCP(0x6f1cb415, 0x3f8bc7b3), + WTCP(0x6f020c1b, 0x3fba4d02), WTCP(0x6ee750a7, 0x3fe8c723), WTCP(0x6ecc81bd, 0x4017360d), + WTCP(0x6eb19f63, 0x404599b8), WTCP(0x6e96a99c, 0x4073f21d), WTCP(0x6e7ba06e, 0x40a23f32), + WTCP(0x6e6083dd, 0x40d080f0), WTCP(0x6e4553ef, 0x40feb74f), WTCP(0x6e2a10a7, 0x412ce246), + WTCP(0x6e0eba0b, 0x415b01ce), WTCP(0x6df3501f, 0x418915de), WTCP(0x6dd7d2e9, 0x41b71e6e), + WTCP(0x6dbc426d, 0x41e51b77), WTCP(0x6da09eb0, 0x42130cf0), WTCP(0x6d84e7b6, 0x4240f2d1), + WTCP(0x6d691d86, 0x426ecd12), WTCP(0x6d4d4022, 0x429c9baa), WTCP(0x6d314f92, 0x42ca5e93), + WTCP(0x6d154bd8, 0x42f815c4), WTCP(0x6cf934fb, 0x4325c135), WTCP(0x6cdd0aff, 0x435360de), + WTCP(0x6cc0cde9, 0x4380f4b6), WTCP(0x6ca47dbe, 0x43ae7cb6), WTCP(0x6c881a83, 0x43dbf8d7), + WTCP(0x6c6ba43d, 0x4409690f), WTCP(0x6c4f1af2, 0x4436cd57), WTCP(0x6c327ea5, 0x446425a7), + WTCP(0x6c15cf5c, 0x449171f7), WTCP(0x6bf90d1c, 0x44beb240), WTCP(0x6bdc37eb, 0x44ebe678), + WTCP(0x6bbf4fcc, 0x45190e99), WTCP(0x6ba254c6, 0x45462a9a), WTCP(0x6b8546dd, 0x45733a73), + WTCP(0x6b682617, 0x45a03e1d), WTCP(0x6b4af278, 0x45cd358f), WTCP(0x6b2dac05, 0x45fa20c2), + WTCP(0x6b1052c5, 0x4626ffae), WTCP(0x6af2e6bb, 0x4653d24a), WTCP(0x6ad567ee, 0x46809890), + WTCP(0x6ab7d662, 0x46ad5277), WTCP(0x6a9a321c, 0x46d9fff7), WTCP(0x6a7c7b22, 0x4706a109), + WTCP(0x6a5eb179, 0x473335a5), WTCP(0x6a40d526, 0x475fbdc2), WTCP(0x6a22e62f, 0x478c3959), + WTCP(0x6a04e498, 0x47b8a863), WTCP(0x69e6d067, 0x47e50ad7), WTCP(0x69c8a9a1, 0x481160ae), + WTCP(0x69aa704b, 0x483da9e0), WTCP(0x698c246b, 0x4869e664), WTCP(0x696dc606, 0x48961634), + WTCP(0x694f5522, 0x48c23948), WTCP(0x6930d1c3, 0x48ee4f98), WTCP(0x69123bf0, 0x491a591b), + WTCP(0x68f393ad, 0x494655cb), WTCP(0x68d4d8ff, 0x497245a0), WTCP(0x68b60bed, 0x499e2892), + WTCP(0x68972c7c, 0x49c9fe99), WTCP(0x68783ab1, 0x49f5c7ad), WTCP(0x68593691, 0x4a2183c7), + WTCP(0x683a2022, 0x4a4d32e0), WTCP(0x681af769, 0x4a78d4ef), WTCP(0x67fbbc6c, 0x4aa469ed), + WTCP(0x67dc6f31, 0x4acff1d2), WTCP(0x67bd0fbc, 0x4afb6c97), WTCP(0x679d9e13, 0x4b26da34), + WTCP(0x677e1a3d, 0x4b523aa1), WTCP(0x675e843e, 0x4b7d8dd7), WTCP(0x673edc1b, 0x4ba8d3cf), + WTCP(0x671f21db, 0x4bd40c7f), WTCP(0x66ff5584, 0x4bff37e2), WTCP(0x66df7719, 0x4c2a55ef), + WTCP(0x66bf86a2, 0x4c55669f), WTCP(0x669f8424, 0x4c8069ea), WTCP(0x667f6fa4, 0x4cab5fc9), + WTCP(0x665f4928, 0x4cd64834), WTCP(0x663f10b6, 0x4d012324), WTCP(0x661ec653, 0x4d2bf090), + WTCP(0x65fe6a05, 0x4d56b073), WTCP(0x65ddfbd2, 0x4d8162c3), WTCP(0x65bd7bc0, 0x4dac077b), + WTCP(0x659ce9d3, 0x4dd69e91), WTCP(0x657c4612, 0x4e0127ff), WTCP(0x655b9083, 0x4e2ba3be), + WTCP(0x653ac92a, 0x4e5611c5), WTCP(0x6519f00f, 0x4e80720d), WTCP(0x64f90537, 0x4eaac48f), + WTCP(0x64d808a7, 0x4ed50944), WTCP(0x64b6fa65, 0x4eff4024), WTCP(0x6495da78, 0x4f296927), + WTCP(0x6474a8e5, 0x4f538447), WTCP(0x645365b1, 0x4f7d917c), WTCP(0x643210e3, 0x4fa790be), + WTCP(0x6410aa80, 0x4fd18206), WTCP(0x63ef328f, 0x4ffb654c), WTCP(0x63cda915, 0x50253a8b), + WTCP(0x63ac0e18, 0x504f01b9), WTCP(0x638a619e, 0x5078bad0), WTCP(0x6368a3ac, 0x50a265c8), + WTCP(0x6346d44a, 0x50cc029b), WTCP(0x6324f37c, 0x50f59140), WTCP(0x63030149, 0x511f11b1), + WTCP(0x62e0fdb7, 0x514883e6), WTCP(0x62bee8cb, 0x5171e7d8), WTCP(0x629cc28c, 0x519b3d80), + WTCP(0x627a8aff, 0x51c484d6), WTCP(0x6258422b, 0x51edbdd3), WTCP(0x6235e815, 0x5216e870), + WTCP(0x62137cc4, 0x524004a6), WTCP(0x61f1003e, 0x5269126e), WTCP(0x61ce7289, 0x529211c0), + WTCP(0x61abd3aa, 0x52bb0295), WTCP(0x618923a8, 0x52e3e4e5), WTCP(0x61666289, 0x530cb8ab), + WTCP(0x61439053, 0x53357dde), WTCP(0x6120ad0c, 0x535e3478), WTCP(0x60fdb8ba, 0x5386dc71), + WTCP(0x60dab364, 0x53af75c2), WTCP(0x60b79d0f, 0x53d80064), WTCP(0x609475c2, 0x54007c50), + WTCP(0x60713d83, 0x5428e97f), WTCP(0x604df458, 0x545147ea), WTCP(0x602a9a47, 0x54799789), + WTCP(0x60072f56, 0x54a1d856), WTCP(0x5fe3b38d, 0x54ca0a4a), WTCP(0x5fc026f0, 0x54f22d5d), + WTCP(0x5f9c8986, 0x551a4188), WTCP(0x5f78db55, 0x554246c5), WTCP(0x5f551c64, 0x556a3d0c), + WTCP(0x5f314cb9, 0x55922457), WTCP(0x5f0d6c5b, 0x55b9fc9d), WTCP(0x5ee97b4e, 0x55e1c5da), + WTCP(0x5ec5799b, 0x56098004), WTCP(0x5ea16746, 0x56312b16), WTCP(0x5e7d4457, 0x5658c709), + WTCP(0x5e5910d4, 0x568053d5), WTCP(0x5e34ccc3, 0x56a7d173), WTCP(0x5e10782a, 0x56cf3fdd), + WTCP(0x5dec1310, 0x56f69f0c), WTCP(0x5dc79d7b, 0x571deef9), WTCP(0x5da31772, 0x57452f9d), + WTCP(0x5d7e80fb, 0x576c60f0), WTCP(0x5d59da1d, 0x579382ed), WTCP(0x5d3522dd, 0x57ba958c), + WTCP(0x5d105b43, 0x57e198c6), WTCP(0x5ceb8355, 0x58088c96), WTCP(0x5cc69b18, 0x582f70f2), + WTCP(0x5ca1a295, 0x585645d6), WTCP(0x5c7c99d0, 0x587d0b3a), WTCP(0x5c5780d2, 0x58a3c117), + WTCP(0x5c3257a0, 0x58ca6767), WTCP(0x5c0d1e40, 0x58f0fe22), WTCP(0x5be7d4ba, 0x59178542), + WTCP(0x5bc27b13, 0x593dfcc1), WTCP(0x5b9d1153, 0x59646497), WTCP(0x5b779780, 0x598abcbe), + WTCP(0x5b520da0, 0x59b1052e), WTCP(0x5b2c73ba, 0x59d73de2), WTCP(0x5b06c9d6, 0x59fd66d3), + WTCP(0x5ae10ff8, 0x5a237ff9), WTCP(0x5abb4628, 0x5a49894f), WTCP(0x5a956c6d, 0x5a6f82cd), +}; +# endif + +// fs 48 32 24 16 8 +// ms +-------------------- +// 10.0 | 480 320 240 160 80 +// 7.5 | 360 240 180 120 60 +// 5.0 | 240 160 120 80 40 +// 2.5 | 120 80 60 40 20 + +void BASOP_getTables( +#ifdef ENABLE_HR_MODE + const PWord32 **twiddle, const PWord32 **sin, +#else + const PWord16 **twiddle, const PWord16 **sin, +#endif + Word16 *sin_step, Word16 length) +{ + SWITCH (length) + { + case 20: + *sin = SineTable320; + move16(); + *sin_step = 32; + move16(); + *twiddle = SineWindow20; + move16(); + BREAK; + case 40: + *sin = SineTable320; + move16(); + *sin_step = 16; + move16(); + *twiddle = SineWindow40; + move16(); + BREAK; + case 60: + *sin = SineTable480; + move16(); + *sin_step = 16; + move16(); + *twiddle = SineWindow60; + move16(); + BREAK; + case 80: + *sin = SineTable320; + move16(); + *sin_step = 8; + move16(); + *twiddle = SineWindow80; + move16(); + BREAK; + case 120: + *sin = SineTable480; + move16(); + *sin_step = 8; + move16(); + *twiddle = SineWindow120; + move16(); + BREAK; + case 160: + *sin = SineTable320; + move16(); + *sin_step = 4; + move16(); + *twiddle = SineWindow160; + move16(); + BREAK; + case 180: + *sin = SineTable360; + move16(); + *sin_step = 4; + move16(); + *twiddle = SineWindow180; + move16(); + BREAK; + case 240: + *sin = SineTable480; + move16(); + *sin_step = 4; + move16(); + *twiddle = SineWindow240; + move16(); + BREAK; + case 320: + *sin = SineTable320; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow320; + move16(); + BREAK; + case 360: + *sin = SineTable360; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow360; + move16(); + BREAK; + case 480: + *sin = SineTable480; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow480; + move16(); + BREAK; +#ifdef ENABLE_HR_MODE +# ifdef CR8_G_ADD_75MS + case 720: + *sin = SineTable720; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow720; + move16(); + break; +# endif + case 960: + *sin = SineTable960; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow960; + move16(); + break; +#endif + default: ASSERT(0); + } +} + +const Word32 RealFFT32_twid[10] = { + 0x7fffffff, 0x00000000, 0x7d8a5f40, 0x18f8b83c, 0x7641af3d, + 0x30fbc54d, 0x6a6d98a4, 0x471cece7, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT40_twid[12] = { + 0x7fffffff, 0x00000000, 0x7e6c9251, 0x14060b68, 0x79bc384d, 0x278dde6e, + 0x720c8075, 0x3a1c5c57, 0x678dde6e, 0x4b3c8c12, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT64_twid[18] = { + 0x7fffffff, 0x00000000, 0x7f62368f, 0x0c8bd35e, 0x7d8a5f40, 0x18f8b83c, 0x7a7d055b, 0x25280c5e, 0x7641af3d, + 0x30fbc54d, 0x70e2cbc6, 0x3c56ba70, 0x6a6d98a4, 0x471cece7, 0x62f201ac, 0x5133cc94, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT80_twid[22] = { + 0x7fffffff, 0x00000000, 0x7f9afcb9, 0x0a0af299, 0x7e6c9251, 0x14060b68, 0x7c769e18, 0x1de189a6, + 0x79bc384d, 0x278dde6e, 0x7641af3d, 0x30fbc54d, 0x720c8075, 0x3a1c5c57, 0x6d23501b, 0x42e13ba4, + 0x678dde6e, 0x4b3c8c12, 0x6154fb91, 0x53211d18, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT96_twid[26] = { + 0x7fffffff, 0x00000000, 0x7fb9d759, 0x085f2137, 0x7ee7aa4c, 0x10b5150f, 0x7d8a5f40, 0x18f8b83c, 0x7ba3751d, + 0x2120fb83, 0x793501a9, 0x2924edac, 0x7641af3d, 0x30fbc54d, 0x72ccb9db, 0x389cea72, 0x6ed9eba1, 0x40000000, + 0x6a6d98a4, 0x471cece7, 0x658c9a2d, 0x4debe4fe, 0x603c496c, 0x54657194, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT128_twid[34] = { + 0x7fffffff, 0x00000000, 0x7fd8878e, 0x0647d97c, 0x7f62368f, 0x0c8bd35e, 0x7e9d55fc, 0x12c8106f, 0x7d8a5f40, + 0x18f8b83c, 0x7c29fbee, 0x1f19f97b, 0x7a7d055b, 0x25280c5e, 0x78848414, 0x2b1f34eb, 0x7641af3d, 0x30fbc54d, + 0x73b5ebd1, 0x36ba2014, 0x70e2cbc6, 0x3c56ba70, 0x6dca0d14, 0x41ce1e65, 0x6a6d98a4, 0x471cece7, 0x66cf8120, + 0x4c3fdff4, 0x62f201ac, 0x5133cc94, 0x5ed77c8a, 0x55f5a4d2, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT192_twid[50] = { + 0x7fffffff, 0x00000000, 0x7fee74a2, 0x0430238f, 0x7fb9d759, 0x085f2137, 0x7f62368f, 0x0c8bd35e, 0x7ee7aa4c, + 0x10b5150f, 0x7e4a5426, 0x14d9c245, 0x7d8a5f40, 0x18f8b83c, 0x7ca80038, 0x1d10d5c2, 0x7ba3751d, 0x2120fb83, + 0x7a7d055b, 0x25280c5e, 0x793501a9, 0x2924edac, 0x77cbc3f2, 0x2d168792, 0x7641af3d, 0x30fbc54d, 0x74972f92, + 0x34d3957e, 0x72ccb9db, 0x389cea72, 0x70e2cbc6, 0x3c56ba70, 0x6ed9eba1, 0x40000000, 0x6cb2a837, 0x4397ba32, + 0x6a6d98a4, 0x471cece7, 0x680b5c33, 0x4a8ea111, 0x658c9a2d, 0x4debe4fe, 0x62f201ac, 0x5133cc94, 0x603c496c, + 0x54657194, 0x5d6c2f99, 0x577ff3da, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT256_twid[66] = { + 0x7fffffff, 0x00000000, 0x7ff62182, 0x03242abf, 0x7fd8878e, 0x0647d97c, 0x7fa736b4, 0x096a9049, 0x7f62368f, + 0x0c8bd35e, 0x7f0991c4, 0x0fab272b, 0x7e9d55fc, 0x12c8106f, 0x7e1d93ea, 0x15e21445, 0x7d8a5f40, 0x18f8b83c, + 0x7ce3ceb2, 0x1c0b826a, 0x7c29fbee, 0x1f19f97b, 0x7b5d039e, 0x2223a4c5, 0x7a7d055b, 0x25280c5e, 0x798a23b1, + 0x2826b928, 0x78848414, 0x2b1f34eb, 0x776c4edb, 0x2e110a62, 0x7641af3d, 0x30fbc54d, 0x7504d345, 0x33def287, + 0x73b5ebd1, 0x36ba2014, 0x72552c85, 0x398cdd32, 0x70e2cbc6, 0x3c56ba70, 0x6f5f02b2, 0x3f1749b8, 0x6dca0d14, + 0x41ce1e65, 0x6c242960, 0x447acd50, 0x6a6d98a4, 0x471cece7, 0x68a69e81, 0x49b41533, 0x66cf8120, 0x4c3fdff4, + 0x64e88926, 0x4ebfe8a5, 0x62f201ac, 0x5133cc94, 0x60ec3830, 0x539b2af0, 0x5ed77c8a, 0x55f5a4d2, 0x5cb420e0, + 0x5842dd54, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT384_twid[98] = { + 0x7fffffff, 0x00000000, 0x7ffb9d15, 0x02182427, 0x7fee74a2, 0x0430238f, 0x7fd8878e, 0x0647d97c, 0x7fb9d759, + 0x085f2137, 0x7f92661d, 0x0a75d60e, 0x7f62368f, 0x0c8bd35e, 0x7f294bfd, 0x0ea0f48c, 0x7ee7aa4c, 0x10b5150f, + 0x7e9d55fc, 0x12c8106f, 0x7e4a5426, 0x14d9c245, 0x7deeaa7a, 0x16ea0646, 0x7d8a5f40, 0x18f8b83c, 0x7d1d7958, + 0x1b05b40f, 0x7ca80038, 0x1d10d5c2, 0x7c29fbee, 0x1f19f97b, 0x7ba3751d, 0x2120fb83, 0x7b1474fd, 0x2325b847, + 0x7a7d055b, 0x25280c5e, 0x79dd3098, 0x2727d486, 0x793501a9, 0x2924edac, 0x78848414, 0x2b1f34eb, 0x77cbc3f2, + 0x2d168792, 0x770acdec, 0x2f0ac320, 0x7641af3d, 0x30fbc54d, 0x757075ac, 0x32e96c09, 0x74972f92, 0x34d3957e, + 0x73b5ebd1, 0x36ba2014, 0x72ccb9db, 0x389cea72, 0x71dba9ab, 0x3a7bd382, 0x70e2cbc6, 0x3c56ba70, 0x6fe2313c, + 0x3e2d7eb1, 0x6ed9eba1, 0x40000000, 0x6dca0d14, 0x41ce1e65, 0x6cb2a837, 0x4397ba32, 0x6b93d02e, 0x455cb40c, + 0x6a6d98a4, 0x471cece7, 0x694015c3, 0x48d84609, 0x680b5c33, 0x4a8ea111, 0x66cf8120, 0x4c3fdff4, 0x658c9a2d, + 0x4debe4fe, 0x6442bd7e, 0x4f9292dc, 0x62f201ac, 0x5133cc94, 0x619a7dce, 0x52cf758f, 0x603c496c, 0x54657194, + 0x5ed77c8a, 0x55f5a4d2, 0x5d6c2f99, 0x577ff3da, 0x5bfa7b82, 0x590443a7, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT512_twid[130] = { + 0x7fffffff, 0x00000000, 0x7ffd885a, 0x01921d20, 0x7ff62182, 0x03242abf, 0x7fe9cbc0, 0x04b6195d, 0x7fd8878e, + 0x0647d97c, 0x7fc25596, 0x07d95b9e, 0x7fa736b4, 0x096a9049, 0x7f872bf3, 0x0afb6805, 0x7f62368f, 0x0c8bd35e, + 0x7f3857f6, 0x0e1bc2e4, 0x7f0991c4, 0x0fab272b, 0x7ed5e5c6, 0x1139f0cf, 0x7e9d55fc, 0x12c8106f, 0x7e5fe493, + 0x145576b1, 0x7e1d93ea, 0x15e21445, 0x7dd6668f, 0x176dd9de, 0x7d8a5f40, 0x18f8b83c, 0x7d3980ec, 0x1a82a026, + 0x7ce3ceb2, 0x1c0b826a, 0x7c894bde, 0x1d934fe5, 0x7c29fbee, 0x1f19f97b, 0x7bc5e290, 0x209f701c, 0x7b5d039e, + 0x2223a4c5, 0x7aef6323, 0x23a6887f, 0x7a7d055b, 0x25280c5e, 0x7a05eead, 0x26a82186, 0x798a23b1, 0x2826b928, + 0x7909a92d, 0x29a3c485, 0x78848414, 0x2b1f34eb, 0x77fab989, 0x2c98fbba, 0x776c4edb, 0x2e110a62, 0x76d94989, + 0x2f875262, 0x7641af3d, 0x30fbc54d, 0x75a585cf, 0x326e54c7, 0x7504d345, 0x33def287, 0x745f9dd1, 0x354d9057, + 0x73b5ebd1, 0x36ba2014, 0x7307c3d0, 0x382493b0, 0x72552c85, 0x398cdd32, 0x719e2cd2, 0x3af2eeb7, 0x70e2cbc6, + 0x3c56ba70, 0x7023109a, 0x3db832a6, 0x6f5f02b2, 0x3f1749b8, 0x6e96a99d, 0x4073f21d, 0x6dca0d14, 0x41ce1e65, + 0x6cf934fc, 0x4325c135, 0x6c242960, 0x447acd50, 0x6b4af279, 0x45cd358f, 0x6a6d98a4, 0x471cece7, 0x698c246c, + 0x4869e665, 0x68a69e81, 0x49b41533, 0x67bd0fbd, 0x4afb6c98, 0x66cf8120, 0x4c3fdff4, 0x65ddfbd3, 0x4d8162c4, + 0x64e88926, 0x4ebfe8a5, 0x63ef3290, 0x4ffb654d, 0x62f201ac, 0x5133cc94, 0x61f1003f, 0x5269126e, 0x60ec3830, + 0x539b2af0, 0x5fe3b38d, 0x54ca0a4b, 0x5ed77c8a, 0x55f5a4d2, 0x5dc79d7c, 0x571deefa, 0x5cb420e0, 0x5842dd54, + 0x5b9d1154, 0x59646498, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT768_twid[194] = { + 0x7fffffff, 0x00000000, 0x7ffee744, 0x010c1460, 0x7ffb9d15, 0x02182427, 0x7ff62182, 0x03242abf, 0x7fee74a2, + 0x0430238f, 0x7fe49698, 0x053c0a01, 0x7fd8878e, 0x0647d97c, 0x7fca47b9, 0x07538d6b, 0x7fb9d759, 0x085f2137, + 0x7fa736b4, 0x096a9049, 0x7f92661d, 0x0a75d60e, 0x7f7b65ef, 0x0b80edf1, 0x7f62368f, 0x0c8bd35e, 0x7f46d86c, + 0x0d9681c2, 0x7f294bfd, 0x0ea0f48c, 0x7f0991c4, 0x0fab272b, 0x7ee7aa4c, 0x10b5150f, 0x7ec3962a, 0x11beb9aa, + 0x7e9d55fc, 0x12c8106f, 0x7e74ea6a, 0x13d114d0, 0x7e4a5426, 0x14d9c245, 0x7e1d93ea, 0x15e21445, 0x7deeaa7a, + 0x16ea0646, 0x7dbd98a4, 0x17f193c5, 0x7d8a5f40, 0x18f8b83c, 0x7d54ff2e, 0x19ff6f2a, 0x7d1d7958, 0x1b05b40f, + 0x7ce3ceb2, 0x1c0b826a, 0x7ca80038, 0x1d10d5c2, 0x7c6a0ef2, 0x1e15a99a, 0x7c29fbee, 0x1f19f97b, 0x7be7c847, + 0x201dc0ef, 0x7ba3751d, 0x2120fb83, 0x7b5d039e, 0x2223a4c5, 0x7b1474fd, 0x2325b847, 0x7ac9ca7a, 0x2427319d, + 0x7a7d055b, 0x25280c5e, 0x7a2e26f2, 0x26284422, 0x79dd3098, 0x2727d486, 0x798a23b1, 0x2826b928, 0x793501a9, + 0x2924edac, 0x78ddcbf5, 0x2a226db5, 0x78848414, 0x2b1f34eb, 0x78292b8d, 0x2c1b3efb, 0x77cbc3f2, 0x2d168792, + 0x776c4edb, 0x2e110a62, 0x770acdec, 0x2f0ac320, 0x76a742d1, 0x3003ad85, 0x7641af3d, 0x30fbc54d, 0x75da14ef, + 0x31f30638, 0x757075ac, 0x32e96c09, 0x7504d345, 0x33def287, 0x74972f92, 0x34d3957e, 0x74278c72, 0x35c750bc, + 0x73b5ebd1, 0x36ba2014, 0x73424fa0, 0x37abff5d, 0x72ccb9db, 0x389cea72, 0x72552c85, 0x398cdd32, 0x71dba9ab, + 0x3a7bd382, 0x71603361, 0x3b69c947, 0x70e2cbc6, 0x3c56ba70, 0x706374ff, 0x3d42a2ec, 0x6fe2313c, 0x3e2d7eb1, + 0x6f5f02b2, 0x3f1749b8, 0x6ed9eba1, 0x40000000, 0x6e52ee52, 0x40e79d8c, 0x6dca0d14, 0x41ce1e65, 0x6d3f4a40, + 0x42b37e96, 0x6cb2a837, 0x4397ba32, 0x6c242960, 0x447acd50, 0x6b93d02e, 0x455cb40c, 0x6b019f1a, 0x463d6a87, + 0x6a6d98a4, 0x471cece7, 0x69d7bf57, 0x47fb3757, 0x694015c3, 0x48d84609, 0x68a69e81, 0x49b41533, 0x680b5c33, + 0x4a8ea111, 0x676e5183, 0x4b67e5e4, 0x66cf8120, 0x4c3fdff4, 0x662eedc3, 0x4d168b8b, 0x658c9a2d, 0x4debe4fe, + 0x64e88926, 0x4ebfe8a5, 0x6442bd7e, 0x4f9292dc, 0x639b3a0b, 0x5063e008, 0x62f201ac, 0x5133cc94, 0x62471749, + 0x520254ef, 0x619a7dce, 0x52cf758f, 0x60ec3830, 0x539b2af0, 0x603c496c, 0x54657194, 0x5f8ab487, 0x552e4605, + 0x5ed77c8a, 0x55f5a4d2, 0x5e22a487, 0x56bb8a90, 0x5d6c2f99, 0x577ff3da, 0x5cb420e0, 0x5842dd54, 0x5bfa7b82, + 0x590443a7, 0x5b3f42ae, 0x59c42381, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RotVector_32_32[2 * 20] = { + 0x7d8a5f00, 0xe70747c0, 0x7641b000, 0xcf043ac0, 0x6a6d9900, 0xb8e31300, 0x5a827980, 0xa57d8680, + 0x471ced80, 0x95926780, 0x30fbc600, 0x89be5100, 0x18f8b800, 0x8275a100, 0x7641b000, 0xcf043ac0, + 0x5a827980, 0xa57d8680, 0x30fbc600, 0x89be5100, 0xcf043b00, 0x89be5100, 0xa57d8680, 0xa57d8680, + 0x89be5100, 0xcf043ac0, 0x6a6d9900, 0xb8e31300, 0x30fbc600, 0x89be5100, 0xe7074800, 0x8275a100, + 0xa57d8680, 0xa57d8680, 0x8275a100, 0xe70747c0, 0x89be5000, 0x30fbc540, 0xb8e31280, 0x6a6d9880, +}; + +const Word32 RotVector_40_32[2 * 28] = { + 0x7e6c9251, 0x14060b68, 0x79bc384d, 0x278dde6e, 0x720c8075, 0x3a1c5c57, 0x678dde6e, 0x4b3c8c12, + 0x79bc384d, 0x278dde6e, 0x678dde6e, 0x4b3c8c12, 0x4b3c8c12, 0x678dde6e, 0x278dde6e, 0x79bc384d, + 0x720c8075, 0x3a1c5c57, 0x4b3c8c12, 0x678dde6e, 0x14060b68, 0x7e6c9251, 0xd8722192, 0x79bc384d, + 0x678dde6e, 0x4b3c8c12, 0x278dde6e, 0x79bc384d, 0xd8722192, 0x79bc384d, 0x98722192, 0x4b3c8c12, + 0x5a82799a, 0x5a82799a, 0x00000000, 0x7fffffff, 0xa57d8666, 0x5a82799a, 0x80000000, 0x00000000, + 0x4b3c8c12, 0x678dde6e, 0xd8722192, 0x79bc384d, 0x8643c7b3, 0x278dde6e, 0x98722192, 0xb4c373ee, + 0x3a1c5c57, 0x720c8075, 0xb4c373ee, 0x678dde6e, 0x81936daf, 0xebf9f498, 0xd8722192, 0x8643c7b3, +}; + +# ifdef ENABLE_HR_MODE +const Word32 RotVector_480[2 * (480 - 30)] = { +# else +const Word16 RotVector_480[2 * (480 - 30)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4), + SHC(0x00000000), SHC(0x80000000), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1), + SHC(0x80000000), SHC(0x00000000), SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa326eec0), SHC(0xa7e3ff4d), SHC(0x94a6715d), SHC(0xba4944a2), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x800b3a91), SHC(0xfca63bd8), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8757860c), SHC(0x2aba2ee4), SHC(0x9126145f), SHC(0x40000000), + SHC(0x9eab046f), SHC(0x53211d18), SHC(0xaf726def), SHC(0x637984d4), SHC(0xc2ec7635), SHC(0x707d1443), + SHC(0xd8722192), SHC(0x79bc384d), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x06b2f1d2), SHC(0x7fd317b4), + SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x340ff242), SHC(0x74ef0ebc), SHC(0x487fffe4), SHC(0x697cf78a), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8), + SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7), + SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d), + SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4), + SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e), + SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84), + SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2), + SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6), + SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d), + SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7)}; + +# ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS +const Word32 RotVector_720[2 * (720 - 30)] = { + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb0260), SHC(0xfdc41e9b), SHC(0x7fec09e3), SHC(0xfb8869ce), + SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7f834ed0), SHC(0xf4d814a4), + SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7da5f5a5), SHC(0xe7939223), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cb82885), SHC(0xe334cdc9), SHC(0x7c32a67e), SHC(0xe108b40d), + SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7a6831ba), SHC(0xda939061), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7906c0b0), SHC(0xd653c860), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76adf5e6), SHC(0xd00ce422), SHC(0x75d31a61), SHC(0xcdfc85bb), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7401e4c1), SHC(0xc9e7a512), SHC(0x730baeed), SHC(0xc7e3744b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6ff389df), SHC(0xc1f1c224), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fec09e3), SHC(0xfb8869ce), SHC(0x7fb02dc6), SHC(0xf7123849), + SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7e0e2e32), SHC(0xe9c5e582), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7c32a67e), SHC(0xe108b40d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7847d909), SHC(0xd438af17), SHC(0x76adf5e6), SHC(0xd00ce422), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x730baeed), SHC(0xc7e3744b), SHC(0x71046d3e), SHC(0xc3e85b18), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x6a1de737), SHC(0xb86c5df0), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x64dd8950), SHC(0xb1320139), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x58ea90c4), SHC(0xa3ecac65), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x4ecdfec7), SHC(0x9b2276b0), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x43d464fb), SHC(0x937328f5), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x40000000), SHC(0x9126145f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x2ff31bde), SHC(0x89520a1a), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1ef74bf3), SHC(0x83cd5982), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x04779632), SHC(0x8013f61d), SHC(0xfb8869ce), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xe108b40d), SHC(0x83cd5982), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc7e3744b), SHC(0x8cf45113), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f834ed0), SHC(0xf4d814a4), SHC(0x7e0e2e32), SHC(0xe9c5e582), + SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7847d909), SHC(0xd438af17), SHC(0x7401e4c1), SHC(0xc9e7a512), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x68d9f964), SHC(0xb6950c1e), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x496af3e2), SHC(0x9726069c), + SHC(0x40000000), SHC(0x9126145f), SHC(0x36185aee), SHC(0x8bfe1b3f), SHC(0x2bc750e9), SHC(0x87b826f7), + SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x0b27eb5c), SHC(0x807cb130), + SHC(0x00000000), SHC(0x80000000), SHC(0xf4d814a4), SHC(0x807cb130), SHC(0xe9c5e582), SHC(0x81f1d1ce), + SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xc9e7a512), SHC(0x8bfe1b3f), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb6950c1e), SHC(0x9726069c), SHC(0xadb922b7), SHC(0x9df24175), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x9726069c), SHC(0xb6950c1e), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7c32a67e), SHC(0xe108b40d), + SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x68d9f964), SHC(0xb6950c1e), + SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x53f9be05), SHC(0x9f65ad2d), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x1ccb3237), SHC(0x8347d77b), + SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xfdc41e9b), SHC(0x8004fda0), SHC(0xee2f9369), SHC(0x813ee55b), + SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc1f1c224), SHC(0x900c7621), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa8b4471a), SHC(0xa263007d), SHC(0x9df24175), SHC(0xadb922b7), + SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8cf45113), SHC(0xc7e3744b), SHC(0x86f93f50), SHC(0xd653c860), + SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x807cb130), SHC(0xf4d814a4), SHC(0x8013f61d), SHC(0x04779632), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x84f56073), SHC(0x234815ba), SHC(0x8a2ce59f), SHC(0x32037a45), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb1320139), SHC(0x9b2276b0), SHC(0xa3ecac65), SHC(0xa7156f3c), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8efb92c2), SHC(0xc3e85b18), SHC(0x87b826f7), SHC(0xd438af17), + SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x804fd23a), SHC(0x08edc7b7), + SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x8efb92c2), SHC(0x3c17a4e8), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa3ecac65), SHC(0x58ea90c4), SHC(0xb1320139), SHC(0x64dd8950), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5246dd49), SHC(0x9df24175), + SHC(0x40000000), SHC(0x9126145f), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0x00000000), SHC(0x80000000), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xd438af17), SHC(0x87b826f7), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xadb922b7), SHC(0x9df24175), SHC(0x9df24175), SHC(0xadb922b7), + SHC(0x9126145f), SHC(0xc0000000), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x81f1d1ce), SHC(0xe9c5e582), + SHC(0x80000000), SHC(0x00000000), SHC(0x81f1d1ce), SHC(0x163a1a7e), SHC(0x87b826f7), SHC(0x2bc750e9), + SHC(0x9126145f), SHC(0x40000000), SHC(0x9df24175), SHC(0x5246dd49), SHC(0xadb922b7), SHC(0x620dbe8b), + SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xd438af17), SHC(0x7847d909), SHC(0xe9c5e582), SHC(0x7e0e2e32), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x163a1a7e), SHC(0x7e0e2e32), SHC(0x2bc750e9), SHC(0x7847d909), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7da5f5a5), SHC(0xe7939223), SHC(0x76adf5e6), SHC(0xd00ce422), + SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x496af3e2), SHC(0x9726069c), + SHC(0x340ff242), SHC(0x8b10f144), SHC(0x1ccb3237), SHC(0x8347d77b), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xbe133b7c), SHC(0x92485786), + SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x99c64fc5), SHC(0xb2f7b9af), SHC(0x8cf45113), SHC(0xc7e3744b), + SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x80f43f69), SHC(0x0f996a26), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x900c7621), SHC(0x3e0e3ddc), SHC(0x9df24175), SHC(0x5246dd49), + SHC(0xaf726def), SHC(0x637984d4), SHC(0xc3e85b18), SHC(0x71046d3e), SHC(0xda939061), SHC(0x7a6831ba), + SHC(0xf29ecfb2), SHC(0x7f4c7e54), SHC(0x0b27eb5c), SHC(0x7f834ed0), SHC(0x234815ba), SHC(0x7b0a9f8d), + SHC(0x3a1c5c57), SHC(0x720c8075), SHC(0x4ecdfec7), SHC(0x64dd8950), SHC(0x609a52d3), SHC(0x53f9be05), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d), + SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4), + SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e), + SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84), + SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2), + SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6), + SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d), + SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7), + SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), + SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), + SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0xfb887fec), SHC(0xf7127fb0), + SHC(0xf29f7f4c), SHC(0xee307ec1), SHC(0xe9c67e0e), SHC(0xe5637d34), SHC(0xe1097c33), SHC(0xdcb87b0b), + SHC(0xd87279bc), SHC(0xd4397848), SHC(0xd00d76ae), SHC(0xcbf074ef), SHC(0xc7e3730c), SHC(0xc3e87104), + SHC(0x00007fff), SHC(0xf7127fb0), SHC(0xee307ec1), SHC(0xe5637d34), SHC(0xdcb87b0b), SHC(0xd4397848), + SHC(0xcbf074ef), SHC(0xc3e87104), SHC(0xbc2c6c8d), SHC(0xb4c3678e), SHC(0xadb9620e), SHC(0xa7155c13), + SHC(0xa0e155a6), SHC(0x9b224ece), SHC(0x95e24794), SHC(0x00007fff), SHC(0xf29f7f4c), SHC(0xe5637d34), + SHC(0xd87279bc), SHC(0xcbf074ef), SHC(0xc0006eda), SHC(0xb4c3678e), SHC(0xaa5a5f1f), SHC(0xa0e155a6), + SHC(0x98724b3d), SHC(0x91264000), SHC(0x8b113410), SHC(0x8644278e), SHC(0x82cc1a9d), SHC(0x80b40d61), + SHC(0x00007fff), SHC(0xee307ec1), SHC(0xdcb87b0b), SHC(0xcbf074ef), SHC(0xbc2c6c8d), SHC(0xadb9620e), + SHC(0xa0e155a6), SHC(0x95e24794), SHC(0x8cf4381d), SHC(0x8644278e), SHC(0x81f2163a), SHC(0x80140478), + SHC(0x80b4f29f), SHC(0x83cde109), SHC(0x8952d00d), SHC(0x00007fff), SHC(0xe9c67e0e), SHC(0xd4397848), + SHC(0xc0006eda), SHC(0xadb9620e), SHC(0x9df25247), SHC(0x91264000), SHC(0x87b82bc7), SHC(0x81f2163a), + SHC(0x80000000), SHC(0x81f2e9c6), SHC(0x87b8d439), SHC(0x9126c000), SHC(0x9df2adb9), SHC(0xadb99df2), + SHC(0x00007fff), SHC(0xe5637d34), SHC(0xcbf074ef), SHC(0xb4c3678e), SHC(0xa0e155a6), SHC(0x91264000), + SHC(0x8644278e), SHC(0x80b40d61), SHC(0x80b4f29f), SHC(0x8644d872), SHC(0x9126c000), SHC(0xa0e1aa5a), + SHC(0xb4c39872), SHC(0xcbf08b11), SHC(0xe56382cc), SHC(0x00007fff), SHC(0xe1097c33), SHC(0xc3e87104), + SHC(0xaa5a5f1f), SHC(0x95e24794), SHC(0x87b82bc7), SHC(0x80b40d61), SHC(0x813fee30), SHC(0x8952d00d), + SHC(0x9872b4c3), SHC(0xadb99df2), SHC(0xc7e38cf4), SHC(0xe56382cc), SHC(0x04788014), SHC(0x234884f5), + SHC(0x00007fff), SHC(0xdcb87b0b), SHC(0xbc2c6c8d), SHC(0xa0e155a6), SHC(0x8cf4381d), SHC(0x81f2163a), + SHC(0x80b4f29f), SHC(0x8952d00d), SHC(0x9b22b132), SHC(0xb4c39872), SHC(0xd43987b8), SHC(0xf7128050), + SHC(0x1a9d82cc), SHC(0x3c188efc), SHC(0x58eba3ed), SHC(0x00007fff), SHC(0xd87279bc), SHC(0xb4c3678e), + SHC(0x98724b3d), SHC(0x8644278e), SHC(0x80000000), SHC(0x8644d872), SHC(0x9872b4c3), SHC(0xb4c39872), + SHC(0xd8728644), SHC(0x00008000), SHC(0x278e8644), SHC(0x4b3d9872), SHC(0x678eb4c3), SHC(0x79bcd872), + SHC(0x00007fff), SHC(0xd4397848), SHC(0xadb9620e), SHC(0x91264000), SHC(0x81f2163a), SHC(0x81f2e9c6), + SHC(0x9126c000), SHC(0xadb99df2), SHC(0xd43987b8), SHC(0x00008000), SHC(0x2bc787b8), SHC(0x52479df2), + SHC(0x6edac000), SHC(0x7e0ee9c6), SHC(0x7e0e163a), SHC(0x00007fff), SHC(0xd00d76ae), SHC(0xa7155c13), + SHC(0x8b113410), SHC(0x80140478), SHC(0x87b8d439), SHC(0xa0e1aa5a), SHC(0xc7e38cf4), SHC(0xf7128050), + SHC(0x278e8644), SHC(0x52479df2), SHC(0x7104c3e8), SHC(0x7f4cf29f), SHC(0x7b0b2348), SHC(0x64de4ece), + SHC(0x00007fff), SHC(0xe21e7c77), SHC(0xc5e4720d), SHC(0xacdf6155), SHC(0x98724b3d), SHC(0x89be30fc), + SHC(0x81931406), SHC(0x8065f5f5), SHC(0x8644d872), SHC(0x92ddbd1f), SHC(0xa57ea57e), SHC(0xbd1f92dd), + SHC(0xd8728644), SHC(0xf5f58065), SHC(0x14068193), SHC(0x00007fff), SHC(0xdba57abb), SHC(0xba496b5a), + SHC(0x9eab5321), SHC(0x8b113410), SHC(0x811810b5), SHC(0x8193ebfa), SHC(0x8c78c8e5), SHC(0xa0e1aa5a), + SHC(0xbd1f92dd), SHC(0xdedf845d), SHC(0x035a800b), SHC(0x278e8644), SHC(0x48809683), SHC(0x637aaf72), + SHC(0x00007fff), SHC(0xd54678a8), SHC(0xaf72637a), SHC(0x92dd42e1), SHC(0x82cc1a9d), SHC(0x8118ef4b), + SHC(0x8df3c5e4), SHC(0xa7e4a327), SHC(0xcbf08b11), SHC(0xf5f58065), SHC(0x2121845d), SHC(0x48809683), + SHC(0x678eb4c3), SHC(0x7abbdba5), SHC(0x7fd306b3), SHC(0x00007fff), SHC(0xcf047642), SHC(0xa57e5a82), + SHC(0x89be30fc), SHC(0x80000000), SHC(0x89becf04), SHC(0xa57ea57e), SHC(0xcf0489be), SHC(0x00008000), + SHC(0x30fc89be), SHC(0x5a82a57e), SHC(0x7642cf04), SHC(0x7fff0000), SHC(0x764230fc), SHC(0x5a825a82), + SHC(0xe2e1004b), SHC(0x00000000), SHC(0x00000000), SHC(0x6fb076e0), SHC(0x002fba9c), SHC(0x6fb079d0), + SHC(0x8d92be50), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff), + SHC(0x00010000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff), SHC(0x00010000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xeabee318), SHC(0x00000000), SHC(0x4d55545a), + SHC(0000000000), SHC(0000000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff), SHC(0x904f882f), + SHC(0x4d55545a), SHC(0x00000000), SHC(0x00000000), SHC(0x006f5dd8), SHC(0x40000000), SHC(0x00666004), + SHC(0x006ec0b0), SHC(0x00660000), SHC(0x006f5dd8), SHC(0x42000000), SHC(0x00665fa0), SHC(0x006ec080), + SHC(0x6fb07880), SHC(0x00660000), SHC(0x00660000), SHC(0x00309ca0), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0xffffffff), SHC(0x00010000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x0d888000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000170), SHC(0x00000000), SHC(0x00000000), SHC(0x6fb07880), SHC(0x6fb078a8), SHC(0x8d926000), + SHC(0x0d888000), SHC(0x8d888000), SHC(0x6fb079e0), SHC(0x00000000), SHC(0000000000), SHC(0x002f8000), + SHC(0x00000001), SHC(0x6fb07b40), SHC(0x00000000), SHC(0x6fb07b54), SHC(0x6fb07b70), SHC(0x6fb07b80), + SHC(0x6fb07b94), SHC(0x6fb07bcd), SHC(0x6fb07be6), SHC(0x6fb07c0e), SHC(0x6fb07c43), SHC(0x6fb07c4d), + SHC(0x6fb07c8f), SHC(0x6fb07d49), SHC(0x6fb07d71), SHC(0x6fb07d9e), SHC(0x6fb07daf), SHC(0x6fb07dbd), + SHC(0x6fb07dcc), SHC(0x6fb07ddf), SHC(0x6fb07de7), SHC(0x6fb07df8), SHC(0x6fb07e05), SHC(0x6fb07e45), + SHC(0x00000000), SHC(0x6fb07b18), SHC(0x6fb07e60), SHC(0x6fb07e70), SHC(0x6fb07e8f), SHC(0x6fb07ec4), + SHC(0x6fb07ee1), SHC(0x6fb07f17), SHC(0x6fb07f3e), SHC(0x6fb07f67), SHC(0x6fb07fa2), SHC(0x6fb07fdf), + SHC(0x6fb07fed), SHC(0x00000000), SHC(0x63657865), SHC(0x705f656c), SHC(0x65672f2e), SHC(0x6f526574), + SHC(0x00726f74), SHC(0x65672f2e), SHC(0x6f526574), SHC(0x00726f74), SHC(0x4f52505f), SHC(0x7070413d), + SHC(0x696d7265), SHC(0x4c454853), SHC(0x622f6e69), SHC(0x4d524554), SHC(0x322d6d72), SHC(0x00726f6c), + SHC(0x2f3d5249), SHC(0x646c6f66), SHC(0x6e2f3238), SHC(0x36737636), SHC(0x78663431), SHC(0x3031785f), + SHC(0x2f542f33), SHC(0x52505f4d), SHC(0x45565f4d), SHC(0x34343d4e), SHC(0x44575044), SHC(0x2f737265), + SHC(0x636f442f), SHC(0x6c2f7374), SHC(0x65747361), SHC(0x535f4d52), SHC(0x495f4e4f), SHC(0x34323939), + SHC(0x2d364133), SHC(0x4345382d), SHC(0x43344233), SHC(0x55003845), SHC(0x6d676c73), SHC(0x5455415f), + SHC(0x2f3d4b43), SHC(0x2f657461), SHC(0x2e6d6f63), SHC(0x616c2e65), SHC(0x64722e64), SHC(0x4b776b7a), + SHC(0x656e6574), SHC(0x3d485441), SHC(0x6d6f682f), SHC(0x69622f77), SHC(0x6c2f7273), SHC(0x6e69622f), + SHC(0x69622f72), SHC(0x2f3a6e69), SHC(0x6e696273), SHC(0x2f3a6e69), SHC(0x656d6f68), SHC(0x6e69622f), + SHC(0x31582f74), SHC(0x4c2f3a6e), SHC(0x412f7972), SHC(0x7273752f), SHC(0x70412f3a), SHC(0x6f697461), + SHC(0x61757369), SHC(0x6f696475), SHC(0x70612e65), SHC(0x6e65746e), SHC(0x756f7365), SHC(0x7070612f), + SHC(0x435f5f00), SHC(0x49656c64), SHC(0x65696669), SHC(0x70612e6d), SHC(0x6d726554), SHC(0x44575000), + SHC(0x2f737265), SHC(0x636f442f), SHC(0x6c2f7374), SHC(0x65747361), SHC(0x74706972), SHC(0x643d474e), + SHC(0x4654552e), SHC(0x465f4350), SHC(0x3078303d), SHC(0x40755c3d), SHC(0x00202477), SHC(0x56524553), + SHC(0x454d414e), SHC(0x4c564c48), SHC(0x3d454d4f), SHC(0x732f7372), SHC(0x4e474f4c), SHC(0x6d676c73), + SHC(0x59414c50), SHC(0x74617669), SHC(0x6f632f70), SHC(0x2e656c70), SHC(0x2e646863), SHC(0x53386438) + }; +#endif +const Word32 RotVector_960[2 * (480 - 60)] = { + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8), + SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x759af34c), SHC(0xcd790887), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x743e0918), SHC(0xca695b94), SHC(0x7387ea23), SHC(0xc8e5032b), SHC(0x72ccb9db), SHC(0xc763158e), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71474660), SHC(0xc466be4f), SHC(0x707d1443), SHC(0xc2ec7635), + SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6e010780), SHC(0xbe8df2ba), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6c40cf2c), SHC(0xbbb28501), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x697cf78a), SHC(0xb780001c), SHC(0x6887b5e2), SHC(0xb6201b3e), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x658c9a2d), SHC(0xb2141b02), + SHC(0x648543e4), SHC(0xb0c1878b), SHC(0x637984d4), SHC(0xaf726def), SHC(0x626968be), SHC(0xae26dcdf), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5cd91140), SHC(0xa7e3ff4d), SHC(0x5bafc837), SHC(0xa6aecd5e), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x581c00b3), SHC(0xa326eec0), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x53211d18), SHC(0x9eab046f), SHC(0x508d9211), SHC(0x9c867b2c), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x487fffe4), SHC(0x96830876), SHC(0x45b6bb5e), SHC(0x94a6715d), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x40000000), SHC(0x9126145f), SHC(0x3d1389cb), SHC(0x8f82ebbd), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x371afcd5), SHC(0x8c7815dd), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2ddf0040), SHC(0x88806fc4), SHC(0x2aba2ee4), SHC(0x8757860c), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x1de189a6), SHC(0x838961e8), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x17537e63), SHC(0x8224b404), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x0a0af299), SHC(0x80650347), SHC(0x06b2f1d2), SHC(0x802ce84c), SHC(0x0359c428), SHC(0x800b3a91), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2c4d9050), SHC(0x87e958a7), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x1de189a6), SHC(0x838961e8), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0f0b7727), SHC(0x80e321ff), SHC(0x0a0af299), SHC(0x80650347), + SHC(0x05067734), SHC(0x80194350), SHC(0x00000000), SHC(0x80000000), SHC(0xfaf988cc), SHC(0x80194350), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xf0f488d9), SHC(0x80e321ff), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xe21e765a), SHC(0x838961e8), SHC(0xdd417079), SHC(0x84ce444e), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xcf043ab3), SHC(0x89be50c3), + SHC(0xca695b94), SHC(0x8bc1f6e8), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xc174dbf2), SHC(0x90520d04), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xacdee2e8), SHC(0x9eab046f), SHC(0xa91d0ea3), SHC(0xa201b853), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x00000000), SHC(0x80000000), SHC(0xf94d0e2e), SHC(0x802ce84c), SHC(0xf29ecfb2), SHC(0x80b381ac), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe5632654), SHC(0x82cc0f36), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd220ffc0), SHC(0x88806fc4), SHC(0xcbf00dbe), SHC(0x8b10f144), + SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xc0000000), SHC(0x9126145f), SHC(0xba4944a2), SHC(0x94a6715d), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaf726def), SHC(0x9c867b2c), SHC(0xaa59eda4), SHC(0xa0e0a15f), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0xa0e0a15f), SHC(0xaa59eda4), SHC(0x9c867b2c), SHC(0xaf726def), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x9126145f), SHC(0xc0000000), + SHC(0x8df37f8b), SHC(0xc5e3a3a9), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x88806fc4), SHC(0xd220ffc0), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x82cc0f36), SHC(0xe5632654), + SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80b381ac), SHC(0xf29ecfb2), SHC(0x802ce84c), SHC(0xf94d0e2e), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7), + SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc763158e), SHC(0x8d334625), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb8e31319), SHC(0x9592675c), SHC(0xb2141b02), SHC(0x9a7365d3), SHC(0xab9a8e6c), SHC(0x9fc3b694), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9fc3b694), SHC(0xab9a8e6c), SHC(0x9a7365d3), SHC(0xb2141b02), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8d334625), SHC(0xc763158e), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x86cafe57), SHC(0xd6db1254), SHC(0x845c8ae3), SHC(0xdedf047d), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x811855b4), SHC(0xef4aeaf1), SHC(0x804628a7), SHC(0xf7a0dec9), + SHC(0x80000000), SHC(0x00000000), SHC(0x804628a7), SHC(0x085f2137), SHC(0x811855b4), SHC(0x10b5150f), + SHC(0x8275a0c0), SHC(0x18f8b83c), SHC(0x845c8ae3), SHC(0x2120fb83), SHC(0x86cafe57), SHC(0x2924edac), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x8d334625), SHC(0x389cea72), SHC(0x9126145f), SHC(0x40000000), + SHC(0x9592675c), SHC(0x471cece7), SHC(0x9a7365d3), SHC(0x4debe4fe), SHC(0x9fc3b694), SHC(0x54657194), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9eab046f), SHC(0xacdee2e8), SHC(0x98722192), SHC(0xb4c373ee), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8df37f8b), SHC(0xc5e3a3a9), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x838961e8), SHC(0xe21e765a), SHC(0x81936daf), SHC(0xebf9f498), + SHC(0x80650347), SHC(0xf5f50d67), SHC(0x80000000), SHC(0x00000000), SHC(0x80650347), SHC(0x0a0af299), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x838961e8), SHC(0x1de189a6), SHC(0x8643c7b3), SHC(0x278dde6e), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x8df37f8b), SHC(0x3a1c5c57), SHC(0x92dcafe5), SHC(0x42e13ba4), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0x9eab046f), SHC(0x53211d18), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xacdee2e8), SHC(0x6154fb91), SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xbd1ec45c), SHC(0x6d23501b), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xd8722192), SHC(0x79bc384d), + SHC(0xe21e765a), SHC(0x7c769e18), SHC(0xebf9f498), SHC(0x7e6c9251), SHC(0xf5f50d67), SHC(0x7f9afcb9), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x85c1e80e), SHC(0xda0aecf9), SHC(0x82cc0f36), SHC(0xe5632654), + SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0xfca63bd8), SHC(0x804628a7), SHC(0x085f2137), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x83f03dd6), SHC(0x1f81f37c), SHC(0x8757860c), SHC(0x2aba2ee4), + SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9126145f), SHC(0x40000000), SHC(0x97784a1e), SHC(0x49dfe4c2), + SHC(0x9eab046f), SHC(0x53211d18), SHC(0xa6aecd5e), SHC(0x5bafc837), SHC(0xaf726def), SHC(0x637984d4), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xc2ec7635), SHC(0x707d1443), SHC(0xcd790887), SHC(0x759af34c), + SHC(0xd8722192), SHC(0x79bc384d), SHC(0xe3c02fbb), SHC(0x7cd80464), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), + SHC(0xfaf988cc), SHC(0x7fe6bcb0), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x125df75b), SHC(0x7eace58a), + SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x2924edac), SHC(0x793501a9), SHC(0x340ff242), SHC(0x74ef0ebc), + SHC(0x3e8b240e), SHC(0x6fadf2fc), SHC(0x487fffe4), SHC(0x697cf78a), SHC(0x51d92321), SHC(0x626968be)}; +# endif + +#ifdef ENABLE_FFT_30X16 +/* Twiddle coefficients for 30x16 FFTs, generated by fft_tables.py */ +# ifdef ENABLE_HR_MODE +const Word32 RotVector_30_16[2 * (480 - 30)] = { + + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8), + SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7), + SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4), + SHC(0x00000000), SHC(0x80000000), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1), + SHC(0x80000000), SHC(0x00000000), SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d), + SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4), + SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e), + SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84), + SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2), + SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6), + SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa326eec0), SHC(0xa7e3ff4d), SHC(0x94a6715d), SHC(0xba4944a2), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x800b3a91), SHC(0xfca63bd8), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8757860c), SHC(0x2aba2ee4), SHC(0x9126145f), SHC(0x40000000), + SHC(0x9eab046f), SHC(0x53211d18), SHC(0xaf726def), SHC(0x637984d4), SHC(0xc2ec7635), SHC(0x707d1443), + SHC(0xd8722192), SHC(0x79bc384d), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x06b2f1d2), SHC(0x7fd317b4), + SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x340ff242), SHC(0x74ef0ebc), SHC(0x487fffe4), SHC(0x697cf78a), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d), + SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7)}; +# endif +#endif + +# ifdef ENABLE_HR_MODE +const Word32 RotVector_360[2 * (360 - 30)] = { +# else +const Word16 RotVector_360[2 * (360 - 30)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb0260), SHC(0xfdc41e9b), SHC(0x7fec09e3), SHC(0xfb8869ce), + SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7f834ed0), SHC(0xf4d814a4), + SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7da5f5a5), SHC(0xe7939223), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cb82885), SHC(0xe334cdc9), SHC(0x7c32a67e), SHC(0xe108b40d), + SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7a6831ba), SHC(0xda939061), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7906c0b0), SHC(0xd653c860), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76adf5e6), SHC(0xd00ce422), SHC(0x75d31a61), SHC(0xcdfc85bb), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7401e4c1), SHC(0xc9e7a512), SHC(0x730baeed), SHC(0xc7e3744b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6ff389df), SHC(0xc1f1c224), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fec09e3), SHC(0xfb8869ce), SHC(0x7fb02dc6), SHC(0xf7123849), + SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7e0e2e32), SHC(0xe9c5e582), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7c32a67e), SHC(0xe108b40d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7847d909), SHC(0xd438af17), SHC(0x76adf5e6), SHC(0xd00ce422), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x730baeed), SHC(0xc7e3744b), SHC(0x71046d3e), SHC(0xc3e85b18), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x6a1de737), SHC(0xb86c5df0), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x64dd8950), SHC(0xb1320139), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x58ea90c4), SHC(0xa3ecac65), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x4ecdfec7), SHC(0x9b2276b0), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x43d464fb), SHC(0x937328f5), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x40000000), SHC(0x9126145f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x2ff31bde), SHC(0x89520a1a), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1ef74bf3), SHC(0x83cd5982), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x04779632), SHC(0x8013f61d), SHC(0xfb8869ce), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xe108b40d), SHC(0x83cd5982), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc7e3744b), SHC(0x8cf45113), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f834ed0), SHC(0xf4d814a4), SHC(0x7e0e2e32), SHC(0xe9c5e582), + SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7847d909), SHC(0xd438af17), SHC(0x7401e4c1), SHC(0xc9e7a512), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x68d9f964), SHC(0xb6950c1e), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x496af3e2), SHC(0x9726069c), + SHC(0x40000000), SHC(0x9126145f), SHC(0x36185aee), SHC(0x8bfe1b3f), SHC(0x2bc750e9), SHC(0x87b826f7), + SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x0b27eb5c), SHC(0x807cb130), + SHC(0x00000000), SHC(0x80000000), SHC(0xf4d814a4), SHC(0x807cb130), SHC(0xe9c5e582), SHC(0x81f1d1ce), + SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xc9e7a512), SHC(0x8bfe1b3f), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb6950c1e), SHC(0x9726069c), SHC(0xadb922b7), SHC(0x9df24175), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x9726069c), SHC(0xb6950c1e), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7c32a67e), SHC(0xe108b40d), + SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x68d9f964), SHC(0xb6950c1e), + SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x53f9be05), SHC(0x9f65ad2d), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x1ccb3237), SHC(0x8347d77b), + SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xfdc41e9b), SHC(0x8004fda0), SHC(0xee2f9369), SHC(0x813ee55b), + SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc1f1c224), SHC(0x900c7621), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa8b4471a), SHC(0xa263007d), SHC(0x9df24175), SHC(0xadb922b7), + SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8cf45113), SHC(0xc7e3744b), SHC(0x86f93f50), SHC(0xd653c860), + SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x807cb130), SHC(0xf4d814a4), SHC(0x8013f61d), SHC(0x04779632), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x84f56073), SHC(0x234815ba), SHC(0x8a2ce59f), SHC(0x32037a45), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb1320139), SHC(0x9b2276b0), SHC(0xa3ecac65), SHC(0xa7156f3c), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8efb92c2), SHC(0xc3e85b18), SHC(0x87b826f7), SHC(0xd438af17), + SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x804fd23a), SHC(0x08edc7b7), + SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x8efb92c2), SHC(0x3c17a4e8), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa3ecac65), SHC(0x58ea90c4), SHC(0xb1320139), SHC(0x64dd8950), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5246dd49), SHC(0x9df24175), + SHC(0x40000000), SHC(0x9126145f), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0x00000000), SHC(0x80000000), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xd438af17), SHC(0x87b826f7), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xadb922b7), SHC(0x9df24175), SHC(0x9df24175), SHC(0xadb922b7), + SHC(0x9126145f), SHC(0xc0000000), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x81f1d1ce), SHC(0xe9c5e582), + SHC(0x80000000), SHC(0x00000000), SHC(0x81f1d1ce), SHC(0x163a1a7e), SHC(0x87b826f7), SHC(0x2bc750e9), + SHC(0x9126145f), SHC(0x40000000), SHC(0x9df24175), SHC(0x5246dd49), SHC(0xadb922b7), SHC(0x620dbe8b), + SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xd438af17), SHC(0x7847d909), SHC(0xe9c5e582), SHC(0x7e0e2e32), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x163a1a7e), SHC(0x7e0e2e32), SHC(0x2bc750e9), SHC(0x7847d909), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7da5f5a5), SHC(0xe7939223), SHC(0x76adf5e6), SHC(0xd00ce422), + SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x496af3e2), SHC(0x9726069c), + SHC(0x340ff242), SHC(0x8b10f144), SHC(0x1ccb3237), SHC(0x8347d77b), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xbe133b7c), SHC(0x92485786), + SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x99c64fc5), SHC(0xb2f7b9af), SHC(0x8cf45113), SHC(0xc7e3744b), + SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x80f43f69), SHC(0x0f996a26), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x900c7621), SHC(0x3e0e3ddc), SHC(0x9df24175), SHC(0x5246dd49), + SHC(0xaf726def), SHC(0x637984d4), SHC(0xc3e85b18), SHC(0x71046d3e), SHC(0xda939061), SHC(0x7a6831ba), + SHC(0xf29ecfb2), SHC(0x7f4c7e54), SHC(0x0b27eb5c), SHC(0x7f834ed0), SHC(0x234815ba), SHC(0x7b0a9f8d), + SHC(0x3a1c5c57), SHC(0x720c8075), SHC(0x4ecdfec7), SHC(0x64dd8950), SHC(0x609a52d3), SHC(0x53f9be05)}; + +# ifdef ENABLE_HR_MODE +const Word32 RotVector_320[2 * (320 - 20)] = { +# else +const Word16 RotVector_320[2 * (320 - 20)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x720c8075), SHC(0xc5e3a3a9), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x6154fb91), SHC(0xacdee2e8), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), SHC(0x14060b68), SHC(0x81936daf), + SHC(0x0a0af299), SHC(0x80650347), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), + SHC(0xca695b94), SHC(0x8bc1f6e8), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), SHC(0xe70747c4), SHC(0x8275a0c0), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x8275a0c0), SHC(0xe70747c4), + SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), SHC(0x89be50c3), SHC(0x30fbc54d), + SHC(0x9592675c), SHC(0x471cece7), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x14060b68), SHC(0x81936daf), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x98722192), SHC(0x4b3c8c12), + SHC(0xacdee2e8), SHC(0x6154fb91), SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xe21e765a), SHC(0x7c769e18), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x80e321ff), SHC(0xf0f488d9), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9eab046f), SHC(0x53211d18), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xfaf988cc), SHC(0x7fe6bcb0), + SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x3e8b240e), SHC(0x6fadf2fc), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7ff9af04), SHC(0xfd7ca4a6), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fc72ae2), SHC(0xf876ebe8), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f1cde01), SHC(0xf0f488d9), + SHC(0x7ecaf9e5), SHC(0xee76612d), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e01b096), SHC(0xe97f81eb), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d06aa16), SHC(0xe4918486), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7bda497d), SHC(0xdfae5b23), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78ef678f), SHC(0xd61036db), SHC(0x7816a759), SHC(0xd3b26fb0), + SHC(0x77320d0d), SHC(0xd15907d9), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fc72ae2), SHC(0xf876ebe8), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e01b096), SHC(0xe97f81eb), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7545a5a0), SHC(0xccb44322), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6e6e1492), SHC(0xbf469e83), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x660e9a6a), SHC(0xb2beadcc), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5c44ee40), SHC(0xa748e9ce), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x45027c0c), SHC(0x943239c7), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x37dc420c), SHC(0x8cd50c59), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000), SHC(0xf3742ca2), SHC(0x809dc971), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7ecaf9e5), SHC(0xee76612d), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7545a5a0), SHC(0xccb44322), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x56e2f15d), SHC(0xa201b853), + SHC(0x4930590f), SHC(0x96fd15e3), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x29efc925), SHC(0x87109871), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x07891418), SHC(0x8038d51e), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xe4918486), SHC(0x82f955ea), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc3a94590), SHC(0x8f1d343a), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa748e9ce), SHC(0xa3bb11c0), SHC(0x9b7abc1c), SHC(0xb0c1878b), + SHC(0x9191eb6e), SHC(0xbf469e83), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e01b096), SHC(0xe97f81eb), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x6e6e1492), SHC(0xbf469e83), SHC(0x6154fb91), SHC(0xacdee2e8), + SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x29efc925), SHC(0x87109871), + SHC(0x14060b68), SHC(0x81936daf), SHC(0xfd7ca4a6), SHC(0x800650fc), SHC(0xe70747c4), SHC(0x8275a0c0), + SHC(0xd15907d9), SHC(0x88cdf2f3), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xaaf9c6af), SHC(0xa051a5ab), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x8643c7b3), SHC(0xd8722192), + SHC(0x8135061b), SHC(0xee76612d), SHC(0x80194350), SHC(0x05067734), SHC(0x82f955ea), SHC(0x1b6e7b7a), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d06aa16), SHC(0xe4918486), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x660e9a6a), SHC(0xb2beadcc), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x07891418), SHC(0x8038d51e), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd15907d9), SHC(0x88cdf2f3), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xa3bb11c0), SHC(0xa748e9ce), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x87109871), SHC(0xd61036db), SHC(0x80e321ff), SHC(0xf0f488d9), + SHC(0x809dc971), SHC(0x0c8bd35e), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x9191eb6e), SHC(0x40b9617d), + SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xb6cfa6f1), SHC(0x6902ea1d), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7bda497d), SHC(0xdfae5b23), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x5c44ee40), SHC(0xa748e9ce), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x05067734), SHC(0x80194350), + SHC(0xe4918486), SHC(0x82f955ea), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xaaf9c6af), SHC(0xa051a5ab), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x87109871), SHC(0xd61036db), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x81fe4f6a), SHC(0x16807e15), SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9d0dfe54), SHC(0x5133cc94), + SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xd15907d9), SHC(0x77320d0d), SHC(0xf0f488d9), SHC(0x7f1cde01), + SHC(0x11899ed3), SHC(0x7ecaf9e5), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xc3a94590), SHC(0x8f1d343a), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x8275a0c0), SHC(0xe70747c4), + SHC(0x809dc971), SHC(0x0c8bd35e), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9d0dfe54), SHC(0x5133cc94), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0x00000000), SHC(0x7fffffff), + SHC(0x25280c5e), SHC(0x7a7d055b), SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x62f201ac), SHC(0x5133cc94)}; + + +/* Twiddle coefficients for 32x8 FFTs, generated by fft_tables.py */ +# ifdef ENABLE_HR_MODE +const Word32 RotVector_32_8[2 * (256 - 32)] = { +# else +const Word16 RotVector_32_8[2 * (256 - 32)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff62182), SHC(0xfcdbd541), SHC(0x7fd8878e), SHC(0xf9b82684), + SHC(0x7fa736b4), SHC(0xf6956fb7), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f0991c4), SHC(0xf054d8d5), + SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7e1d93ea), SHC(0xea1debbb), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7ce3ceb2), SHC(0xe3f47d96), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7b5d039e), SHC(0xdddc5b3b), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x798a23b1), SHC(0xd7d946d8), SHC(0x78848414), SHC(0xd4e0cb15), + SHC(0x776c4edb), SHC(0xd1eef59e), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x7504d345), SHC(0xcc210d79), + SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x72552c85), SHC(0xc67322ce), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6f5f02b2), SHC(0xc0e8b648), SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6c242960), SHC(0xbb8532b0), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x68a69e81), SHC(0xb64beacd), SHC(0x66cf8120), SHC(0xb3c0200c), + SHC(0x64e88926), SHC(0xb140175b), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x60ec3830), SHC(0xac64d510), + SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5cb420e0), SHC(0xa7bd22ac), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7fd8878e), SHC(0xf9b82684), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7e9d55fc), SHC(0xed37ef91), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x73b5ebd1), SHC(0xc945dfec), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x66cf8120), SHC(0xb3c0200c), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55f5a4d2), SHC(0xa1288376), SHC(0x5133cc94), SHC(0x9d0dfe54), + SHC(0x4c3fdff4), SHC(0x99307ee0), SHC(0x471cece7), SHC(0x9592675c), SHC(0x41ce1e65), SHC(0x9235f2ec), + SHC(0x3c56ba70), SHC(0x8f1d343a), SHC(0x36ba2014), SHC(0x8c4a142f), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x2b1f34eb), SHC(0x877b7bec), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x1f19f97b), SHC(0x83d60412), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x12c8106f), SHC(0x8162aa04), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0x0647d97c), SHC(0x80277872), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fa736b4), SHC(0xf6956fb7), + SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7ce3ceb2), SHC(0xe3f47d96), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x776c4edb), SHC(0xd1eef59e), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6f5f02b2), SHC(0xc0e8b648), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x64e88926), SHC(0xb140175b), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), + SHC(0x5842dd54), SHC(0xa34bdf20), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x49b41533), SHC(0x9759617f), + SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x398cdd32), SHC(0x8daad37b), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x2826b928), SHC(0x8675dc4f), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x15e21445), SHC(0x81e26c16), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x03242abf), SHC(0x8009de7e), SHC(0xf9b82684), SHC(0x80277872), + SHC(0xf054d8d5), SHC(0x80f66e3c), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdddc5b3b), SHC(0x84a2fc62), + SHC(0xd4e0cb15), SHC(0x877b7bec), SHC(0xcc210d79), SHC(0x8afb2cbb), SHC(0xc3a94590), SHC(0x8f1d343a), + SHC(0xbb8532b0), SHC(0x93dbd6a0), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xac64d510), SHC(0x9f13c7d0), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000), SHC(0xf3742ca2), SHC(0x809dc971), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5), SHC(0xcf043ab3), SHC(0x89be50c3), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaecc336c), SHC(0x9d0dfe54), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x9592675c), SHC(0xb8e31319), + SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x8582faa5), SHC(0xdad7f3a2), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x809dc971), SHC(0xf3742ca2), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7f0991c4), SHC(0xf054d8d5), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x776c4edb), SHC(0xd1eef59e), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x68a69e81), SHC(0xb64beacd), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), + SHC(0x539b2af0), SHC(0x9f13c7d0), SHC(0x471cece7), SHC(0x9592675c), SHC(0x398cdd32), SHC(0x8daad37b), + SHC(0x2b1f34eb), SHC(0x877b7bec), SHC(0x1c0b826a), SHC(0x831c314e), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0xfcdbd541), SHC(0x8009de7e), SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xdddc5b3b), SHC(0x84a2fc62), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0e8b648), SHC(0x90a0fd4e), SHC(0xb3c0200c), SHC(0x99307ee0), + SHC(0xa7bd22ac), SHC(0xa34bdf20), SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x93dbd6a0), SHC(0xbb8532b0), + SHC(0x8c4a142f), SHC(0xc945dfec), SHC(0x8675dc4f), SHC(0xd7d946d8), SHC(0x8275a0c0), SHC(0xe70747c4), + SHC(0x8058c94c), SHC(0xf6956fb7), SHC(0x80277872), SHC(0x0647d97c), SHC(0x81e26c16), SHC(0x15e21445), + SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8afb2cbb), SHC(0x33def287), SHC(0x9235f2ec), SHC(0x41ce1e65), + SHC(0x9b1776da), SHC(0x4ebfe8a5), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e9d55fc), SHC(0xed37ef91), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x41ce1e65), SHC(0x9235f2ec), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0xf9b82684), SHC(0x80277872), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd4e0cb15), SHC(0x877b7bec), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x99307ee0), SHC(0xb3c0200c), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x877b7bec), SHC(0xd4e0cb15), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80277872), SHC(0xf9b82684), SHC(0x809dc971), SHC(0x0c8bd35e), + SHC(0x83d60412), SHC(0x1f19f97b), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9235f2ec), SHC(0x41ce1e65), + SHC(0x9d0dfe54), SHC(0x5133cc94), SHC(0xaa0a5b2e), SHC(0x5ed77c8a), SHC(0xb8e31319), SHC(0x6a6d98a4), + SHC(0xc945dfec), SHC(0x73b5ebd1), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xed37ef91), SHC(0x7e9d55fc), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e1d93ea), SHC(0xea1debbb), SHC(0x78848414), SHC(0xd4e0cb15), + SHC(0x6f5f02b2), SHC(0xc0e8b648), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x539b2af0), SHC(0x9f13c7d0), + SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x2e110a62), SHC(0x8893b125), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x03242abf), SHC(0x8009de7e), SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xd7d946d8), SHC(0x8675dc4f), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb140175b), SHC(0x9b1776da), SHC(0xa1288376), SHC(0xaa0a5b2e), + SHC(0x93dbd6a0), SHC(0xbb8532b0), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x831c314e), SHC(0xe3f47d96), + SHC(0x80277872), SHC(0xf9b82684), SHC(0x80f66e3c), SHC(0x0fab272b), SHC(0x8582faa5), SHC(0x25280c5e), + SHC(0x8daad37b), SHC(0x398cdd32), SHC(0x99307ee0), SHC(0x4c3fdff4), SHC(0xa7bd22ac), SHC(0x5cb420e0), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcc210d79), SHC(0x7504d345), SHC(0xe0e60685), SHC(0x7c29fbee), + SHC(0xf6956fb7), SHC(0x7fa736b4), SHC(0x0c8bd35e), SHC(0x7f62368f), SHC(0x2223a4c5), SHC(0x7b5d039e), + SHC(0x36ba2014), SHC(0x73b5ebd1), SHC(0x49b41533), SHC(0x68a69e81)}; + + +# ifdef ENABLE_HR_MODE +const Word32 RotVector_15_6[2 * (90 - 15)] = { +# else +const Word16 RotVector_15_6[2 * (90 - 15)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x40000000), SHC(0x9126145f), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xf29ecfb2), SHC(0x80b381ac), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xaa59eda4), SHC(0xa0e0a15f), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x82cc0f36), SHC(0xe5632654), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x6c8cd70b), SHC(0xbc2b9b05), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xb1320139), SHC(0x9b2276b0), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x804fd23a), SHC(0xf7123849), + SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x8efb92c2), SHC(0x3c17a4e8), SHC(0xa3ecac65), SHC(0x58ea90c4), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7847d909), SHC(0xd438af17), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x40000000), SHC(0x9126145f), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0xe9c5e582), SHC(0x81f1d1ce), + SHC(0xc0000000), SHC(0x9126145f), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x87b826f7), SHC(0xd438af17), + SHC(0x80000000), SHC(0x00000000), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x9df24175), SHC(0x5246dd49), + SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xe9c5e582), SHC(0x7e0e2e32), SHC(0x163a1a7e), SHC(0x7e0e2e32)}; + +#if defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB) +/* Twiddle coefficients for 32x12 FFTs, generated by fft_tables.py */ +# ifdef ENABLE_HR_MODE +const Word32 RotVector_32_12[2 * (384 - 32)] = { +# else +const Word16 RotVector_32_12[2 * (384 - 32)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb9d15), SHC(0xfde7dbd9), SHC(0x7fee74a2), SHC(0xfbcfdc71), + SHC(0x7fd8878e), SHC(0xf9b82684), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7f92661d), SHC(0xf58a29f2), + SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f294bfd), SHC(0xf15f0b74), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7deeaa7a), SHC(0xe915f9ba), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d1d7958), SHC(0xe4fa4bf1), SHC(0x7ca80038), SHC(0xe2ef2a3e), + SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b1474fd), SHC(0xdcda47b9), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x79dd3098), SHC(0xd8d82b7a), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x770acdec), SHC(0xd0f53ce0), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x757075ac), SHC(0xcd1693f7), SHC(0x74972f92), SHC(0xcb2c6a82), + SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x71dba9ab), SHC(0xc5842c7e), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6fe2313c), SHC(0xc1d2814f), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7fee74a2), SHC(0xfbcfdc71), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7f62368f), SHC(0xf3742ca2), + SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7ca80038), SHC(0xe2ef2a3e), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x793501a9), SHC(0xd6db1254), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x74972f92), SHC(0xcb2c6a82), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6cb2a837), SHC(0xbc6845ce), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x680b5c33), SHC(0xb5715eef), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x62f201ac), SHC(0xaecc336c), + SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x5d6c2f99), SHC(0xa8800c26), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x577ff3da), SHC(0xa293d067), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x5133cc94), SHC(0x9d0dfe54), + SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x4a8ea111), SHC(0x97f4a3cd), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x4397ba32), SHC(0x934d57c9), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd8878e), SHC(0xf9b82684), + SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x78848414), SHC(0xd4e0cb15), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x66cf8120), SHC(0xb3c0200c), + SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x55f5a4d2), SHC(0xa1288376), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x4c3fdff4), SHC(0x99307ee0), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x36ba2014), SHC(0x8c4a142f), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2b1f34eb), SHC(0x877b7bec), + SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x12c8106f), SHC(0x8162aa04), SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x0647d97c), SHC(0x80277872), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7), + SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc763158e), SHC(0x8d334625), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7f92661d), SHC(0xf58a29f2), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7c29fbee), SHC(0xe0e60685), + SHC(0x793501a9), SHC(0xd6db1254), SHC(0x757075ac), SHC(0xcd1693f7), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6b93d02e), SHC(0xbaa34bf4), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), + SHC(0x577ff3da), SHC(0xa293d067), SHC(0x4f9292dc), SHC(0x9bbd4282), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x3e2d7eb1), SHC(0x901dcec4), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2b1f34eb), SHC(0x877b7bec), + SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x16ea0646), SHC(0x82115586), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0x02182427), SHC(0x800462eb), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xed37ef91), SHC(0x8162aa04), + SHC(0xe2ef2a3e), SHC(0x8357ffc8), SHC(0xd8d82b7a), SHC(0x8622cf68), SHC(0xcf043ab3), SHC(0x89be50c3), + SHC(0xc5842c7e), SHC(0x8e245655), SHC(0xbc6845ce), SHC(0x934d57c9), SHC(0xb3c0200c), SHC(0x99307ee0), + SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa405847e), SHC(0xa6fbbc59), SHC(0x9d0dfe54), SHC(0xaecc336c), + SHC(0x96bfea3d), SHC(0xb727b9f7), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x3c56ba70), SHC(0x8f1d343a), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000), + SHC(0xf3742ca2), SHC(0x809dc971), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xaecc336c), SHC(0x9d0dfe54), SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9d0dfe54), SHC(0xaecc336c), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8582faa5), SHC(0xdad7f3a2), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x809dc971), SHC(0xf3742ca2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f294bfd), SHC(0xf15f0b74), SHC(0x7ca80038), SHC(0xe2ef2a3e), + SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6b93d02e), SHC(0xbaa34bf4), + SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x590443a7), SHC(0xa405847e), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2727d486), SHC(0x8622cf68), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0a75d60e), SHC(0x806d99e3), SHC(0xfbcfdc71), SHC(0x80118b5e), + SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd0f53ce0), SHC(0x88f53214), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb727b9f7), SHC(0x96bfea3d), SHC(0xab9a8e6c), SHC(0x9fc3b694), + SHC(0xa1288376), SHC(0xaa0a5b2e), SHC(0x97f4a3cd), SHC(0xb5715eef), SHC(0x901dcec4), SHC(0xc1d2814f), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x84eb8b03), SHC(0xdcda47b9), SHC(0x81b5abda), SHC(0xeb263dbb), + SHC(0x80277872), SHC(0xf9b82684), SHC(0x804628a7), SHC(0x085f2137), SHC(0x82115586), SHC(0x16ea0646), + SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8a8f8a54), SHC(0x32e96c09), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x00000000), SHC(0x80000000), + SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xcf043ab3), SHC(0x89be50c3), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1), SHC(0x80000000), SHC(0x00000000), + SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83), SHC(0x89be50c3), SHC(0x30fbc54d), + SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xb2141b02), SHC(0x658c9a2d), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e9d55fc), SHC(0xed37ef91), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x41ce1e65), SHC(0x9235f2ec), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0xf9b82684), SHC(0x80277872), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd4e0cb15), SHC(0x877b7bec), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x99307ee0), SHC(0xb3c0200c), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x877b7bec), SHC(0xd4e0cb15), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80277872), SHC(0xf9b82684), SHC(0x809dc971), SHC(0x0c8bd35e), + SHC(0x83d60412), SHC(0x1f19f97b), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9235f2ec), SHC(0x41ce1e65), + SHC(0x9d0dfe54), SHC(0x5133cc94), SHC(0xaa0a5b2e), SHC(0x5ed77c8a), SHC(0xb8e31319), SHC(0x6a6d98a4), + SHC(0xc945dfec), SHC(0x73b5ebd1), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xed37ef91), SHC(0x7e9d55fc), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x577ff3da), SHC(0xa293d067), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xe2ef2a3e), SHC(0x8357ffc8), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xbc6845ce), SHC(0x934d57c9), SHC(0xab9a8e6c), SHC(0x9fc3b694), + SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x9126145f), SHC(0xc0000000), SHC(0x88343c0e), SHC(0xd2e9786e), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80118b5e), SHC(0xfbcfdc71), SHC(0x811855b4), SHC(0x10b5150f), + SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x97f4a3cd), SHC(0x4a8ea111), + SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb5715eef), SHC(0x680b5c33), SHC(0xc763158e), SHC(0x72ccb9db), + SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x0430238f), SHC(0x7fee74a2), + SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x2d168792), SHC(0x77cbc3f2), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7deeaa7a), SHC(0xe915f9ba), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x6dca0d14), SHC(0xbe31e19b), + SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x4f9292dc), SHC(0x9bbd4282), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x2727d486), SHC(0x8622cf68), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xf9b82684), SHC(0x80277872), + SHC(0xe2ef2a3e), SHC(0x8357ffc8), SHC(0xcd1693f7), SHC(0x8a8f8a54), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xa6fbbc59), SHC(0xa405847e), SHC(0x97f4a3cd), SHC(0xb5715eef), SHC(0x8c4a142f), SHC(0xc945dfec), + SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x806d99e3), SHC(0xf58a29f2), SHC(0x809dc971), SHC(0x0c8bd35e), + SHC(0x84eb8b03), SHC(0x2325b847), SHC(0x8d334625), SHC(0x389cea72), SHC(0x99307ee0), SHC(0x4c3fdff4), + SHC(0xa8800c26), SHC(0x5d6c2f99), SHC(0xbaa34bf4), SHC(0x6b93d02e), SHC(0xcf043ab3), SHC(0x7641af3d), + SHC(0xe4fa4bf1), SHC(0x7d1d7958), SHC(0xfbcfdc71), SHC(0x7fee74a2), SHC(0x12c8106f), SHC(0x7e9d55fc), + SHC(0x2924edac), SHC(0x793501a9), SHC(0x3e2d7eb1), SHC(0x6fe2313c), SHC(0x5133cc94), SHC(0x62f201ac), + SHC(0x619a7dce), SHC(0x52cf758f)}; + + +# endif /* !defined(__XTENSA__) */ + + +/* Inverse square root table for operands running from 0.5 to ~1.0 + + (Word32) (0.5 + 1.0/sqrt((op)/CDKpow(2.0,31))) + + Note: First value is not rounded for accuracy reasons + + Implicit exponent is 1 + + Example: 0x5A82799A = Isqrt(0x40000000), exponent=1 +*/ +const Word32 isqrt_table[128 + 2] = { + 0x5A827999, 0x5A287E03, 0x59CF8CBC, 0x5977A0AC, 0x5920B4DF, 0x58CAC480, 0x5875CADE, 0x5821C364, 0x57CEA99D, + 0x577C7930, 0x572B2DE0, 0x56DAC38E, 0x568B3632, 0x563C81E0, 0x55EEA2C4, 0x55A19522, 0x55555555, 0x5509DFD0, + 0x54BF311A, 0x547545D0, 0x542C1AA4, 0x53E3AC5B, 0x539BF7CD, 0x5354F9E7, 0x530EAFA5, 0x52C91618, 0x52842A5F, + 0x523FE9AC, 0x51FC5140, 0x51B95E6B, 0x51770E8F, 0x51355F1A, 0x50F44D89, 0x50B3D768, 0x5073FA50, 0x5034B3E7, + 0x4FF601E0, 0x4FB7E1FA, 0x4F7A5202, 0x4F3D4FCF, 0x4F00D944, 0x4EC4EC4F, 0x4E8986EA, 0x4E4EA718, 0x4E144AE9, + 0x4DDA7073, 0x4DA115DA, 0x4D683948, 0x4D2FD8F4, 0x4CF7F31B, 0x4CC08605, 0x4C899000, 0x4C530F65, 0x4C1D0294, + 0x4BE767F5, 0x4BB23DF9, 0x4B7D8317, 0x4B4935CF, 0x4B1554A6, 0x4AE1DE2A, 0x4AAED0F0, 0x4A7C2B93, 0x4A49ECB3, + 0x4A1812FA, 0x49E69D16, 0x49B589BB, 0x4984D7A4, 0x49548592, 0x49249249, 0x48F4FC97, 0x48C5C34B, 0x4896E53D, + 0x48686148, 0x483A364D, 0x480C6332, 0x47DEE6E1, 0x47B1C049, 0x4784EE60, 0x4758701C, 0x472C447C, 0x47006A81, + 0x46D4E130, 0x46A9A794, 0x467EBCBA, 0x46541FB4, 0x4629CF98, 0x45FFCB80, 0x45D6128A, 0x45ACA3D5, 0x45837E88, + 0x455AA1CB, 0x45320CC8, 0x4509BEB0, 0x44E1B6B4, 0x44B9F40B, 0x449275ED, 0x446B3B96, 0x44444444, 0x441D8F3B, + 0x43F71BBF, 0x43D0E917, 0x43AAF68F, 0x43854374, 0x435FCF15, 0x433A98C6, 0x43159FDC, 0x42F0E3AE, 0x42CC6398, + 0x42A81EF6, 0x42841527, 0x4260458E, 0x423CAF8D, 0x4219528B, 0x41F62DF2, 0x41D3412A, 0x41B08BA2, 0x418E0CC8, + 0x416BC40D, 0x4149B0E5, 0x4127D2C3, 0x41062920, 0x40E4B374, 0x40C3713B, 0x40A261EF, 0x40818512, 0x4060DA22, + 0x404060A1, 0x40201814, 0x40000000, 0x3FE017EC, +}; + +const Word32 Log2_16_table1[16] = { + 0, 2934766, 5701737, 8319067, 10802114, 13163988, 15415967, 17567824, + 19628084, 21604229, 23502857, 25329821, 27090336, 28789065, 30430199, 32017515, +}; + +const Word16 Log2_16_table2[16] = { + 1433, 1351, 1278, 1212, 1153, 1099, 1051, 1006, 965, 927, 892, 860, 829, 801, 775, 750, +}; + +const Word32 InvLog2_16_table1[64] = { + 1073741824, 1085434106, 1097253708, 1109202018, 1121280436, 1133490379, 1145833280, 1158310587, + 1170923762, 1183674286, 1196563654, 1209593378, 1222764986, 1236080024, 1249540052, 1263146652, + 1276901417, 1290805962, 1304861917, 1319070932, 1333434672, 1347954824, 1362633090, 1377471191, + 1392470869, 1407633882, 1422962010, 1438457051, 1454120821, 1469955159, 1485961921, 1502142985, + 1518500250, 1535035634, 1551751076, 1568648537, 1585730000, 1602997467, 1620452965, 1638098541, + 1655936265, 1673968228, 1692196547, 1710623359, 1729250827, 1748081133, 1767116489, 1786359126, + 1805811301, 1825475297, 1845353420, 1865448001, 1885761398, 1906295993, 1927054196, 1948038440, + 1969251188, 1990694927, 2012372174, 2034285470, 2056437387, 2078830522, 2101467502, 2124350982, +}; + +const Word16 InvLog2_16_table2[64] = { + 11418, 11543, 11668, 11795, 11924, 12054, 12185, 12318, 12452, 12587, 12724, 12863, 13003, 13145, 13288, 13432, + 13579, 13727, 13876, 14027, 14180, 14334, 14490, 14648, 14808, 14969, 15132, 15297, 15463, 15632, 15802, 15974, + 16148, 16324, 16501, 16681, 16863, 17046, 17232, 17420, 17609, 17801, 17995, 18191, 18389, 18589, 18792, 18996, + 19203, 19412, 19624, 19837, 20053, 20272, 20492, 20716, 20941, 21169, 21400, 21633, 21868, 22106, 22347, 22590, +}; + +const UWord8 gf16_mult_table[256] = { + /* gf16_mult_table[a | (b << 4)] contains the product of a and b in GF(16) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 2, 4, 6, 8, 10, 12, 14, 3, 1, 7, 5, 11, 9, 15, 13, 0, 3, 6, 5, 12, 15, 10, 9, 11, 8, + 13, 14, 7, 4, 1, 2, 0, 4, 8, 12, 3, 7, 11, 15, 6, 2, 14, 10, 5, 1, 13, 9, 0, 5, 10, 15, 7, 2, 13, + 8, 14, 11, 4, 1, 9, 12, 3, 6, 0, 6, 12, 10, 11, 13, 7, 1, 5, 3, 9, 15, 14, 8, 2, 4, 0, 7, 14, 9, + 15, 8, 1, 6, 13, 10, 3, 4, 2, 5, 12, 11, 0, 8, 3, 11, 6, 14, 5, 13, 12, 4, 15, 7, 10, 2, 9, 1, 0, + 9, 1, 8, 2, 11, 3, 10, 4, 13, 5, 12, 6, 15, 7, 14, 0, 10, 7, 13, 14, 4, 9, 3, 15, 5, 8, 2, 1, 11, + 6, 12, 0, 11, 5, 14, 10, 1, 15, 4, 7, 12, 2, 9, 13, 6, 8, 3, 0, 12, 11, 7, 5, 9, 14, 2, 10, 6, 1, + 13, 15, 3, 4, 8, 0, 13, 9, 4, 1, 12, 8, 5, 2, 15, 11, 6, 3, 14, 10, 7, 0, 14, 15, 1, 13, 3, 2, 12, + 9, 7, 6, 8, 4, 10, 11, 5, 0, 15, 13, 2, 9, 6, 4, 11, 1, 14, 12, 3, 8, 7, 5, 10, +}; + +const UWord8 rs16_elp_deg2_table[256] = { + /* If the polynomial x^2 + ax + b has distinct non-zero roots z1 and z2 in GF(16), * + * then table entry a + 16*b contains log_g(z1) | log_g(z2) << 4, and otherwise it * + * contains 0. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, + 105, 195, 0, 210, 0, 225, 0, 180, 120, 0, 0, 121, 0, 16, 0, 211, 0, 0, 181, 0, 0, 106, + 196, 226, 0, 0, 0, 214, 64, 0, 199, 0, 0, 0, 0, 0, 49, 184, 0, 154, 0, 229, 0, 227, + 182, 0, 0, 32, 0, 0, 0, 197, 0, 0, 122, 0, 212, 152, 0, 203, 0, 158, 128, 0, 0, 0, + 98, 113, 218, 0, 0, 0, 53, 0, 0, 65, 0, 0, 185, 110, 215, 80, 0, 0, 200, 0, 50, 0, + 0, 0, 0, 130, 205, 115, 0, 0, 160, 190, 145, 0, 0, 0, 0, 0, 0, 100, 0, 0, 168, 198, + 0, 183, 33, 0, 0, 48, 228, 213, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 179, 0, 224, 104, + 0, 194, 149, 0, 0, 209, 0, 0, 0, 189, 99, 84, 0, 129, 0, 0, 0, 144, 0, 0, 234, 114, + 0, 0, 82, 0, 0, 0, 0, 217, 202, 0, 112, 52, 232, 0, 97, 0, 0, 0, 126, 0, 81, 201, + 0, 36, 216, 186, 0, 0, 0, 96, 0, 0, 0, 0, 0, 88, 0, 0, 0, 103, 0, 148, 178, 0, + 208, 193, 0, 58, 0, 0, 0, 0, 0, 161, 206, 0, 116, 0, 101, 0, 0, 56, 146, 176, 0, 0, + 147, 162, 222, 0, 132, 0, 0, 0, 0, 0, 177, 117, 192, 0, +}; + +const UWord16 rs16_elp_deg3_table[256] = { + /* If the polynomial x^3 + ax + b has distinct roots z1, z2 and z3 in GF(16), * + * then table entry a + 16*b contains z1) | z2 << 4 | z3 << 8, and otherwise it * + * contains 0. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1889, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2977, 0, 0, 0, 0, 0, 3990, 1859, 0, + 0, 0, 0, 0, 0, 0, 3521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1874, 0, 3718, 0, 0, 0, + 0, 0, 0, 2433, 0, 0, 1619, 0, 0, 0, 0, 3495, 0, 0, 0, 0, 0, 0, 4065, 0, 0, 0, + 0, 0, 0, 3255, 0, 0, 0, 1602, 0, 3735, 0, 0, 0, 0, 3238, 801, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3510, 0, 0, 0, 0, 1345, 3975, 0, 0, 0, 0, 0, 0, 0, 0, 3778, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2947, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3476, 0, 4005, 0, 3461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3748, 0, 0, 2962, 0, 0, 0, 0, 4035, 0, 0, 4020, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3221, 0, 0, 0, 0, 0, 0, 2690, + 0, 0, 0, 3795, 0, 0, 0, 4050, 0, 0, 0, 0, 0, 3204, 3765, 0, 0, 0, 0, 0, 2707, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +#ifdef ENABLE_HR_MODE +const Word32 invSqrtTab[(128 + 2)] = { + 0x5A827999, 0x5A287E03, 0x59CF8CBC, 0x5977A0AC, 0x5920B4DF, 0x58CAC480, 0x5875CADE, 0x5821C364, 0x57CEA99D, + 0x577C7930, 0x572B2DE0, 0x56DAC38E, 0x568B3632, 0x563C81E0, 0x55EEA2C4, 0x55A19522, 0x55555555, 0x5509DFD0, + 0x54BF311A, 0x547545D0, 0x542C1AA4, 0x53E3AC5B, 0x539BF7CD, 0x5354F9E7, 0x530EAFA5, 0x52C91618, 0x52842A5F, + 0x523FE9AC, 0x51FC5140, 0x51B95E6B, 0x51770E8F, 0x51355F1A, 0x50F44D89, 0x50B3D768, 0x5073FA50, 0x5034B3E7, + 0x4FF601E0, 0x4FB7E1FA, 0x4F7A5202, 0x4F3D4FCF, 0x4F00D944, 0x4EC4EC4F, 0x4E8986EA, 0x4E4EA718, 0x4E144AE9, + 0x4DDA7073, 0x4DA115DA, 0x4D683948, 0x4D2FD8F4, 0x4CF7F31B, 0x4CC08605, 0x4C899000, 0x4C530F65, 0x4C1D0294, + 0x4BE767F5, 0x4BB23DF9, 0x4B7D8317, 0x4B4935CF, 0x4B1554A6, 0x4AE1DE2A, 0x4AAED0F0, 0x4A7C2B93, 0x4A49ECB3, + 0x4A1812FA, 0x49E69D16, 0x49B589BB, 0x4984D7A4, 0x49548592, 0x49249249, 0x48F4FC97, 0x48C5C34B, 0x4896E53D, + 0x48686148, 0x483A364D, 0x480C6332, 0x47DEE6E1, 0x47B1C049, 0x4784EE60, 0x4758701C, 0x472C447C, 0x47006A81, + 0x46D4E130, 0x46A9A794, 0x467EBCBA, 0x46541FB4, 0x4629CF98, 0x45FFCB80, 0x45D6128A, 0x45ACA3D5, 0x45837E88, + 0x455AA1CB, 0x45320CC8, 0x4509BEB0, 0x44E1B6B4, 0x44B9F40B, 0x449275ED, 0x446B3B96, 0x44444444, 0x441D8F3B, + 0x43F71BBF, 0x43D0E917, 0x43AAF68F, 0x43854374, 0x435FCF15, 0x433A98C6, 0x43159FDC, 0x42F0E3AE, 0x42CC6398, + 0x42A81EF6, 0x42841527, 0x4260458E, 0x423CAF8D, 0x4219528B, 0x41F62DF2, 0x41D3412A, 0x41B08BA2, 0x418E0CC8, + 0x416BC40D, 0x4149B0E5, 0x4127D2C3, 0x41062920, 0x40E4B374, 0x40C3713B, 0x40A261EF, 0x40818512, 0x4060DA22, + 0x404060A1, 0x40201814, 0x40000000, 0x3FE017EC /* , 0x3FC05F61 */ +}; +#endif diff --git a/lib_lc3plus/rom_basop_util.h b/lib_lc3plus/rom_basop_util.h new file mode 100644 index 000000000..6e757c339 --- /dev/null +++ b/lib_lc3plus/rom_basop_util.h @@ -0,0 +1,172 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef __BASOP_UTIL_ROM_H__ +#define __BASOP_UTIL_ROM_H__ + +#include "basop_util_lc3plus.h" +#include "functions.h" + +#define LD_INT_TAB_LEN 120 +#define INV_TABLE_SIZE 256 +#define SQRT_TABLE_SIZE 256 + +#ifndef CHEAP_NORM_SIZE +#define CHEAP_NORM_SIZE 161 +#endif + +#define MINSFTAB 7 +#define MAXSFTAB 25 + +#ifdef ENABLE_HR_MODE +#define SHC(x) ((Word32)x) +#else +#define SHC(x) WORD322WORD16((Word32)x) +#endif + +/** + * \brief Lookup-Table for binary logarithm + */ +extern const Word16 ldCoeff_lc3plus[7]; + +/** + \brief Lookup-Table for binary power algorithm +*/ +extern const UWord32 exp2_tab_long_lc3plus[32]; + +/** + \brief Lookup-Table for binary power algorithm +*/ +extern const UWord32 exp2w_tab_long_lc3plus[32]; + +/** + \brief Lookup-Table for binary power algorithm +*/ +extern const UWord32 exp2x_tab_long_lc3plus[32]; + +/** + * \brief 1/x, x=[0,1,2,3...] table + */ +#ifdef ENABLE_HR_MODE +extern const Word16 InvIntTable[74]; +#else +extern const Word16 InvIntTable[32]; +#endif + +/** + * \ brief Lookup for sine tables and windows. + */ +void BASOP_getTables( +#ifdef ENABLE_HR_MODE + const PWord32 **ptwiddle, + const PWord32 **sin_twiddle, +#else + const PWord16 **ptwiddle, + const PWord16 **sin_twiddle, +#endif + Word16 *sin_step, + Word16 length); + +extern const Word32 RealFFT20_twid[6]; +extern const Word32 RealFFT32_twid[10]; +extern const Word32 RealFFT40_twid[12]; +extern const Word32 RealFFT60_twid[17]; +extern const Word32 RealFFT64_twid[18]; +extern const Word32 RealFFT80_twid[22]; +extern const Word32 RealFFT96_twid[26]; +extern const Word32 RealFFT128_twid[34]; +extern const Word32 RealFFT192_twid[50]; +extern const Word32 RealFFT256_twid[66]; +extern const Word32 RealFFT384_twid[98]; +extern const Word32 RealFFT512_twid[130]; +extern const Word32 RealFFT768_twid[194]; + +#ifdef ENABLE_HR_MODE +extern const PWord32 SineTable480[241]; +extern const PWord32 SineTable320[161]; +extern const PWord32 SineTable960[481]; +#else +extern const PWord16 SineTable480[241]; +extern const PWord16 SineTable320[161]; +extern const PWord16 SineTable960[481]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_15_6[2 * (90 - 15)]; +#else +extern const Word16 RotVector_15_6[2 * (90 - 15)]; +#endif + +extern const Word32 RotVector_32_32[2 * 20]; +extern const Word32 RotVector_40_32[2 * 28]; + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_320[2 * (320 - 20)]; +#else +extern const Word16 RotVector_320[2 * (320 - 20)]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_360[2 * (360 - 30)]; +#else +extern const Word16 RotVector_360[2 * (360 - 30)]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_480[2 * (480 - 30)]; +#else +extern const Word16 RotVector_480[2 * (480 - 30)]; +#endif + +#ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS +extern const Word32 RotVector_720[2 * (720 - 30)]; +#endif +extern const Word32 RotVector_960[2 * (480 - 60)]; +#else +extern const Word16 RotVector_960[2 * (480 - 60)]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_30_16[2 * (480 - 30)]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_32_8[2 * (256 - 32)]; +#else +extern const Word16 RotVector_32_8[2 * (256 - 32)]; +#endif + +#if defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB) +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_32_12[2 * (384 - 32)]; +#else +extern const Word16 RotVector_32_12[2 * (384 - 32)]; +#endif +#else +#define RotVector_32_12 NULL +#endif + +extern const Word32 isqrt_table[128 + 2]; + +extern const Word32 Log2_16_table1[16]; +extern const Word16 Log2_16_table2[16]; + +extern const Word32 InvLog2_16_table1[64]; +extern const Word16 InvLog2_16_table2[64]; + +extern const UWord8 gf16_mult_table[256]; +extern const UWord8 rs16_elp_deg2_table[256]; +extern const UWord16 rs16_elp_deg3_table[256]; + +#ifdef ENABLE_HR_MODE +extern const Word32 invSqrtTab[(128 + 2)]; +#endif + +#endif diff --git a/lib_lc3plus/scale_signal24_fx.c b/lib_lc3plus/scale_signal24_fx.c new file mode 100644 index 000000000..548788d2a --- /dev/null +++ b/lib_lc3plus/scale_signal24_fx.c @@ -0,0 +1,121 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void scale_signal24_fx(Word32 x[], /* i: time input signal */ +#ifdef ENABLE_HR_MODE + Word32 x_scaled[], +#else + Word16 x_scaled[], +#endif + Word16 *x_exp, +#ifdef ENABLE_HR_MODE + Word32 mdct_mem[], +#else + Word16 mdct_mem[], +#endif + Word16 mdct_mem_len, + Word16 resample_mem_in[], Word16 resample_mem_in_len, Word32 resample_mem_in50[], + Word16 resample_mem_out[], Word16 resample_mem_out_len, Word32 mdct_mem32[], Word16 N, + Word32 resamp_mem32[], Word16 mem_s12k8[], Word16 *resamp_scale) +{ + Word16 i; + Word16 s; + Word16 scales[6]; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("scale_signal24_fx", sizeof(struct { + Word16 i; + Word16 s; + Word16 scales[6]; + })); +#endif + + /* Scale input for 24 bit case */ + /* assure 24 bit input */ + FOR (i = 0; i < N; i++) + { + IF (x[i] >= 0) + { + x[i] = L_and(x[i], 0x007fffff); + } + ELSE + { + x[i] = (Word32)L_or( (UWord32)x[i], 0xff800000); + } + } + + /* Find maximum exponent */ + scales[0] = sub(15 + 8, getScaleFactor32_0(x, N)); + scales[1] = sub(15 + 8, getScaleFactor32_0(mdct_mem32, mdct_mem_len)); + scales[2] = sub(15 + 8, getScaleFactor32_0(resamp_mem32, resample_mem_in_len)); + scales[3] = sub(sub(*resamp_scale, 2), getScaleFactor32_0(resample_mem_in50, 2)); + scales[4] = sub(sub(*resamp_scale, 2), getScaleFactor16_0(resample_mem_out, resample_mem_out_len)); + scales[5] = sub(sub(*resamp_scale, 2), getScaleFactor16_0(mem_s12k8, 3)); + *x_exp = 7; move16(); + FOR (i = 0; i < 6; i++) + { + *x_exp = s_max(*x_exp, scales[i]); move16(); + } + + /* Shift input buffers */ + s = sub(15 + 8, *x_exp); + FOR (i = 0; i < N; i++) + { +#ifdef ENABLE_HR_MODE + x_scaled[i] = L_shl(x[i], s); +#else + x_scaled[i] = round_fx_sat(L_shl(x[i], s)); +#endif + } + + FOR (i = 0; i < mdct_mem_len; i++) + { +#ifdef ENABLE_HR_MODE + mdct_mem[i] = L_shl(mdct_mem32[i], s); +#else + mdct_mem[i] = round_fx_sat(L_shl(mdct_mem32[i], s)); +#endif + } + + FOR (i = 0; i < resample_mem_in_len; i++) + { + resample_mem_in[i] = round_fx_sat(L_shl(resamp_mem32[i], s)); + } + + /* Adjust resampler filter and output buffers */ + s = sub(sub(*resamp_scale, 2), *x_exp); + *resamp_scale = add(*x_exp, 2); + + IF (s) + { + FOR (i = 0; i < 2; i++) + { + resample_mem_in50[i] = L_shl(resample_mem_in50[i], s); + } + FOR (i = 0; i < resample_mem_out_len; i++) + { + resample_mem_out[i] = shl(resample_mem_out[i], s); + } + + FOR (i = 0; i < 3; i++) + { + mem_s12k8[i] = shl(mem_s12k8[i], s); + } + } + /* Store part of current frame as mdct memory buffer and resampler input buffer for next frame */ + basop_memcpy(mdct_mem32, &x[N - mdct_mem_len], mdct_mem_len * sizeof(Word32)); + basop_memmove(resamp_mem32, &x[N - resample_mem_in_len], resample_mem_in_len * sizeof(Word32)); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3.c index 1a6e4e7cc..1d2849f56 100644 --- a/lib_lc3plus/setup_dec_lc3.c +++ b/lib_lc3plus/setup_dec_lc3.c @@ -1,542 +1,539 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" -#include "setup_dec_lc3.h" #include "functions.h" -#include -#include +#include "setup_dec_lc3.h" /* if decoder is null only size is reported */ -# include "fft/iis_fft.h" - -int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) +/*assume 10ms for memory allocation for now */ +int alloc_decoder(LC3PLUS_Dec *decoder, int samplerate, int channels) { - int ch = 0; - size_t size = sizeof(LC3PLUS_Dec); - size_t frame_len = DYN_MAX_LEN_EXT(samplerate); - - void *PlcAdvSetup = NULL; - LC3_FLOAT *pcmbufHist, *harmonicBuf; - LC3_FLOAT *PhECU_oold_grp_shape, *PhECU_old_grp_shape; - LC3_FLOAT *PhECU_xfp; - Complex *PhECU_X_sav_m; - LC3_INT32 *PhECU_plocs; - LC3_FLOAT *PhECU_f0est, *PhECU_mag_chg_1st, *PhECU_Xavg; - LC3_FLOAT *sine_table1_phecu, *sine_table2_phecu; - HANDLE_IIS_FFT handle_fft_phaseecu; - HANDLE_IIS_FFT handle_ifft_phaseecu; - LC3_FLOAT *q_old_res; - + int ch = 0; + size_t size = sizeof(LC3PLUS_Dec); + void * ltpf_mem_x = NULL, *ltpf_mem_y = NULL, *stDec_ola_mem_fx = NULL; + int max_len = DYN_MAX_LEN_EXT(samplerate); /*NB sing 80 as minimum value changes BE for NB */ #ifdef CR8_A_PLC_FADEOUT_TUNING - LC3_INT32 * plc_longterm_advc_tdc = NULL, *plc_longterm_advc_ns = NULL; - LC3_INT16 longterm_analysis_counter_max = 0, longterm_analysis_counter_max_bytebuffer = 0; + Word32 * plc_longterm_advc_tdc = NULL, *plc_longterm_advc_ns = NULL; + Word16 longterm_analysis_counter_max = 0, longterm_analysis_counter_max_bytebuffer = 0; +#endif + + void *q_old_res_fx = NULL; + Word16 *sharedBuf = NULL; +#if defined(ENABLE_PC) + void *q_old_d_fx = NULL; +#endif + void *plcAd = NULL, *PhECU_f0est = NULL, *PhECU_plocs = NULL; + + for (ch = 0; ch < channels; ch++) + { + DecSetup *setup = balloc(decoder, &size, sizeof(DecSetup)); +#ifdef ENABLE_HR_MODE + int q_old_len = MIN(CODEC_FS(samplerate) * 100 / 10000, MAX_BW_HR); +#else + int q_old_len = MIN(CODEC_FS(samplerate) * 100 / 10000, MAX_BW ); #endif + int x_old_len = DYN_MAX_LEN_PCM_PLC(samplerate); /* max(pitchmax + frame ms, M+1 + pitchmax + frame/2) */ + int fs_idx = (samplerate / 10000); /* floor= integer truncation is needed here */ + + ltpf_mem_x = balloc(decoder, &size, sizeof(*setup->ltpf_mem_x) * (max_len + max_len / 40 - 2)); + ltpf_mem_y = + balloc(decoder, &size, + sizeof(*setup->ltpf_mem_y) * (max_len + CEILING(MAX_PITCH_12K8 * max_len, 128) + (max_len / 80))); - for (ch = 0; ch < channels; ch++) { - DecSetup* setup = balloc(decoder, &size, sizeof(DecSetup)); - - size_t max_pitch = ceilf(228.0 * CODEC_FS(samplerate) / 12800.0); - size_t pcm_plc_len = max_pitch + frame_len; - pcmbufHist = balloc(decoder, &size, sizeof(LC3_FLOAT) * pcm_plc_len); - harmonicBuf = balloc(decoder, &size, sizeof(LC3_FLOAT) * max_pitch); - PlcAdvSetup = balloc(decoder, &size, sizeof(*setup->PlcAdvSetup)); - PhECU_oold_grp_shape = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_oold_grp_shape_fx[MAX_LGW]; */ - PhECU_old_grp_shape = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_old_grp_shape_fx[MAX_LGW] ; */ - PhECU_xfp = balloc(decoder, &size, sizeof(LC3_FLOAT) *(frame_len * 16 / 10)); - PhECU_X_sav_m = balloc(decoder, &size, sizeof(Complex) *(((frame_len * 16 / 10) / 2) + 1));/*MAX_PLC_LMSPEC*/ - PhECU_plocs = balloc(decoder, &size, sizeof(LC3_INT32) * (((frame_len * 16 / 10) / 4) + 1 + 1)); /* BASOP Word16 *PhECU_plocs; */ - - handle_fft_phaseecu = balloc(decoder, &size, sizeof(IIS_FFT) * 1); - handle_ifft_phaseecu = balloc(decoder, &size, sizeof(IIS_FFT) * 1); - PhECU_f0est = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((frame_len * 16 / 10) / 4) + 1)); /*BASOP Word32 *PhECU_f0est;*/ - PhECU_mag_chg_1st = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_mag_chg_1st[MAX_LGW];*/ - PhECU_Xavg = balloc(decoder, &size, sizeof(LC3_FLOAT) * MAX_LGW); /* BASOP Word16 PhECU_Xavg[MAX_LGW] ; */ - - sine_table1_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); - sine_table2_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); + stDec_ola_mem_fx = balloc(decoder, &size, sizeof(*setup->stDec_ola_mem_fx) * DYN_MAX_MDCT_LEN(samplerate)); + +#if defined(ENABLE_PC) + q_old_d_fx = balloc(decoder, &size, sizeof(*setup->q_old_d_fx) * q_old_len); +#endif + sharedBuf = balloc(decoder, &size, sizeof(*setup->q_old_d_fx) * q_old_len + sizeof(*setup->plcAd->x_old_tot_fx) * x_old_len); + + /* To save static RAM, a large buffer sharedBuf is used to share + * space for q_old_d_fx, x_old_tot_fx and X_sav_fx (note: + * PHASE_ECU operates only at 10ms and standard precision) + * + * If partial Concealment is active, q_old_d_fx is saved in a separate buffer + * + * The following graph provides an overview about the memory + * sharing for 10ms and normal resolution: + */ + + /* Total buffer | <--- sharedBuf ---> | */ + /* ConcealMethod 3or4 | <---q_old_d_fx---> | <-------------------- x_old_tot_fx ------------------> | */ + /* ConcealMethod 3 | <---q_old_d_fx---> | |<------- M+1+pitch_max+ (frame_len/2)----------> | */ /* first BFI-frame only? */ + /* Meth 2,prevBfi=0 | | <------- 16 ms xfp ------->| */ + /* Meth 2 | ^ X_sav_fx ptr | <-------- maintained old_tot_fx ---------> | */ /* pitchmax samples maintained */ + /* Meth 2 | <----- X_sav 16 ms ----------> | ^xfp_fx ptr | */ + /* Meth2 ,prevBfi=1 | | <-12.25(forTDC),3.75(PLC2)->| */ /*the part used by PhECU is 3.75ms */ + /* ConcealMethod 2 |<- <10ms ->| */ + int max_plocs = DYN_MAX_PLOCS(samplerate); + plcAd = balloc(decoder, &size, sizeof(*setup->plcAd)); + PhECU_f0est = balloc(decoder, &size, sizeof(*setup->plcAd->PhECU_f0est) * max_plocs); + PhECU_plocs = balloc(decoder, &size, sizeof(*setup->plcAd->PhECU_plocs) * max_plocs); +#ifdef ENABLE_HR_MODE + q_old_res_fx = balloc(decoder, &size, sizeof(*setup->q_old_res_fx) * max_len); +#else + q_old_res_fx = balloc(decoder, &size, sizeof(*setup->q_old_res_fx) * MIN(max_len, MAX_BW)); +#endif #ifdef CR8_A_PLC_FADEOUT_TUNING - longterm_analysis_counter_max = plc_fadeout_param_maxlen[0]; - longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[0]; - +/* longterm_analysis_counter_max = PLC_LONGTERM_ANALYSIS_MS * (100.0f / 25.0f);*/ +/* assert(longterm_analysis_counter_max == (PLC_LONGTERM_ANALYSIS_MS * (100 /25))); */ /* test integer division for compatibility */ +/* longterm_analysis_counter_max_bytebuffer = floor(longterm_analysis_counter_max / 30.0); */ +/* assert(longterm_analysis_counter_max_bytebuffer == (longterm_analysis_counter_max / 30)); */ /* test integer division for compatibility */ - plc_longterm_advc_tdc = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer); - plc_longterm_advc_ns = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer); +/* longterm_analysis_counter_max = (longterm_analysis_counter_max_bytebuffer+1) * 30; */ + + longterm_analysis_counter_max = plc_fadeout_param_maxlen[0]; + longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[0]; + + plc_longterm_advc_tdc = balloc(decoder, &size, sizeof(Word32) * longterm_analysis_counter_max_bytebuffer); + plc_longterm_advc_ns = balloc(decoder, &size, sizeof(Word32) * longterm_analysis_counter_max_bytebuffer); #endif - - q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); - - if (decoder) { + + if (decoder) + { decoder->channel_setup[ch] = setup; + setup->ltpf_mem_x = ltpf_mem_x; + setup->ltpf_mem_y = ltpf_mem_y; + setup->stDec_ola_mem_fx = stDec_ola_mem_fx; + setup->q_old_res_fx = q_old_res_fx; +#if defined(ENABLE_PC) + setup->q_old_d_fx = q_old_d_fx; +#else + setup->q_old_d_fx = sharedBuf; +#endif + setup->plcAd = plcAd; + } + if (decoder && plcAd) + { +#ifdef ENABLE_HR_MODE + if (fs_idx > 4) + { + fs_idx = 4; + } +#endif - setup->PlcAdvSetup = PlcAdvSetup; - - setup->PlcAdvSetup->pcmbufHist = pcmbufHist; - setup->PlcAdvSetup->PlcTdcSetup.harmonicBuf = harmonicBuf; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape = PhECU_oold_grp_shape; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape = PhECU_old_grp_shape; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp = PhECU_xfp; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m = PhECU_X_sav_m; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_plocs = PhECU_plocs; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_f0est = PhECU_f0est; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st = PhECU_mag_chg_1st; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Xavg = PhECU_Xavg; - setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu = handle_fft_phaseecu; - setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu = handle_ifft_phaseecu; - - setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu->sine_table = sine_table1_phecu; - setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu->sine_table = sine_table2_phecu; + setup->plcAd->x_old_tot_fx = &sharedBuf[q_old_len]; + setup->plcAd->PhECU_f0est = PhECU_f0est; + setup->plcAd->PhECU_xfp_fx = &(setup->plcAd->x_old_tot_fx[x_old_len-LprotSzPtr[fs_idx]]); /* point to the last 16ms of the x_old_tot_fx */ + setup->plcAd->PhECU_X_sav_fx = sharedBuf; /* reuse of lprot(=num_FsByResQ0[fs_idx]) values from this point fwd, i.e beyond the end of q_old_fx */ + setup->plcAd->PhECU_plocs = PhECU_plocs; #ifdef CR8_A_PLC_FADEOUT_TUNING - setup->PlcAdvSetup->longterm_analysis_counter_max = longterm_analysis_counter_max; - setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = longterm_analysis_counter_max_bytebuffer; + setup->plcAd->longterm_analysis_counter_max = longterm_analysis_counter_max; + setup->plcAd->longterm_analysis_counter_max_bytebuffer = longterm_analysis_counter_max_bytebuffer; - setup->PlcAdvSetup->plc_longterm_advc_tdc = plc_longterm_advc_tdc; - setup->PlcAdvSetup->plc_longterm_advc_ns = plc_longterm_advc_ns; + setup->plcAd->plc_longterm_advc_tdc = plc_longterm_advc_tdc; + setup->plcAd->plc_longterm_advc_ns = plc_longterm_advc_ns; #endif - - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (CODEC_FS(samplerate) * 16) / 1000; - real_fft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu)); - real_ifft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu)); - setup->statePC.q_old_res = q_old_res; } } return (int)size; } -LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode - , int hrmode -) +LC3PLUS_Error FillDecSetup(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + ) { - memset(decoder, 0, lc3plus_dec_get_size(samplerate, channels)); + int ch = 0; + + memset(decoder, 0, lc3plus_dec_get_size(samplerate, channels, plc_mode)); alloc_decoder(decoder, samplerate, channels); + +#ifdef ENABLE_HR_MODE + decoder->hrmode = hrmode != 0; +#endif decoder->fs = CODEC_FS(samplerate); decoder->fs_out = samplerate; decoder->fs_idx = FS2FS_IDX(decoder->fs); - decoder->plcMeth = plc_mode; - - decoder->hrmode = hrmode != 0; - -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (decoder->fs_idx > 4) { - decoder->fs_idx = 5; - } -#endif - decoder->channels = channels; - decoder->frame_ms = 10; - decoder->frame_dms = 100; - decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx]; - - if (decoder->fs == 8000) { - decoder->tilt = 14; - } else if (decoder->fs == 16000) { - decoder->tilt = 18; - } else if (decoder->fs == 24000) { - decoder->tilt = 22; - } else if (decoder->fs == 32000) { - decoder->tilt = 26; - } else if (decoder->fs == 48000) { - decoder->tilt = 30; - } - else if (decoder->fs == 96000) { - decoder->tilt = 34; + decoder->channels = channels; + decoder->frame_dms = 100; + decoder->plcMeth = plc_mode; + { + decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx]; } + decoder->ltpf_mem_x_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(L_max(16000, decoder->fs), 16778), 11)) - 2; + decoder->ltpf_mem_y_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(decoder->fs, 18678) - 1, 5)) + 1 + + extract_l(L_shr_pos(Mpy_32_16_lc3plus(L_max(16000, decoder->fs), 16778), 12)); set_dec_frame_params(decoder); - lc3plus_dec_set_ep_enabled(decoder, 0); + for (ch = 0; ch < decoder->channels; ch++) + { + DecSetup *setup = decoder->channel_setup[ch]; + setup->plc_damping = 32767; + setup->ltpf_mem_scale_fac_idx = -1; + move16(); + + setup->pc_seed = 24607; + setup->ns_seed = 24607; + setup->ns_cum_alpha = 32767; + + int i = 0; + /* 0 = 0kHz 1= 8kHz, 2= 16 kHz 3= 24 , 4 = 32 5=40 6=48kHz */ +#if (PHECU_XFP_LA == 0) + Word16 oneMsTab_LA[5] = {0, 0, 0, 0, 0}; +#else +# if (PHECU_XFP_LA == 4) + Word16 oneMsTab_LA[7] = {0 /*unused*/, 2, 4, 6, 8, 10 /*unused*/, 12}; +# else + Word16 oneMsTab_LA[7] = {0 /*unused*/, 8, 16, 24, 32, 40 /*unused*/, 48}; +# endif +#endif + Word16 oneMsTab[5] = {8, 16, 24, 32, 48}; + + setup->plcAd->stab_fac = 32767; + setup->plcAd->tdc_seed = 24607; + setup->plcAd->tdc_preemph_fac = plc_preemph_fac[decoder->fs_idx]; + setup->plcAd->tdc_lpc_order = 16; + setup->plcAd->PhECU_fs_idx_fx = + mult(decoder->frame_length, + (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */ + /* idx=frame/80, 0=8kHZ, 1=16kHz, 2=24 kHz, 3=32 kHz 5=*, 4=48 */ + + setup->plcAd->max_len_pcm_plc = DYN_MAX_LEN_PCM_PLC(decoder->fs); + if ((decoder->hrmode == 0) && (samplerate <= 48000)) + { + setup->plcAd->PhECU_frame_ms = (Word16)( + decoder->frame_dms * 0.1); /* needed in PLCUpdate and PLC main functions, adjusted in first frame */ + setup->plcAd->PhECU_seed_fx = 21845; + setup->plcAd->PhECU_LprotOrg_fx = + shl_pos(oneMsTab[setup->plcAd->PhECU_fs_idx_fx], 4); /* 16 *1ms = 1.6 *framelength */ + setup->plcAd->PhECU_Lprot_fx = setup->plcAd->PhECU_LprotOrg_fx; + setup->plcAd->PhECU_LA = oneMsTab_LA[setup->plcAd->PhECU_fs_idx_fx]; + setup->plcAd->PhECU_whr_tot_taper = sub(setup->plcAd->PhECU_Lprot_fx, decoder->frame_length); /* 3+3 ms */ + setup->plcAd->PhECU_whr_tot_flat = decoder->frame_length; /* 10 ms */ + setup->plcAd->PhECU_LDWIN_OLAP = shr_pos(decoder->frame_length, 2); /* 2.5 ms */ + setup->plcAd->max_lprot = DYN_MAX_LPROT(decoder->fs); + setup->plcAd->max_plocs = DYN_MAX_PLOCS(decoder->fs); + setup->plcAd->PhECU_margin_xfp = 0; + setup->plcAd->PhECU_L_oold_xfp_w_E_fx = LTOT_MIN_MAN; + setup->plcAd->PhECU_L_old_xfp_w_E_fx = LTOT_MIN_MAN; + + setup->plcAd->PhECU_oold_xfp_w_E_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL; + setup->plcAd->PhECU_old_xfp_w_E_exp_fx = LTOT_INIT_FLAG; + + setup->plcAd->PhECU_oold_Ltot_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL; + setup->plcAd->PhECU_old_Ltot_exp_fx = LTOT_INIT_FLAG; + + + for (i = 0; i < MAX_LGW; i++) + { + setup->plcAd->PhECU_oold_grp_shape_fx[i] = + GRP_SHAPE_INIT; /* negative value will be replaced in very first calculation */ + setup->plcAd->PhECU_old_grp_shape_fx[i] = GRP_SHAPE_INIT; + } + /* t_adv=ctrl.FRAME/2 + ctrl.PhECU.LprotOrg/2 - ctrl.PhECU.LA + LDWIN_OLAP/2; */ + i = add(add(decoder->frame_length, setup->plcAd->PhECU_LprotOrg_fx), setup->plcAd->PhECU_LDWIN_OLAP); + setup->plcAd->PhECU_t_adv = sub(shr_pos(i, 1), setup->plcAd->PhECU_LA); + + for (i = 0; i < MAX_LGW; i++) + { + setup->plcAd->PhECU_mag_chg_1st[i] = 32767; + } + setup->plcAd->PhECU_beta_mute = 16384; +#ifdef CR8_A_PLC_FADEOUT_TUNING + setup->plcAd->PhECU_nonpure_tone_flag = -1; +#endif + } + } + + lc3plus_dec_set_ep_enabled(decoder, 0); return LC3PLUS_OK; } /* set frame config params */ -void set_dec_frame_params(LC3PLUS_Dec* decoder) +void set_dec_frame_params(LC3PLUS_Dec *decoder) { - int ch = 0; +# ifdef CR8_G_ADD_75MS + Word16 tmp = 0; +# endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + Word16 n; +#endif - if (decoder->fs_idx == 5) - { - decoder->hrmode = 1; - } - - decoder->frame_length = ceil(decoder->fs * 10 / 1000); /* fs * 0.01*2^6 */ - if (decoder->hrmode == 1) - { - decoder->yLen = decoder->frame_length; - } - else + decoder->frame_length = extract_l(L_shr_pos(Mpy_32_16_lc3plus(decoder->fs, 20972), 6)); /* fs * 0.01*2^6 */ + +#ifdef ENABLE_HR_MODE + if (decoder->hrmode) { - decoder->yLen = MIN(MAX_BW, decoder->frame_length); + decoder->BW_cutoff_bits = 0; } +#endif - decoder->bands_number = 64; - if (decoder->frame_ms == 2.5) + SWITCH (decoder->frame_dms) { - decoder->frame_length = decoder->frame_length >> 2; - decoder->yLen /= 4; + case 25: + decoder->frame_length = shr_pos(decoder->frame_length, 2); + decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_2_5ms[decoder->fs_idx]; + decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes); + +#ifdef ENABLE_HR_MODE if (decoder->hrmode) { decoder->bands_number = bands_number_2_5ms_HR[decoder->fs_idx]; - } - else - { - decoder->bands_number = bands_number_2_5ms[decoder->fs_idx]; + decoder->bands_offset = bands_offset_2_5ms_HR[decoder->fs_idx - 4]; + decoder->W_fx = LowDelayShapes_n960_HRA_2_5ms[decoder->fs_idx - 4]; + decoder->W_size = LowDelayShapes_n960_len_2_5ms[decoder->fs_idx]; + decoder->yLen = decoder->frame_length; } - } - if (decoder->frame_ms == 5) - { - decoder->frame_length = decoder->frame_length >> 1; - decoder->yLen /= 2; - decoder->bands_number = bands_number_5ms[decoder->fs_idx]; - } -#ifdef CR8_G_ADD_75MS - if (decoder->frame_ms == 7.5) - { - decoder->frame_length = (decoder->frame_length >> 2) * 3; - decoder->yLen = (decoder->yLen / 4) * 3; - if (decoder->hrmode) - { - decoder->bands_number = bands_number_7_5ms_HR[decoder->fs_idx]; - } else - { - decoder->bands_number = bands_number_7_5ms[decoder->fs_idx]; - } - } #endif - - if (decoder->hrmode) - { - decoder->BW_cutoff_bits = 0; - } - else - { - decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx]; - } - - if (decoder->frame_ms == 10) - { - if (decoder->hrmode) { - decoder->bands_offset = ACC_COEFF_PER_BAND_HR[decoder->fs_idx]; + decoder->bands_number = bands_number_2_5ms[decoder->fs_idx]; + decoder->bands_offset = bands_offset_2_5ms[decoder->fs_idx]; + decoder->W_fx = LowDelayShapes_n960_2_5ms[decoder->fs_idx]; + decoder->W_size = LowDelayShapes_n960_len_2_5ms[decoder->fs_idx]; + decoder->yLen = s_min(MAX_BW >> 2, decoder->frame_length); } - else + + if (decoder->fs_idx == 0) { - decoder->bands_offset = ACC_COEFF_PER_BAND[decoder->fs_idx]; + int ch; + for (ch = 0; ch < decoder->channels; ch++) + { + DecSetup *setup = decoder->channel_setup[ch]; + if (setup->plcAd != NULL) + { + setup->plcAd->tdc_lpc_order = 8; + } + } } - decoder->cutoffBins = BW_cutoff_bin_all; - } - else if (decoder->frame_ms == 2.5) - { + BREAK; + case 50: + decoder->frame_length = shr_pos(decoder->frame_length, 1); + decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_5ms[decoder->fs_idx]; + decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes); + +#ifdef ENABLE_HR_MODE if (decoder->hrmode) { - decoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[decoder->fs_idx]; + decoder->bands_offset = bands_offset_5ms_HR[decoder->fs_idx - 4]; + decoder->W_fx = LowDelayShapes_n960_HRA_5ms[decoder->fs_idx - 4]; + decoder->W_size = LowDelayShapes_n960_len_5ms[decoder->fs_idx]; + decoder->yLen = decoder->frame_length; + decoder->bands_number = bands_number_5ms[decoder->fs_idx]; } else +#endif { - decoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[decoder->fs_idx]; + decoder->bands_offset = bands_offset_5ms[decoder->fs_idx]; + decoder->W_fx = LowDelayShapes_n960_5ms[decoder->fs_idx]; + decoder->W_size = LowDelayShapes_n960_len_5ms[decoder->fs_idx]; + decoder->yLen = s_min(MAX_BW >> 1, decoder->frame_length); + decoder->bands_number = bands_number_5ms[decoder->fs_idx]; } - decoder->cutoffBins = BW_cutoff_bin_all_2_5ms; - } - else if (decoder->frame_ms == 5) - { + BREAK; + +#ifdef CR8_G_ADD_75MS + case 75: + tmp = shr_pos(decoder->frame_length, 2); + decoder->frame_length = add(tmp, add(tmp, tmp)); + decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_7_5ms[decoder->fs_idx]; + decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes); +# ifdef ENABLE_HR_MODE if (decoder->hrmode) { - decoder->bands_offset = ACC_COEFF_PER_BAND_5ms_HR[decoder->fs_idx]; + decoder->bands_offset = bands_offset_7_5ms_HR[decoder->fs_idx - 4]; + decoder->W_fx = LowDelayShapes_n960_HRA_7_5ms[decoder->fs_idx - 4]; + decoder->W_size = LowDelayShapes_n960_len_7_5ms[decoder->fs_idx]; + decoder->yLen = decoder->frame_length; + decoder->bands_number = bands_number_7_5ms[decoder->fs_idx]; } else +# endif { - decoder->bands_offset = ACC_COEFF_PER_BAND_5ms[decoder->fs_idx]; + decoder->bands_offset = bands_offset_7_5ms[decoder->fs_idx]; + decoder->W_fx = LowDelayShapes_n960_7_5ms[decoder->fs_idx]; + decoder->W_size = LowDelayShapes_n960_len_7_5ms[decoder->fs_idx]; + decoder->yLen = s_min((MAX_BW >> 2) * 3, decoder->frame_length); + decoder->bands_number = bands_number_7_5ms[decoder->fs_idx]; } - decoder->cutoffBins = BW_cutoff_bin_all_5ms; - } -#ifdef CR8_G_ADD_75MS - else if (decoder->frame_ms == 7.5) - { + BREAK; +# endif + + case 100: + decoder->la_zeroes = LowDelayShapes_n960_la_zeroes[decoder->fs_idx]; + decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes); + decoder->bands_number = 64; + +#ifdef ENABLE_HR_MODE if (decoder->hrmode) { - decoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms_HR[decoder->fs_idx]; + decoder->bands_offset = bands_offset_HR[decoder->fs_idx - 4]; + decoder->W_fx = LowDelayShapes_n960_HRA[decoder->fs_idx - 4]; + decoder->W_size = LowDelayShapes_n960_len[decoder->fs_idx]; + decoder->yLen = decoder->frame_length; } else - { - decoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms[decoder->fs_idx]; - } - decoder->cutoffBins = BW_cutoff_bin_all_7_5ms; - } #endif - - decoder->n_bandsPLC = MIN(decoder->frame_length, 80); - - if (decoder->frame_ms == 10) - { - decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC[decoder->fs_idx]; - } - else if (decoder->frame_ms == 5) - { - decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_5ms[decoder->fs_idx]; - - if (decoder->fs == 24000) { - decoder->n_bandsPLC = 40; + decoder->W_fx = LowDelayShapes_n960[decoder->fs_idx]; + decoder->W_size = LowDelayShapes_n960_len[decoder->fs_idx]; + decoder->bands_offset = bands_offset[decoder->fs_idx]; + decoder->yLen = s_min(MAX_BW, decoder->frame_length); } + BREAK; } - else if (decoder->frame_ms == 2.5) - { - decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_2_5ms[decoder->fs_idx]; - if (decoder->fs == 48000) - { - decoder->n_bandsPLC = 60; - } - } -#ifdef CR8_G_ADD_75MS - else if (decoder->frame_ms == 7.5) { - decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_7_5ms[decoder->fs_idx]; - -#ifdef FIX_1082_INSTRUM_FAILED_LC3PLUS - if (decoder->fs != 32000 && decoder->fs != 96000) -#else - if (decoder->fs != 32000 && decoder->fs != 96000) - if (decoder->fs != 32000) -#endif - { - decoder->n_bandsPLC = 60; - } - } -#endif - - assert(decoder->bands_offsetPLC); - - if (decoder->frame_ms == 10) { - decoder->imdct_win = MDCT_WINS_10ms[decoder->hrmode][decoder->fs_idx]; - decoder->imdct_laZeros = MDCT_la_zeroes[decoder->fs_idx]; - decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_10ms[decoder->fs_idx]; - } - else if (decoder->frame_ms == 2.5) { - decoder->imdct_win = MDCT_WINS_2_5ms[decoder->hrmode][decoder->fs_idx]; - decoder->imdct_laZeros = MDCT_la_zeroes_2_5ms[decoder->fs_idx]; - decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_2_5ms[decoder->fs_idx]; - } - else if (decoder->frame_ms == 5) { - decoder->imdct_win = MDCT_WINS_5ms[decoder->hrmode][decoder->fs_idx]; - decoder->imdct_laZeros = MDCT_la_zeroes_5ms[decoder->fs_idx]; - decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_5ms[decoder->fs_idx]; - } -#ifdef CR8_G_ADD_75MS - else if (decoder->frame_ms == 7.5) { - decoder->imdct_win = MDCT_WINS_7_5ms[decoder->hrmode][decoder->fs_idx]; - decoder->imdct_laZeros = MDCT_la_zeroes_7_5ms[decoder->fs_idx]; - decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_7_5ms[decoder->fs_idx]; - } -#endif - - decoder->la_zeroes = decoder->imdct_laZeros; - - decoder->imdct_memLen = decoder->frame_length - decoder->imdct_laZeros; - - for (ch = 0; ch < decoder->channels; ch++) { - DecSetup* setup = decoder->channel_setup[ch]; - - setup->ltpf_mem_beta_idx = -1; - - setup->statePC.seed = 24607; - - if (decoder) { - /* Init DCT4 structs */ - if (setup->dct4structImdct.length != 0) { - dct4_free(&setup->dct4structImdct); - dct4_init(&setup->dct4structImdct, decoder->frame_length); - } else { - dct4_init(&setup->dct4structImdct, decoder->frame_length); - } - - setup->PlcNsSetup.cum_alpha = 1; - setup->PlcNsSetup.seed = 24607; - setup->alpha = 1; - if (setup->PlcAdvSetup) - { - LC3_INT32 pitch_max = 0, pitch_ana_len = 0, tdc_synt_len = 0; - pitch_max = ceil(228.0 * (LC3_FLOAT) decoder->fs / 12800.0); - pitch_ana_len = pitch_max + decoder->frame_length * (LC3_FLOAT) 100 / decoder->frame_dms; - tdc_synt_len = 16 + 1 + pitch_max + ceil(decoder->frame_length / 2); - setup->PlcAdvSetup->max_len_pcm_plc = MAX(pitch_ana_len, tdc_synt_len); - setup->PlcAdvSetup->PlcTdcSetup.preemphFac = plc_preemph_fac[decoder->fs_idx]; - setup->PlcAdvSetup->PlcTdcSetup.seed = 24607; - setup->PlcAdvSetup->PlcTdcSetup.lpcorder = 16; - - if (decoder->fs_idx == 0 && decoder->frame_dms == 25) - { - setup->PlcAdvSetup->PlcTdcSetup.lpcorder = 8; - } - - setup->PlcAdvSetup->stabFac = 1; - setup->PlcAdvSetup->cum_fading_fast = 1; - setup->PlcAdvSetup->cum_fading_slow = 1; - setup->PlcAdvSetup->cum_fflcAtten = 1; - + int ch; + for (ch = 0; ch < decoder->channels; ch++) + { + DecSetup *setup = decoder->channel_setup[ch]; + if (setup->plcAd != NULL) + { /*only set if plcAd was actually allocated */ #ifdef CR8_A_PLC_FADEOUT_TUNING - setup->PlcAdvSetup->longterm_analysis_counter_max = plc_fadeout_param_maxlen[(decoder->frame_dms / 25) - 1]; - setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[(decoder->frame_dms / 25) - 1]; -#endif - - if (decoder->fs_idx <= 4 && decoder->frame_dms == 100) - { - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (decoder->fs * 16) / 1000; /* 16 ms of samples at fs*/ - - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin = 0; - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr = 0; + setup->plcAd->longterm_analysis_counter_max = plc_fadeout_param_maxlen[(decoder->frame_dms / 25) - 1]; + setup->plcAd->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[(decoder->frame_dms / 25) - 1]; - set_vec(PHECU_GRP_SHAPE_INIT, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape, MAX_LGW); - set_vec(PHECU_GRP_SHAPE_INIT, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape, MAX_LGW); - - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E = (LC3_FLOAT)PHECU_LTOT_MIN_MAN * LC3_POW(2.0, PHECU_LTOT_MIN_EXP - 31); - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E = (LC3_FLOAT)PHECU_LTOT_MIN_MAN * LC3_POW(2.0, PHECU_LTOT_MIN_EXP - 31); - - /* CFL uses separate buffers for pcmHist, xfp and Xsav and q_d , BASOP uses an optimized joint buffer*/ - zero_float(setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot); - zero_cmplx(setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m, (setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot/2 + 1)); - - set_vec(POS_ONE_Q15, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st, MAX_LGW); - - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_beta_mute = (16384.0/32768.0); - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_seed = 21845; - - assert(decoder->frame_dms == 100); - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_LDWIN_OLAP = (decoder->frame_length / 4 ); /* 2.5 ms for regular 10 ms MDCT */ - - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_t_adv = ( - decoder->frame_length - + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot - + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_LDWIN_OLAP )/ 2; - } - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev = 0; /* fullband transient */ - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_num_plocs = 0; -#ifdef CR8_A_PLC_FADEOUT_TUNING - setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_nonpure_tone_flag = -1; /* nonpure tone flag, -1==new calc., 0==pure, 1==nonpure */ -#endif +#endif + setup->plcAd->PhECU_frame_ms = (Word16)( + decoder->frame_dms * + 0.1); /* needed in processPLCupdate_fx(), now set properly set in first frame /second time */ } } } +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + FOR (n=0; n < PLC_FADEOUT_TYPE_1_IN_MS*10/decoder->frame_dms;n++){ + decoder->alpha_type_2_table[n] = type_2_fadeout_fx(n, decoder->frame_dms); + } +#endif } -LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) +LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec *decoder, int ch, Word16 nBytes) { - int totalBits = 0, bitsTmp = 0, channel_bytes = 0, maxBytes = 0, minBytes = 0; - DecSetup* setup; + int tmp = 0, totalBits = 0; + int channel_bytes = 0; + int minBytes, maxBytes; + DecSetup *setup = decoder->channel_setup[ch]; + channel_bytes = nBytes; + +#ifdef ENABLE_HR_MODE if (decoder->hrmode) { - switch (decoder->frame_dms) + SWITCH (decoder->frame_dms) { case 25: maxBytes = 210; minBytes = MIN_NBYTES; - break; + BREAK; case 50: maxBytes = 375; minBytes = MIN_NBYTES; - break; + BREAK; #ifdef CR8_G_ADD_75MS case 75: maxBytes = 625; minBytes = MIN_NBYTES; - break; + BREAK; #endif case 100: maxBytes = 625; minBytes = MIN_NBYTES; - break; - default: - return LC3PLUS_HRMODE_ERROR; + BREAK; + default: return LC3PLUS_HRMODE_ERROR; } } else +#endif { minBytes = MIN_NBYTES; - maxBytes = MAX_NBYTES_100; // for backward compatibility, MAX_NBYTES_100 is used for all frame lengths + maxBytes = MAX_NBYTES_100; + } + + if (channel_bytes < minBytes || channel_bytes > maxBytes) + { + return LC3PLUS_NUMBYTES_ERROR; } - channel_bytes = nBytes; - - setup = decoder->channel_setup[ch]; - - if (channel_bytes < minBytes || channel_bytes > maxBytes) - { - return LC3PLUS_NUMBYTES_ERROR; - } + setup->targetBytes = channel_bytes; + move16(); + setup->total_bits = shl(setup->targetBytes, 3); + setup->enable_lpc_weighting = (setup->total_bits < 480); + setup->quantizedGainOff = + -(s_min(115, setup->total_bits / (10 * (decoder->fs_idx + 1))) + 105 + 5 * (decoder->fs_idx + 1)); + tmp = DEPR_i_mult(80, decoder->fs_idx); - setup->targetBytes = channel_bytes; - setup->total_bits = setup->targetBytes << 3; - setup->enable_lpc_weighting = (setup->total_bits < 480); - setup->quantizedGainOff = - -(MIN(115, setup->total_bits / (10 * (decoder->fs_idx + 1))) + 105 + 5 * (decoder->fs_idx + 1)); +#ifdef ENABLE_HR_MODE + if (decoder->hrmode && decoder->fs_idx == 5) + { + setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181); + } +#endif + + totalBits = setup->total_bits; - if (decoder->hrmode && decoder->fs_idx == 5) - { - setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181); - } - totalBits = setup->total_bits; - - if (decoder->frame_ms == 2.5) { - setup->enable_lpc_weighting = setup->total_bits < 120; - totalBits = setup->total_bits * 4.0 * (1.0 - 0.4); - } - if (decoder->frame_ms == 5) { - setup->enable_lpc_weighting = (setup->total_bits < 240); - totalBits = setup->total_bits * 2 - 160; - } + SWITCH (decoder->frame_dms) + { + case 25: + setup->enable_lpc_weighting = 0; + /* total_bits * 2.4 */ + totalBits = extract_l(L_shr(L_mult0(19661, setup->total_bits), 13)); + BREAK; + case 50: + setup->enable_lpc_weighting = setup->total_bits < 240; + totalBits = sub(DEPR_i_mult(setup->total_bits, 2), 160); + BREAK; #ifdef CR8_G_ADD_75MS - if (decoder->frame_ms == 7.5) { - setup->enable_lpc_weighting = (setup->total_bits < 360); - totalBits = round(setup->total_bits * 10 / 7.5); - } -#endif - - if (decoder->frame_length > 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0)) { - setup->N_red_tns = 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0); - setup->fs_red_tns = 40000; - } else { - setup->N_red_tns = decoder->frame_length; - setup->fs_red_tns = decoder->fs; - } + case 75: + setup->enable_lpc_weighting = setup->total_bits < 360; + totalBits = L_shr(L_mult0(10923, setup->total_bits), 13); + BREAK; +# endif + case 100: + BREAK; + } - bitsTmp = totalBits; - - if (bitsTmp < 400 + (decoder->fs_idx - 1) * 80) { - setup->ltpf_conf_beta = 0.4; - setup->ltpf_conf_beta_idx = 0; - } else if (bitsTmp < 480 + (decoder->fs_idx - 1) * 80) { - setup->ltpf_conf_beta = 0.35; - setup->ltpf_conf_beta_idx = 1; - } else if (bitsTmp < 560 + (decoder->fs_idx - 1) * 80) { - setup->ltpf_conf_beta = 0.3; - setup->ltpf_conf_beta_idx = 2; - } else if (bitsTmp < 640 + (decoder->fs_idx - 1) * 80) { - setup->ltpf_conf_beta = 0.25; - setup->ltpf_conf_beta_idx = 3; - } else { - setup->ltpf_conf_beta = 0; - setup->ltpf_conf_beta_idx = -1; - } - /* No LTPF in hrmode */ - if (decoder->hrmode == 1) { - setup->ltpf_conf_beta = 0; - setup->ltpf_conf_beta_idx = -1; - } + if (sub(totalBits, add(320, tmp)) < 0) + { + setup->ltpf_scale_fac_idx = 0; + move16(); + } + else if (sub(totalBits, add(400, tmp)) < 0) + { + setup->ltpf_scale_fac_idx = 1; + move16(); + } + else if (sub(totalBits, add(480, tmp)) < 0) + { + setup->ltpf_scale_fac_idx = 2; + move16(); + } + else if (sub(totalBits, add(560, tmp)) < 0) + { + setup->ltpf_scale_fac_idx = 3; + move16(); + } + else + { + setup->ltpf_scale_fac_idx = -1; + move16(); + } +#ifdef ENABLE_HR_MODE + /* No LTPF in hrmode */ + if (decoder->hrmode) + { + setup->ltpf_scale_fac_idx = -1; + move16(); + } +#endif + return LC3PLUS_OK; } + diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3.h index 17201a4a9..5c36163d3 100644 --- a/lib_lc3plus/setup_dec_lc3.h +++ b/lib_lc3plus/setup_dec_lc3.h @@ -1,117 +1,185 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#ifndef SETUP_DEC_LC3_FL_H -#define SETUP_DEC_LC3_FL_H +#ifndef SETUP_DEC_LC3_H +#define SETUP_DEC_LC3_H -#include "options.h" -#include "wmc_auto.h" #include "constants.h" -/* Channel state and bitrate-derived values go in this struct */ -typedef struct { - LC3_INT* stDec_ola_mem_fx; /* MDCT_MEM_LEN_MAX */ - LC3_INT total_bits; - LC3_INT enable_lpc_weighting; - LC3_INT targetBytes; - LC3_INT quantizedGainOff; - LC3_INT ltpf_param[3]; - LC3_INT ltpf_param_mem[3]; - LC3_INT ltpf_mem_pitch; - LC3_INT ltpf_mem_active; - LC3_INT ltpf_mem_pitch_fr; - LC3_INT ltpf_mem_beta_idx; - LC3_INT ltpf_conf_beta_idx; - LC3_INT spec_inv_idx; - LC3_INT concealMethod; - LC3_INT last_size; - LC3_INT BW_cutoff_idx_nf; - LC3_INT prev_BW_cutoff_idx_nf; - LC3_INT fs_red_tns; - LC3_INT N_red_tns; - LC3_INT scf_idx[SCF_MAX_PARAM]; - uint8_t resBits[MAX_RESBITS_LEN]; - LC3_INT tns_idx[TNS_NUMFILTERS_MAX * MAXLAG]; +typedef struct +{ + Word16 *x_old_tot_fx; /* MAX_LEN_PCM_PLC_TOT */ + Word32 *PhECU_f0est; /* MAX_PLOCS interpolated plocs */ + Word16 *PhECU_xfp_fx; /* MAX_LPROT */ + Word16 *PhECU_X_sav_fx; /* MAX_LPROT */ + Word16 *PhECU_plocs; /* MAX_PLOCS */ + Word16 *PhECU_fg_wintaper; /* MDCT_MEM_LEN_MAX */ + Word16 *PhECU_win_pre_tda; /* MAX_WIN_PRE_TDA */ + Word32 tdc_gain_c; + Word16 stab_fac; + Word16 tdc_fract; + Word16 tdc_seed; + Word16 tdc_preemph_fac; + Word16 tdc_lpc_order; + Word16 cum_fflcAtten; + Word16 harmonicBuf_fx[MAX_PITCH] ALIGN_BUFFER_STRUCT; + Word16 harmonicBuf_Q; + Word16 synthHist_fx[M] ALIGN_BUFFER_STRUCT; + Word16 cum_fading_slow; + Word16 cum_fading_fast; + Word16 PhECU_LprotOrg_fx; /* needed to change the Prot size adaptively */ + Word16 PhECU_Lprot_fx; + Word16 PhECU_fs_idx_fx; + Word16 PhECU_frame_ms; /* needed in PLC_Update and PLCMain functons*/ + Word16 PhECU_seed_fx; + Word16 PhECU_xfp_exp_fx; + Word16 PhECU_time_offs; + Word16 PhECU_X_savQ_fx; + Word16 PhECU_num_plocs; + Word16 PhECU_f0hzLtpBinQ7; /* ltp F0 in bins if available */ + Word16 PhECU_short_flag_prev; + Word16 PhECU_whr_tot_taper; + Word16 PhECU_whr_tot_flat; + Word16 PhECU_LDWIN_OLAP; + Word16 PhECU_LA; + Word16 PhECU_t_adv; + Word16 PhECU_beta_mute; + Word16 norm_corrQ15_fx; + Word16 q_fx_old_exp; + Word16 max_len_pcm_plc; + Word16 max_lprot; + Word16 max_plocs; + + /* Word32 L_tot W_energy sum exponent */ + Word16 PhECU_oold_Ltot_exp_fx; + Word16 PhECU_old_Ltot_exp_fx; + Word32 PhECU_L_oold_xfp_w_E_fx; + Word32 PhECU_L_old_xfp_w_E_fx; + Word16 PhECU_oold_xfp_w_E_exp_fx; /* input Word16 xfp exponnet */ + Word16 PhECU_old_xfp_w_E_exp_fx; + Word16 PhECU_oold_grp_shape_fx[MAX_LGW] ALIGN_BUFFER_STRUCT; + Word16 PhECU_old_grp_shape_fx[MAX_LGW] ALIGN_BUFFER_STRUCT; + Word16 PhECU_margin_xfp; +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 PhECU_nonpure_tone_flag; /* non-pure single tone indicator state */ +#endif + Word16 PhECU_mag_chg_1st[MAX_LGW] ALIGN_BUFFER_STRUCT; + Word16 PhECU_Xavg[MAX_LGW] ALIGN_BUFFER_STRUCT; + Word16 old_scf_q[M] ALIGN_BUFFER_STRUCT; + Word16 old_old_scf_q[M] ALIGN_BUFFER_STRUCT; + Word16 tdc_A[M + 1] ALIGN_BUFFER_STRUCT; + /* for now 20 ms saved Q14 or ptr to a combined ifft win and MDCT preTDA synthesis window 16 ms */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 longterm_counter_plcTdc; +# ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + Word16 longterm_counter_plcPhaseEcu; +# endif + Word16 longterm_counter_plcNsAdv; + Word16 longterm_analysis_counter_max; /* Maximum longterm frames number */ + Word16 longterm_analysis_counter_max_bytebuffer; /* Same as above but reduced for circular bit-buffer */ + Word32 *plc_longterm_advc_tdc; + Word32 *plc_longterm_advc_ns; + UWord8 plc_fadeout_type; + Word16 overall_counter; + Word8 longterm_counter_byte_position; + Word8 longterm_counter_bit_position; +#endif +} AplcSetup; - LC3_FLOAT prev_fac_ns; - LC3_FLOAT ltpf_mem_x[3 * MAX_LEN]; - LC3_FLOAT ltpf_mem_y[3 * MAX_LEN]; - LC3_FLOAT ltpf_mem_gain; - LC3_FLOAT ltpf_conf_beta; - LC3_FLOAT sqQdec_fl[MAX_LEN]; - LC3_FLOAT scf_q[M]; - LC3_FLOAT int_scf[MAX_BANDS_NUMBER]; - LC3_FLOAT x_fl[MAX_LEN]; - LC3_FLOAT imdct_mem[MAX_LEN]; - LC3_FLOAT alpha; +/* Channel state and bitrate-derived values go in this struct */ +typedef struct +{ + Word16 *ltpf_mem_x; /* LTPF_MEM_X_LEN */ + Word16 *ltpf_mem_y; /* LTPF_MEM_Y_LEN */ +#ifdef ENABLE_HR_MODE + Word32 *stDec_ola_mem_fx; /* MDCT_MEM_LEN_MAX */ +#else + Word16 *stDec_ola_mem_fx; /* MDCT_MEM_LEN_MAX */ +#endif + AplcSetup *plcAd; + Word16 * q_old_d_fx; /* MAX_BW */ + Word16 q_old_fx_exp; + Word16 ns_seed; + Word16 ns_cum_alpha; + Word16 pc_nbLostFramesInRow; + Word16 pc_seed; + Word16 *q_old_res_fx; + Word16 q_old_res_fx_exp; + Word16 prev_gg; + Word16 prev_gg_e; + Word16 prev_BW_cutoff_idx_nf; + Word16 prev_fac_ns_fx; + Word16 total_bits; + Word16 enable_lpc_weighting; + Word16 stDec_ola_mem_fx_exp; + Word16 targetBytes; + Word16 ltpf_mem_e; + Word16 ltpf_mem_pitch_int; + Word16 ltpf_mem_pitch_fr; + Word16 ltpf_mem_gain; + Word16 ltpf_mem_active; + Word16 ltpf_scale_fac_idx; + Word16 ltpf_mem_scale_fac_idx; + Word16 quantizedGainOff; + Word16 prev_bfi; + Word16 prev_prev_bfi; + Word16 concealMethod; + Word16 nbLostFramesInRow; + Word16 plc_damping; + Word16 last_size; #ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - LC3_FLOAT rel_pitch_change; + Word32 rel_pitch_change; #endif - - Dct4 dct4structImdct; - - PlcSetup PlcSetup; - PlcNsSetup PlcNsSetup; - - pcState statePC; - PlcAdvSetup* PlcAdvSetup; } DecSetup; /* Constants and sampling rate derived values go in this struct */ -struct LC3PLUS_Dec { - DecSetup* channel_setup[MAX_CHANNELS]; - const LC3_INT* W_fx; - const LC3_INT* bands_offset; - const LC3_INT* cutoffBins; - - LC3_INT fs; /* sampling rate, 44.1 maps to 48 */ - LC3_INT fs_out; /* output sampling rate */ - LC3_INT fs_idx; /* sampling rate index */ - LC3_INT frame_length; /* sampling rate index */ - LC3_INT channels; /* number of channels */ - LC3_FLOAT frame_ms; /* frame length in ms (wrong for 44.1) */ - LC3_INT frame_dms; /* frame length in ms * 10 (wrong for 44.1) */ - LC3_INT last_size; /* size of last frame, without error protection */ - LC3_INT ep_enabled; /* error protection enabled */ - LC3_INT error_report; /* corrected errors in last frame or -1 on error */ +struct LC3PLUS_Dec +{ + DecSetup * channel_setup[MAX_CHANNELS]; +#ifdef ENABLE_HR_MODE + const Word32 *W_fx; +#else + const Word16 *W_fx; +#endif + const Word16 *bands_offset; + Word32 fs; /* sampling rate, 44.1 maps to 48 */ + Word32 fs_out; /* output sampling rate */ + Word16 fs_idx; /* sampling rate index */ + Word16 frame_length; /* sampling rate index */ + Word16 channels; /* number of channels */ + Word16 plcMeth; /* PLC method for all channels */ + Word16 frame_dms; /* frame length in dms (decimilliseconds, 10^-4)*/ + Word16 last_size; /* size of last frame, without error protection */ + Word16 ep_enabled; /* error protection enabled */ + Word16 error_report; /* corrected errors in last frame or -1 on error */ - LC3_INT imdct_memLen; - LC3_INT imdct_winLen; - LC3_INT imdct_laZeros; - const LC3_FLOAT* imdct_win; + Word16 n_pccw; + Word16 be_bp_left; + Word16 be_bp_right; + Word16 n_pc; + Word16 m_fec; + Word16 epmr; + Word16 combined_channel_coding; - LC3_INT yLen; - LC3_INT W_size; - LC3_INT la_zeroes; - LC3_INT bands_number; - LC3_INT ltpf_mem_x_len; - LC3_INT ltpf_mem_y_len; - LC3_INT BW_cutoff_bits; - LC3_INT tilt; - - LC3_INT hrmode; - LC3_INT specflip; - - const LC3_INT* bands_offsetPLC; - LC3_INT n_bandsPLC; - - LC3_INT32 rframe; - int plcMeth; /* PLC method for all channels */ - LC3_INT16 n_pccw; - LC3_INT16 be_bp_left; - LC3_INT16 be_bp_right; - LC3_INT16 n_pc; - LC3_INT16 m_fec; - int epmr; - LC3_INT16 combined_channel_coding; - int last_error; + Word16 yLen; + Word16 W_size; + Word16 la_zeroes; + Word16 stDec_ola_mem_fx_len; + Word16 bands_number; + Word16 ltpf_mem_x_len; + Word16 ltpf_mem_y_len; + Word16 BW_cutoff_bits; + Word16 hrmode; +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + Word16 alpha_type_2_table[80];/* PLC_FADEOUT_TYPE_1_IN_MS*10/25 */ +#endif }; #endif diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3.c index e991c50f4..7e20912bb 100644 --- a/lib_lc3plus/setup_enc_lc3.c +++ b/lib_lc3plus/setup_enc_lc3.c @@ -1,349 +1,466 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#include "options.h" -#include "wmc_auto.h" -#include "setup_enc_lc3.h" #include "functions.h" -#include +#include "setup_enc_lc3.h" /* if encoder is null only size is reported */ -int alloc_encoder(LC3PLUS_Enc* encoder, int channels) +int alloc_encoder(LC3PLUS_Enc *encoder, int samplerate, int channels) { - int ch = 0; - size_t size = sizeof(LC3PLUS_Enc); + int ch = 0; + size_t size = sizeof(LC3PLUS_Enc); + void * mdct_mem32 = NULL, *stEnc_mdct_mem = NULL; - for (ch = 0; ch < channels; ch++) { - EncSetup* setup = balloc(encoder, &size, sizeof(EncSetup)); - if (encoder) { + for (ch = 0; ch < channels; ch++) + { + EncSetup *setup = balloc(encoder, &size, sizeof(EncSetup)); + mdct_mem32 = balloc(encoder, &size, sizeof(*setup->mdct_mem32) * DYN_MAX_MDCT_LEN(samplerate)); + stEnc_mdct_mem = balloc(encoder, &size, sizeof(*setup->stEnc_mdct_mem) * DYN_MAX_MDCT_LEN(samplerate)); + if (encoder) + { encoder->channel_setup[ch] = setup; + setup->mdct_mem32 = mdct_mem32; + setup->stEnc_mdct_mem = stEnc_mdct_mem; } } return (int)size; } -LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels - , int hrmode - , int32_t lfe_channel_array[] -) +LC3PLUS_Error FillEncSetup(LC3PLUS_Enc *encoder, int samplerate, int channels +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + , int32_t lfe_channel_array[] + ) { int ch = 0; + memset(encoder, 0, lc3plus_enc_get_size(samplerate, channels)); - alloc_encoder(encoder, channels); + alloc_encoder(encoder, samplerate, channels); encoder->fs = CODEC_FS(samplerate); encoder->fs_in = samplerate; encoder->fs_idx = FS2FS_IDX(encoder->fs); - encoder->frame_dms = 100; - -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (encoder->fs_idx > 4) { - encoder->fs_idx = 5; + +# ifdef ENABLE_HR_MODE + if (encoder->fs_idx > 4) + { + encoder->fs_idx = 5; } -#endif - encoder->hrmode = hrmode != 0; - - encoder->channels = channels; - encoder->frame_ms = 10; - encoder->envelope_bits = 38; - encoder->global_gain_bits = 8; - encoder->noise_fac_bits = 3; - encoder->BW_cutoff_bits = BW_cutoff_bits_all[encoder->fs_idx]; - - encoder->r12k8_mem_in_len = 2 * 8 * encoder->fs / 12800; +# endif + + encoder->channels = channels; + encoder->frame_dms = 100; + encoder->envelope_bits = 38; + encoder->global_gain_bits = 8; + encoder->noise_fac_bits = 3; + encoder->r12k8_mem_in_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(encoder->fs, 20972), 9)); encoder->r12k8_mem_out_len = 24; + encoder->epmr = LC3PLUS_EPMR_ZERO; + encoder->bw_ctrl_active = 0; + encoder->bandwidth = L_shr_pos(encoder->fs, 1); + encoder->bandwidth_preset = L_shr_pos(encoder->fs, 1); for (ch = 0; ch < encoder->channels; ch++) { encoder->channel_setup[ch]->lfe = lfe_channel_array[ch] != 0; } - encoder->bw_ctrl_active = 0; - encoder->bandwidth = encoder->fs / 2; - encoder->bandwidth_preset = encoder->fs / 2; - - - if (encoder->fs == 8000) { - encoder->tilt = 14; - } else if (encoder->fs == 16000) { - encoder->tilt = 18; - } else if (encoder->fs == 24000) { - encoder->tilt = 22; - } else if (encoder->fs == 32000) { - encoder->tilt = 26; - } else if (encoder->fs == 48000) { - encoder->tilt = 30; - } - else if (encoder->fs == 96000) { - encoder->tilt = 34; + + for (ch = 0; ch < encoder->channels; ch++) + { + encoder->channel_setup[ch]->x_exp = 15; + encoder->channel_setup[ch]->resamp_exp = 17; } set_enc_frame_params(encoder); - return LC3PLUS_OK; + + return lc3plus_enc_set_ep_mode(encoder, LC3PLUS_EP_OFF); /* also calls update_enc_bitrate */ } /* set frame config params */ -void set_enc_frame_params(LC3PLUS_Enc* encoder) +void set_enc_frame_params(LC3PLUS_Enc *encoder) { - int ch = 0; - EncSetup* setup; - - encoder->frame_length = ceil(encoder->fs * 10 / 1000); /* fs * 0.01*2^6 */ - if (encoder->hrmode == 1) - { - encoder->yLen = encoder->frame_length; - } - else - { - encoder->yLen = MIN(MAX_BW, encoder->frame_length); - encoder->sns_damping = 0.85; - } +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_075_DMS_MODE + Word16 tmp; +# endif +#endif - encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; - encoder->bands_number = 64; - encoder->nSubdivisions = 3; - encoder->near_nyquist_index = encoder->bands_number - 2; - encoder->near_nyquist_flag = 0; - encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN; + encoder->frame_length = extract_l(L_shr_pos(Mpy_32_16_lc3plus(encoder->fs, 20972), 6)); /* fs * 0.01*2^6 */ - if (encoder->fs_idx == 5) - { - encoder->hrmode = 1; - } - +# ifdef ENABLE_HR_MODE if (encoder->hrmode) { encoder->BW_cutoff_bits = 0; } else +# endif { encoder->BW_cutoff_bits = BW_cutoff_bits_all[encoder->fs_idx]; } - if (encoder->frame_ms == 10) { - encoder->la_zeroes = MDCT_la_zeroes[encoder->fs_idx]; + SWITCH (encoder->frame_dms) + { + case 25: + encoder->frame_length = shr_pos(encoder->frame_length, 2); + encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_2_5ms[encoder->fs_idx]; + encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes); + encoder->nSubdivisions = 2; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 2); + +# ifdef ENABLE_HR_MODE if (encoder->hrmode) { - encoder->bands_offset = ACC_COEFF_PER_BAND_HR[encoder->fs_idx]; + encoder->bands_number = bands_number_2_5ms_HR[encoder->fs_idx]; + encoder->bands_offset = bands_offset_2_5ms_HR[encoder->fs_idx - 4]; + encoder->W_fx = LowDelayShapes_n960_HRA_2_5ms[encoder->fs_idx - 4]; + encoder->W_size = LowDelayShapes_n960_len_2_5ms[encoder->fs_idx]; + encoder->yLen = encoder->frame_length; } else +# endif { - encoder->bands_offset = ACC_COEFF_PER_BAND[encoder->fs_idx]; - } - encoder->cutoffBins = BW_cutoff_bin_all; + encoder->yLen = s_min(MAX_BW >> 2, encoder->frame_length); + encoder->W_fx = LowDelayShapes_n960_2_5ms[encoder->fs_idx]; + encoder->W_size = LowDelayShapes_n960_len_2_5ms[encoder->fs_idx]; + encoder->bands_number = bands_number_2_5ms[encoder->fs_idx]; + encoder->bands_offset = bands_offset_2_5ms[encoder->fs_idx]; + encoder->near_nyquist_index = encoder->bands_number - 2; + encoder->near_nyquist_flag = 0; + } + + BREAK; + case 50: + encoder->frame_length = shr_pos(encoder->frame_length, 1); + encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_5ms[encoder->fs_idx]; + encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes); + encoder->nSubdivisions = 2; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 1); - encoder->attdec_nblocks = 4; - encoder->attdec_damping = 0.5; - encoder->attdec_hangover_thresh = 2; - } -#ifdef CR8_G_ADD_75MS - else if (encoder->frame_ms == 7.5) { +# ifdef ENABLE_HR_MODE if (encoder->hrmode) { - encoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms_HR[encoder->fs_idx]; + encoder->bands_offset = bands_offset_5ms_HR[encoder->fs_idx - 4]; + encoder->W_fx = LowDelayShapes_n960_HRA_5ms[encoder->fs_idx - 4]; + encoder->W_size = LowDelayShapes_n960_len_5ms[encoder->fs_idx]; + encoder->yLen = encoder->frame_length; + encoder->bands_number = bands_number_5ms[encoder->fs_idx]; } else +# endif { - encoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms[encoder->fs_idx]; - } - encoder->la_zeroes = MDCT_la_zeroes_7_5ms[encoder->fs_idx]; - encoder->cutoffBins = BW_cutoff_bin_all_7_5ms; - encoder->attdec_nblocks = 3; - encoder->attdec_damping = 0.3; - encoder->attdec_hangover_thresh = 1; - - encoder->frame_length = (encoder->frame_length >> 2) * 3; - encoder->yLen = (encoder->yLen >> 2) * 3; + encoder->yLen = s_min(MAX_BW >> 1, encoder->frame_length); + encoder->W_fx = LowDelayShapes_n960_5ms[encoder->fs_idx]; + encoder->W_size = LowDelayShapes_n960_len_5ms[encoder->fs_idx]; + encoder->bands_number = bands_number_5ms[encoder->fs_idx]; + encoder->bands_offset = bands_offset_5ms[encoder->fs_idx]; + encoder->near_nyquist_index = encoder->bands_number - 3; + encoder->near_nyquist_flag = 0; + } + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN; + BREAK; - encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; +#ifdef CR8_G_ADD_75MS + case 75: + tmp = shr_pos(encoder->frame_length, 2); + encoder->frame_length = add(tmp, add(tmp, tmp)); + encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_7_5ms[encoder->fs_idx]; + encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes); + encoder->bands_number = bands_number_7_5ms[encoder->fs_idx]; + encoder->nSubdivisions = 3; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN; + encoder->attdec_nblocks = 3; + encoder->attdec_damping = 9830; + encoder->attdec_hangover_thresh = 1; + encoder->r12k8_mem_out_len = 44; + encoder->near_nyquist_index = encoder->bands_number - 4; + encoder->near_nyquist_flag = 0; +# ifdef ENABLE_HR_MODE if (encoder->hrmode) { - encoder->bands_number = bands_number_7_5ms_HR[encoder->fs_idx]; + encoder->yLen = encoder->frame_length; + encoder->W_fx = LowDelayShapes_n960_HRA_7_5ms[encoder->fs_idx - 4]; + encoder->W_size = LowDelayShapes_n960_len_7_5ms[encoder->fs_idx]; + encoder->bands_number = bands_number_7_5ms[encoder->fs_idx]; + encoder->bands_offset = bands_offset_7_5ms_HR[encoder->fs_idx - 4]; } else +# endif { + encoder->yLen = s_min((MAX_BW >> 2) * 3, encoder->frame_length); + encoder->W_fx = LowDelayShapes_n960_7_5ms[encoder->fs_idx]; + encoder->W_size = LowDelayShapes_n960_len_7_5ms[encoder->fs_idx]; encoder->bands_number = bands_number_7_5ms[encoder->fs_idx]; + encoder->bands_offset = bands_offset_7_5ms[encoder->fs_idx]; } + BREAK; +# endif + + case 100: + encoder->la_zeroes = LowDelayShapes_n960_la_zeroes[encoder->fs_idx]; + encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes); + encoder->bands_number = 64; encoder->nSubdivisions = 3; - encoder->near_nyquist_index = encoder->bands_number - 4; - encoder->r12k8_mem_out_len = ceil(2.0 * ((LC3_FLOAT) encoder->frame_length / 2.0 - (LC3_FLOAT) encoder->la_zeroes) * 12800.0 / (LC3_FLOAT) encoder->fs - 8.0); - } -#endif - else if (encoder->frame_ms == 5) { - encoder->frame_length = encoder->frame_length >> 1; - encoder->yLen /= 2; - encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; - encoder->bands_number = bands_number_5ms[encoder->fs_idx]; - encoder->nSubdivisions = 2; - encoder->near_nyquist_index = encoder->bands_number - 3; - encoder->la_zeroes = MDCT_la_zeroes_5ms[encoder->fs_idx]; - if (encoder->hrmode) - { - encoder->bands_offset = ACC_COEFF_PER_BAND_5ms_HR[encoder->fs_idx]; - } - else - { - encoder->bands_offset = ACC_COEFF_PER_BAND_5ms[encoder->fs_idx]; - } - encoder->cutoffBins = BW_cutoff_bin_all_5ms; - } - else if (encoder->frame_ms == 2.5) { - encoder->la_zeroes = MDCT_la_zeroes_2_5ms[encoder->fs_idx]; - if (encoder->hrmode) - { - encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[encoder->fs_idx]; - } - else - { - encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[encoder->fs_idx]; - } - encoder->cutoffBins = BW_cutoff_bin_all_2_5ms; - encoder->frame_length = encoder->frame_length >> 2; - encoder->yLen /= 4; - encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN; + encoder->attdec_nblocks = 4; + encoder->attdec_damping = 16384; + encoder->attdec_hangover_thresh = 2; + encoder->near_nyquist_index = encoder->bands_number - 2; + encoder->near_nyquist_flag = 0; + +# ifdef ENABLE_HR_MODE if (encoder->hrmode) { - encoder->bands_number = bands_number_2_5ms_HR[encoder->fs_idx]; + encoder->bands_offset = bands_offset_HR[encoder->fs_idx - 4]; + encoder->W_fx = LowDelayShapes_n960_HRA[encoder->fs_idx - 4]; + encoder->W_size = LowDelayShapes_n960_len[encoder->fs_idx]; + encoder->yLen = encoder->frame_length; } else +# endif { - encoder->bands_number = bands_number_2_5ms[encoder->fs_idx]; - } - - encoder->nSubdivisions = 2; - encoder->near_nyquist_index = encoder->bands_number - 2; - encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 2); - } - - for (ch = 0; ch < encoder->channels; ch++) { - setup = encoder->channel_setup[ch]; - - setup->olpa_mem_pitch = 17; -#ifdef CR9_F_PITCH_WIN_LEN_FIX - setup->pitch_flag = 0; -#endif - if (setup->mdctStruct.mem != NULL) { - mdct_free(&setup->mdctStruct); - mdct_init(&setup->mdctStruct, encoder->frame_length, encoder->frame_dms, encoder->fs_idx, encoder->hrmode); - - dct2_free(&setup->dct2StructSNS); - dct2_init(&setup->dct2StructSNS, M); - } - else - { - mdct_init(&setup->mdctStruct, encoder->frame_length, encoder->frame_dms, encoder->fs_idx, encoder->hrmode); - dct2_init(&setup->dct2StructSNS, M); + encoder->yLen = s_min(MAX_BW, encoder->frame_length); + encoder->W_fx = LowDelayShapes_n960[encoder->fs_idx]; + encoder->W_size = LowDelayShapes_n960_len[encoder->fs_idx]; + encoder->bands_offset = bands_offset[encoder->fs_idx]; } + BREAK; } } /* change encoder bitrate */ -LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) +LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc *encoder, int bitrate) { - int ch = 0, bitsTmp = 0, minBR = 0, maxBR = 0, totalBytes = 0; - LC3_INT channel_bytes = 0, max_bytes = 0; + int ch = 0; + int totalBytes = 0, maxBR = 0, minBR = 0, max_bytes = 0; + int channel_bytes = 0; -#ifdef ENABLE_HR_MODE_FL +# ifdef ENABLE_HR_MODE if (encoder->hrmode) { switch (encoder->frame_dms) { case 25: maxBR = 672000; - if (encoder->fs == 48000) {minBR = MIN_BR_25MS_48KHZ_HR;} - else if (encoder->fs == 96000) {minBR = MIN_BR_25MS_96KHZ_HR;} - else { return LC3PLUS_HRMODE_ERROR;} + if (encoder->fs == 48000) + { + minBR = MIN_BR_25MS_48KHZ_HR; + } + else if (encoder->fs == 96000) + { + minBR = MIN_BR_25MS_96KHZ_HR; + } + else + { + return LC3PLUS_HRMODE_ERROR; + } break; case 50: maxBR = 600000; - if (encoder->fs == 48000) {minBR = MIN_BR_50MS_48KHZ_HR;} - else if (encoder->fs == 96000) {minBR = MIN_BR_50MS_96KHZ_HR;} - else { return LC3PLUS_HRMODE_ERROR;} + if (encoder->fs == 48000) + { + minBR = MIN_BR_50MS_48KHZ_HR; + } + else if (encoder->fs == 96000) + { + minBR = MIN_BR_50MS_96KHZ_HR; + } + else + { + return LC3PLUS_HRMODE_ERROR; + } break; -#ifdef CR8_G_ADD_75MS - case 75: +# ifdef CR8_G_ADD_75MS + case 75: maxBR = 500000; if (encoder->fs == 48000) {minBR = MIN_BR_075DMS_48KHZ_HR;} else if (encoder->fs == 96000) {minBR = MIN_BR_075DMS_96KHZ_HR;} else {return LC3PLUS_HRMODE_ERROR;} - break; -#endif + BREAK; +# endif case 100: maxBR = 500000; - if (encoder->fs == 48000) {minBR = MIN_BR_100MS_48KHZ_HR;} - else if (encoder->fs == 96000) {minBR = MIN_BR_100MS_96KHZ_HR;} - else { return LC3PLUS_HRMODE_ERROR;} + if (encoder->fs == 48000) + { + minBR = MIN_BR_100MS_48KHZ_HR; + } + else if (encoder->fs == 96000) + { + minBR = MIN_BR_100MS_96KHZ_HR; + } + else + { + return LC3PLUS_HRMODE_ERROR; + } break; - default: - return LC3PLUS_HRMODE_ERROR; + default: return LC3PLUS_HRMODE_ERROR; } } else -#endif /* ENABLE_HR_MODE_FL */ { minBR = (MIN_NBYTES << 3); maxBR = MAX_BR; - + switch (encoder->frame_dms) { case 25: minBR = MIN_BR_025DMS; maxBR = MAX_BR; - break; + BREAK; case 50: minBR = MIN_BR_050DMS; maxBR = MAX_BR; /* have additional limitations for 5.0ms */ - switch (encoder->fs_in) + SWITCH (encoder->fs_in) { - case 8000: maxBR = MAX_BR_050DMS_NB; break; - default: break; +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_050DMS_NB; BREAK; +# endif + default: BREAK; } - break; -#ifdef CR8_G_ADD_75MS + BREAK; +# ifdef CR8_G_ADD_75MS case 75: minBR = MIN_BR_075DMS; - maxBR = MAX_BR_075DMS; + maxBR = MAX_BR_075DMS; // special value for maxBR @ 7.5ms /* have additional limitations for 7.5ms */ - switch (encoder->fs_in) + SWITCH (encoder->fs_in) { - case 8000: maxBR = MAX_BR_075DMS_NB ; break; - case 16000: maxBR = MAX_BR_075DMS_WB ; break; - case 24000: maxBR = MAX_BR_075DMS_SSWB; break; - default: break; +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_075DMS_NB ; BREAK; +# endif +# ifdef SUBSET_WB + case 16000: maxBR = MAX_BR_075DMS_WB ; BREAK; +# endif +# ifdef SUBSET_SSWB + case 24000: maxBR = MAX_BR_075DMS_SSWB; BREAK; +# endif + default: BREAK; } - break; -#endif + BREAK; +# endif case 100: /* have additional limitations for 10ms */ minBR = MIN_BR_100DMS; maxBR = MAX_BR; - switch (encoder->fs_in) + SWITCH (encoder->fs_in) { - case 8000: maxBR = MAX_BR_100DMS_NB ; break; - case 16000: maxBR = MAX_BR_100DMS_WB ; break; - case 24000: maxBR = MAX_BR_100DMS_SSWB; break; - default: maxBR = MAX_BR; break; +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_100DMS_NB ; BREAK; +# endif +# ifdef SUBSET_WB + case 16000: maxBR = MAX_BR_100DMS_WB ; BREAK; +# endif +# ifdef SUBSET_SSWB + case 24000: maxBR = MAX_BR_100DMS_SSWB; BREAK; +# endif + default: maxBR = MAX_BR; BREAK; } - break; + BREAK; default: return LC3PLUS_FRAMEMS_ERROR; } - maxBR *= (encoder->fs_in == 44100 ? 441. / 480 : 1); + + /* 441/480 in Q31 and 1000/75 in Q23 */ + if (encoder->fs_in == 44100) + { + minBR = Mpy_32_32_lc3plus(minBR, 1973000602); + maxBR = Mpy_32_32_lc3plus(maxBR, 1973000602); + } } +#else /* ENABLE_HR_MODE */ + minBR = (MIN_NBYTES << 3); + maxBR = MAX_BR; + + switch (encoder->frame_dms) + { + case 25: + minBR = MIN_BR_025DMS; + maxBR = MAX_BR; + BREAK; + case 50: + minBR = MIN_BR_050DMS; + maxBR = MAX_BR; + /* have additional limitations for 5.0ms */ + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_050DMS_NB; BREAK; +# endif + default: BREAK; + } + BREAK; +# ifdef CR8_G_ADD_75MS + case 75: + minBR = MIN_BR_075DMS; + maxBR = MAX_BR_075DMS; // special value for maxBR @ 7.5ms + /* have additional limitations for 7.5ms */ + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_075DMS_NB ; BREAK; +# endif +# ifdef SUBSET_WB + case 16000: maxBR = MAX_BR_075DMS_WB ; BREAK; +# endif +# ifdef SUBSET_SSWB + case 24000: maxBR = MAX_BR_075DMS_SSWB; BREAK; +# endif + default: BREAK; + } + BREAK; +# endif + case 100: + /* have additional limitations for 10ms */ + minBR = MIN_BR_100DMS; + maxBR = MAX_BR; + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_100DMS_NB ; BREAK; +# endif +# ifdef SUBSET_WB + case 16000: maxBR = MAX_BR_100DMS_WB ; BREAK; +# endif +# ifdef SUBSET_SSWB + case 24000: maxBR = MAX_BR_100DMS_SSWB; BREAK; +# endif + default: maxBR = MAX_BR; BREAK; + } + BREAK; + default: return LC3PLUS_FRAMEMS_ERROR; + } + + /* 441/480 in Q31 and 1000/75 in Q23 */ + if (encoder->fs_in == 44100) + { + minBR = Mpy_32_32_lc3plus(minBR, 1973000602); + maxBR = Mpy_32_32_lc3plus(maxBR, 1973000602); + } +#endif /* ENABLE_HR_MODE */ + minBR *= encoder->channels; maxBR *= encoder->channels; - + + if (bitrate < minBR || bitrate > maxBR) + { + return LC3PLUS_BITRATE_ERROR; + } + + encoder->bitrate = bitrate; + encoder->lc3_br_set = 1; + + /* move stuff to encoder->channel_setup */ + encoder->combined_channel_coding = 0; - if (encoder->channels > 1 && encoder->epmode) { if (encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in) <= 160) @@ -355,9 +472,9 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) if (encoder->epmode > 0) { max_bytes = bitrate * encoder->frame_length / (8 * encoder->fs_in * encoder->channels); + if (max_bytes < FEC_SLOT_BYTES_MIN || max_bytes > FEC_SLOT_BYTES_MAX) { - encoder->lc3_br_set = 0; return LC3PLUS_BITRATE_ERROR; } } @@ -365,37 +482,23 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) if (encoder->combined_channel_coding) { totalBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding, - bitrate * encoder->frame_length / (8 * encoder->fs_in)); + bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in)); encoder->channel_setup[0]->n_pccw = - fec_get_n_pccw(bitrate * encoder->frame_length / (8 * encoder->fs_in), encoder->epmode, + fec_get_n_pccw(bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in), encoder->epmode, encoder->combined_channel_coding); encoder->channel_setup[0]->n_pc = fec_get_n_pc(encoder->epmode, encoder->channel_setup[0]->n_pccw, - bitrate * encoder->frame_length / (8 * encoder->fs_in)); + bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in)); } else { - totalBytes = bitrate * encoder->frame_length / (8 * encoder->fs_in); - } - - if (encoder->frame_dms <= 50) - { - encoder->tnsMaxOrder = 4; - } else { - encoder->tnsMaxOrder = 8; + totalBytes = bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in); } - if (bitrate < minBR || bitrate > maxBR) { - return LC3PLUS_BITRATE_ERROR; - } - - encoder->lc3_br_set = 1; - for (ch = 0; ch < encoder->channels; ch++) { - - EncSetup* setup = encoder->channel_setup[ch]; - - setup->targetBytes = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); + for (ch = 0; ch < encoder->channels; ch++) + { + EncSetup *setup = encoder->channel_setup[ch]; channel_bytes = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); if (encoder->combined_channel_coding) @@ -405,15 +508,15 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) else { setup->targetBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding, channel_bytes); - setup->n_pccw = fec_get_n_pccw(channel_bytes, encoder->epmode, encoder->combined_channel_coding); - setup->n_pc = fec_get_n_pc(encoder->epmode, setup->n_pccw, channel_bytes); + setup->n_pccw = fec_get_n_pccw(channel_bytes, encoder->epmode, encoder->combined_channel_coding); + setup->n_pc = fec_get_n_pc(encoder->epmode, setup->n_pccw, channel_bytes); } - // reduce bandwith to 12kHz if bitrate is low - if (encoder->frame_dms == 100 && - ((setup->targetBytes < 40 && encoder->fs == 48000) || - (setup->targetBytes < 36 && encoder->fs == 32000))) + /* reduce bandwith to 12kHz if bitrate is low */ + if (sub(encoder->frame_dms, 100) == 0 && + ((sub(setup->targetBytes, 40) < 0 && L_sub(encoder->fs, 48000) == 0) || + (sub(setup->targetBytes, 36) < 0 && L_sub(encoder->fs, 32000) == 0))) { - encoder->bandwidth = MIN(12000, encoder->bandwidth_preset); + encoder->bandwidth = L_min(12000, encoder->bandwidth_preset); } else { @@ -421,177 +524,219 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) For a second channel with lower targetBytes, bandwidth is overwritten */ encoder->bandwidth = encoder->bandwidth_preset; } - encoder->bw_ctrl_cutoff_bin = encoder->bandwidth * encoder->frame_dms / 5000; - encoder->bw_index = (encoder->bandwidth / 4000) - 1; - setup->total_bits = setup->targetBytes << 3; - setup->targetBitsInit = setup->total_bits - encoder->envelope_bits - encoder->global_gain_bits - - encoder->noise_fac_bits - encoder->BW_cutoff_bits - - ceil(LC3_LOGTWO(encoder->frame_length / 2)) - 2 - 1; - if (setup->total_bits > 1280) { - setup->targetBitsInit = setup->targetBitsInit - 1; + { + Word16 tmp; + + SWITCH(encoder->frame_dms) + { + case 25: tmp = 1; BREAK; + case 50: tmp = 2; BREAK; + case 75: tmp = 3; BREAK; + default : tmp = 4; BREAK; + } + + encoder->bw_ctrl_cutoff_bin = L_mult0(Mpy_32_32_lc3plus(encoder->bandwidth, 10737419), tmp); /* bandwidth * frame_dms / 5000 */ } - if (setup->total_bits > 2560) { - setup->targetBitsInit = setup->targetBitsInit - 1; + + encoder->bw_index = sub( Mpy_32_32_lc3plus(encoder->bandwidth, 536871), 1); /* (bandwidth / 4000 ) - 1 */ + switch (encoder->frame_dms) + { + case 25: max_bytes = MAX_NBYTES_025; break; + case 50: max_bytes = MAX_NBYTES_050; break; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: max_bytes = MAX_NBYTES_075; BREAK; +# endif +#endif + case 100: max_bytes = MAX_NBYTES_100; break; + } +#ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + max_bytes = MAX_NBYTES_RED_HR; + } +#endif + if (setup->targetBytes < MIN_NBYTES || setup->targetBytes > max_bytes) + { + return LC3PLUS_BITRATE_ERROR; } + setup->total_bits = shl(setup->targetBytes, 3); + setup->targetBitsInit = + sub(setup->total_bits, + add(encoder->envelope_bits, + add(encoder->global_gain_bits, add(encoder->noise_fac_bits, encoder->BW_cutoff_bits)))); + setup->targetBitsInit = sub(setup->targetBitsInit, sub(17, norm_s(sub(encoder->yLen, 1)))); + if (setup->total_bits > 1280) + { + setup->targetBitsInit = sub(setup->targetBitsInit, 1); + } + if (setup->total_bits > 2560) + { + setup->targetBitsInit = sub(setup->targetBitsInit, 1); + } + +# ifdef ENABLE_HR_MODE if (encoder->hrmode) { setup->targetBitsInit -= 1; } +# endif - setup->targetBitsAri = setup->total_bits; - setup->enable_lpc_weighting = setup->total_bits < 480; + setup->targetBitsAri = setup->total_bits; + SWITCH (encoder->frame_dms) + { + case 25: + /* 9830 = 2.4 * 2^12 */ + setup->ltpf_enable = + sub(extract_l(L_shr(L_mult0(9830, setup->total_bits), 12)), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0; + setup->enable_lpc_weighting = 0; + BREAK; + case 50: + setup->ltpf_enable = sub(sub(DEPR_i_mult(setup->total_bits, 2), 160), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0; + setup->enable_lpc_weighting = setup->total_bits < 240; + BREAK; #ifdef CR8_G_ADD_75MS - if (encoder->frame_ms == 7.5) { + case 75: + setup->ltpf_enable = sub(L_shr(L_mult0(10923, setup->total_bits), 13), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0; setup->enable_lpc_weighting = setup->total_bits < 360; - } -#endif - if (encoder->frame_ms == 5) { - setup->enable_lpc_weighting = setup->total_bits < 240; - } - if (encoder->frame_ms == 2.5) { - setup->enable_lpc_weighting = setup->total_bits < 120; + BREAK; +# endif + case 100: + setup->enable_lpc_weighting = setup->total_bits < 480; + setup->ltpf_enable = sub(setup->total_bits, add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0; + BREAK; } setup->quantizedGainOff = - -(MIN(115, setup->total_bits / (10 * (encoder->fs_idx + 1))) + 105 + 5 * (encoder->fs_idx + 1)); + -(s_min(115, setup->total_bits / (10 * (encoder->fs_idx + 1))) + 105 + 5 * (encoder->fs_idx + 1)); + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode && encoder->fs_idx == 5) + { + setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181); + } +# endif - if (encoder->hrmode && encoder->fs_idx == 5) +# ifdef ENABLE_HR_MODE + if (encoder->frame_dms == 100 && + ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) || + (encoder->fs_in == 32000 && setup->targetBytes >= 81)) + && setup->targetBytes < 340 + && (encoder->hrmode == 0)) +# else + if (encoder->frame_dms == 100 && + ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) || + (encoder->fs_in == 32000 && setup->targetBytes >= 81)) + && setup->targetBytes < 340 + ) +# endif { - setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181); - } - - if (encoder->frame_ms == 10 && ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) || - (encoder->fs_in == 32000 && setup->targetBytes >= 81)) && setup->targetBytes < 340 && encoder->hrmode == 0) { setup->attack_handling = 1; - - } + } else if (encoder->frame_dms == 75 && ((encoder->fs_in >= 44100 && setup->targetBytes >= 75) || - (encoder->fs_in == 32000 && setup->targetBytes >= 61)) && setup->targetBytes < 150 && encoder->hrmode == 0) + (encoder->fs_in == 32000 && setup->targetBytes >= 61)) && setup->targetBytes < 150 +# ifdef ENABLE_HR_MODE + && encoder->hrmode == 0 +# endif + ) { setup->attack_handling = 1; } else { - /* reset for bitrate switching */ - setup->attack_handling = 0; - + /* reset attack detector for bitrate switching */ + setup->attack_handling = 0; setup->attdec_filter_mem[0] = 0; setup->attdec_filter_mem[1] = 0; - - setup->attdec_detected = 0; - setup->attdec_position = 0; - setup->attdec_acc_energy = 0; - } - - bitsTmp = setup->total_bits; - if (encoder->frame_ms == 2.5) { - bitsTmp = bitsTmp * 4.0 * (1.0 - 0.4); - } - if (encoder->frame_ms == 5) { - bitsTmp = bitsTmp * 2 - 160; - } -#ifdef CR8_G_ADD_75MS - if (encoder->frame_ms == 7.5) { - bitsTmp = round(bitsTmp * 10 / 7.5); - } -#endif - - if (bitsTmp < 400 + (encoder->fs_idx - 1) * 80) { - setup->ltpf_enable = 1; - } else if (bitsTmp < 480 + (encoder->fs_idx - 1) * 80) { - setup->ltpf_enable = 1; - } else if (bitsTmp < 560 + (encoder->fs_idx - 1) * 80) { - setup->ltpf_enable = 1; - } else if (bitsTmp < 640 + (encoder->fs_idx - 1) * 80) { - setup->ltpf_enable = 1; - } else { - setup->ltpf_enable = 0; + setup->attdec_detected = 0; + setup->attdec_position = 0; + setup->attdec_acc_energy = 0; + setup->attdec_scaling = 0; } - if (encoder->hrmode) { + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { setup->ltpf_enable = 0; } +# endif + encoder->sns_damping = SNS_DAMPING; - /* turn down SNS shaping for higher rates */ - if (encoder->hrmode == 0) { - encoder->sns_damping = 0.85; - } else { - encoder->sns_damping = 0.6; - if (encoder->fs_idx >= 4) { - if (encoder->frame_ms == 10) +# ifdef ENABLE_HR_MODE + IF (encoder->hrmode) + { + encoder->sns_damping = SNS_DAMPING_HRMODE; + IF (encoder->fs_idx >= 4) + { + IF ((encoder->frame_dms == 100) & (setup->total_bits > 4400)) { - if (setup->total_bits > 4400) { - encoder->sns_damping = 6881.0/32768.0; - } + encoder->sns_damping = SNS_DAMPING_HRMODE_UB_10MS; } #ifdef CR8_G_ADD_75MS - if (encoder->frame_ms == 7.5) + IF ((encoder->frame_dms == 75) & (setup->total_bits > 3300)) { - if (setup->total_bits > 3*4400/4) { - encoder->sns_damping = 5898.0/32768.0; - } + encoder->sns_damping = SNS_DAMPING_HRMODE_UB_7_5MS; } #endif - if (encoder->frame_ms == 5) + IF ((encoder->frame_dms == 50) & (setup->total_bits > 2300)) { - if (setup->total_bits > 4600/2) { - encoder->sns_damping = 4915.0/32768.0; - } + encoder->sns_damping = SNS_DAMPING_HRMODE_UB_5MS; } - if (encoder->frame_ms == 2.5) + IF ((encoder->frame_dms == 25) & (setup->total_bits > 1150)) { - if (setup->total_bits > 4600/4) { - encoder->sns_damping = 4915.0/32768.0; - } + encoder->sns_damping = SNS_DAMPING_HRMODE_UB_2_5MS; } } } if (encoder->hrmode && encoder->fs_idx >= 4) { - int real_rate = setup->targetBytes * 8000 / encoder->frame_ms; + int real_rate = setup->targetBytes * 8 * 10000 / encoder->frame_dms; setup->regBits = real_rate / 12500; if (encoder->fs_idx == 5) { - if (encoder->frame_ms == 10) + if (encoder->frame_dms == 100) { - setup->regBits +=2; + setup->regBits += 2; } #ifdef CR8_G_ADD_75MS - if (encoder->frame_ms == 7.5) + if (encoder->frame_dms == 75) { setup->regBits +=1; } #endif - if (encoder->frame_ms == 2.5) + if (encoder->frame_dms == 25) { setup->regBits -= 6; } } else { - if (encoder->frame_ms == 2.5) + if (encoder->frame_dms == 25) { setup->regBits -= 6; } - else if (encoder->frame_ms == 5) + else if (encoder->frame_dms == 50) { setup->regBits += 0; } #ifdef CR8_G_ADD_75MS - if (encoder->frame_ms == 7.5) + if (encoder->frame_dms == 75) { setup->regBits +=2; } #endif - if (encoder->frame_ms == 10) + if (encoder->frame_dms == 100) { setup->regBits += 5; } } + + if (setup->regBits < 6) { setup->regBits = 6; @@ -605,6 +750,7 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) { setup->regBits = -1; } +# endif } encoder->bitrate = bitrate; @@ -612,22 +758,3 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) return LC3PLUS_OK; } -void update_enc_bandwidth(LC3PLUS_Enc* encoder, int bandwidth) -{ - int index = 0; - - if (bandwidth >= encoder->fs_in) { - encoder->bandwidth = 0; - } - else - { - encoder->bandwidth = bandwidth; - index = FS2FS_IDX(bandwidth); -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (index > 4) { - index = 5; - } -#endif - encoder->bw_ctrl_cutoff_bin = encoder->cutoffBins[index]; - } -} diff --git a/lib_lc3plus/setup_enc_lc3.h b/lib_lc3plus/setup_enc_lc3.h index e3f62ba55..5e89829da 100644 --- a/lib_lc3plus/setup_enc_lc3.h +++ b/lib_lc3plus/setup_enc_lc3.h @@ -1,128 +1,131 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.4.5 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - -#ifndef SETUP_ENC_LC3_FL_H -#define SETUP_ENC_LC3_FL_H +#ifndef SETUP_ENC_LC3_H +#define SETUP_ENC_LC3_H -#include "options.h" -#include "wmc_auto.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ -typedef struct { - LC3_FLOAT targetBitsOff; - LC3_FLOAT ltpf_mem_normcorr; - LC3_FLOAT ltpf_mem_mem_normcorr; - LC3_FLOAT attdec_filter_mem[2]; - LC3_FLOAT attdec_acc_energy; - LC3_FLOAT r12k8_mem_50[2]; - LC3_FLOAT r12k8_mem_in[120]; -#ifdef CR8_G_ADD_75MS - LC3_FLOAT r12k8_mem_out[44]; +typedef struct +{ +#ifdef ENABLE_HR_MODE + Word32 *stEnc_mdct_mem; /* MDCT_MEM_LEN_MAX */ #else - LC3_FLOAT r12k8_mem_out[24]; + Word16 *stEnc_mdct_mem; /* MDCT_MEM_LEN_MAX */ #endif - LC3_FLOAT olpa_mem_s12k8[3]; - LC3_FLOAT olpa_mem_s6k4[LEN_6K4 + MAX_PITCH_6K4 + 16]; - LC3_FLOAT ltpf_mem_in[LTPF_MEMIN_LEN + LEN_12K8 + 1]; - LC3_FLOAT s_in_scaled[MAX_LEN]; - LC3_FLOAT s_12k8[LEN_12K8 + 1]; - LC3_FLOAT ener[MAX_BANDS_NUMBER]; - LC3_FLOAT scf_q[M]; - LC3_FLOAT scf[M]; - LC3_FLOAT int_scf[MAX_BANDS_NUMBER]; - LC3_FLOAT ltpf_mem_pitch; - - LC3_INT targetBytes; - LC3_INT total_bits; - LC3_INT targetBitsInit; - LC3_INT targetBitsAri; - LC3_INT enable_lpc_weighting; - LC3_INT ltpf_enable; - LC3_INT quantizedGainOff; - LC3_INT tns_bits; - LC3_INT targetBitsQuant; - LC3_INT olpa_mem_pitch; + Word32 *mdct_mem32; /* MDCT_MEM_LEN_MAX */ + Word32 targetBitsOff; + Word16 targetBytes; + Word16 total_bits; + Word16 targetBitsInit; + Word16 targetBitsAri; + Word16 enable_lpc_weighting; + Word16 ltpf_enable; + Word16 quantizedGainOff; + Word16 tns_bits; + Word16 targetBitsQuant; + Word16 olpa_mem_s6k4_exp; + Word16 olpa_mem_pitch; #ifdef CR9_F_PITCH_WIN_LEN_FIX - LC3_INT pitch_flag; + Word16 pitch_flag; #endif - LC3_INT ltpf_mem_ltpf_on; - LC3_INT mem_targetBits; - LC3_INT mem_specBits; - LC3_INT attack_handling; /* flag to enable attack handling */ - LC3_INT attdec_detected; - LC3_INT attdec_position; - LC3_INT ltpf_param[3]; - LC3_INT L_scf_idx[SCF_MAX_PARAM]; - LC3_INT codingdata[3 * MAX_LEN]; - uint8_t resBits[MAX_RESBITS_LEN]; - LC3_INT regBits; - - LC3_INT16 n_pc; - LC3_INT16 n_pccw; - LC3_INT16 be_bp_left; - LC3_INT16 be_bp_right; - - Mdct mdctStruct; - Dct2 dct2StructSNS; + Word16 ltpf_mem_in_exp; + Word16 ltpf_mem_normcorr; + Word16 ltpf_mem_mem_normcorr; + Word16 ltpf_mem_ltpf_on; + Word16 ltpf_mem_pitch; + Word16 mem_targetBits; + Word16 mem_specBits; + Word16 x_exp; + Word16 resamp_exp; + Word16 attack_handling; /* flag to enable attack handling */ + Word16 attdec_filter_mem[2]; + Word16 attdec_detected; + Word16 attdec_position; + Word32 attdec_acc_energy; + Word16 attdec_scaling; +#ifdef ENABLE_HR_MODE + Word16 regBits; + Word32 resamp_mem32[120] ALIGN_BUFFER_STRUCT; +#else + Word32 resamp_mem32[60] ALIGN_BUFFER_STRUCT; +#endif +#ifdef ENABLE_HR_MODE + Word16 r12k8_mem_in[120] ALIGN_BUFFER_STRUCT; +#else + Word16 r12k8_mem_in[60] ALIGN_BUFFER_STRUCT; +#endif + Word32 r12k8_mem_50[2] ALIGN_BUFFER_STRUCT; +#ifdef CR8_G_ADD_75MS + Word16 r12k8_mem_out[44] ALIGN_BUFFER_STRUCT; +#else + Word16 r12k8_mem_out[24] ALIGN_BUFFER_STRUCT; +#endif + Word16 olpa_mem_s12k8[3] ALIGN_BUFFER_STRUCT; + Word16 olpa_mem_s6k4[LEN_6K4 + MAX_PITCH_6K4 + 16] ALIGN_BUFFER_STRUCT; + Word16 ltpf_mem_in[LTPF_MEMIN_LEN + LEN_12K8 + 1] ALIGN_BUFFER_STRUCT; + Word16 n_pccw; + Word16 n_pc; - LC3_INT lfe; + Word16 lfe; } EncSetup; /* Constants and sampling rate derived values go in this struct */ -struct LC3PLUS_Enc { - EncSetup* channel_setup[MAX_CHANNELS]; - const LC3_INT* W_fx; - const LC3_INT* bands_offset; - const LC3_INT* cutoffBins; +struct LC3PLUS_Enc +{ + EncSetup *channel_setup[MAX_CHANNELS]; +#ifdef ENABLE_HR_MODE + const Word32 *W_fx; +#else + const Word16 *W_fx; +#endif + const Word16 *bands_offset; + + Word32 fs; /* encoder sampling rate 44.1 -> 48 */ + Word32 fs_in; /* input sampling rate */ + Word32 bitrate; /* global bitrate */ + Word16 fs_idx; /* sampling rate index */ + Word16 frame_length; /* audio samples / frame */ + Word16 channels; /* number of channels */ + Word16 epmode; /* error protection mode */ + Word16 frame_dms; /* frame length in dms (decimilliseconds, 10^-4)*/ + Word8 lc3_br_set; /* indicate if bitrate has been set */ + + Word16 yLen; + Word16 W_size; + Word16 la_zeroes; + Word16 stEnc_mdct_mem_len; + Word16 bands_number; + Word16 nSubdivisions; + Word16 ltpf_mem_in_len; + Word16 envelope_bits; + Word16 global_gain_bits; + Word16 noise_fac_bits; + Word16 BW_cutoff_bits; + Word16 r12k8_mem_in_len; + Word16 r12k8_mem_out_len; + Word16 near_nyquist_index; + Word16 near_nyquist_flag; - LC3_INT fs; /* encoder sampling rate 44.1 -> 48 */ - LC3_INT fs_in; /* input sampling rate */ - LC3_INT bitrate; /* global bitrate */ - LC3_INT fs_idx; /* sampling rate index */ - LC3_INT frame_length; /* audio samples / frame */ - LC3_INT channels; /* number of channels */ - LC3_INT epmode; /* error protection mode */ - LC3_FLOAT frame_ms; /* frame length in ms (wrong for 44.1) */ - LC3_INT frame_dms; /* frame length in ms * 10 (wrong for 44.1) */ - LC3_INT tilt; - LC3_INT lc3_br_set; - LC3_INT yLen; - LC3_INT W_size; - LC3_INT la_zeroes; - LC3_INT stEnc_mdct_mem_len; - LC3_INT bands_number; - LC3_INT nSubdivisions; - LC3_INT ltpf_mem_in_len; - LC3_INT envelope_bits; - LC3_INT global_gain_bits; - LC3_INT noise_fac_bits; - LC3_INT BW_cutoff_bits; - LC3_INT r12k8_mem_in_len; - LC3_INT r12k8_mem_out_len; - LC3_INT16 near_nyquist_index; - LC3_INT16 near_nyquist_flag; - LC3_INT tnsMaxOrder; - LC3_INT hrmode; - LC3_INT bandwidth; - LC3_INT bandwidth_preset; - LC3_INT bw_ctrl_active; - LC3_INT bw_ctrl_cutoff_bin; - LC3_INT bw_index; - LC3_FLOAT sns_damping; - LC3_INT attdec_nblocks; - LC3_FLOAT attdec_damping; - LC3_INT attdec_hangover_thresh; - - LC3_INT16 combined_channel_coding; - LC3_INT16 epmr; + Word16 epmr; + Word16 combined_channel_coding; + Word32 bandwidth; + Word32 bandwidth_preset; + Word32 bw_ctrl_active; + Word16 bw_ctrl_cutoff_bin; + Word16 bw_index; + Word16 attdec_nblocks; + Word16 attdec_damping; + Word16 attdec_hangover_thresh; + Word16 hrmode; + Word16 sns_damping; }; #endif diff --git a/lib_lc3plus/sns_compute_scf.c b/lib_lc3plus/sns_compute_scf.c deleted file mode 100644 index 7f78b3666..000000000 --- a/lib_lc3plus/sns_compute_scf.c +++ /dev/null @@ -1,175 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx) -{ - LC3_INT bands_number, d, i, j, n, n2, n4, mapping[64]; - LC3_FLOAT x_tmp1[MAX_LEN], sum, mean, nf, gains_smooth[M], ratio; - LC3_FLOAT sum_gains_smooth; - const LC3_FLOAT* sns_preemph; - - sum_gains_smooth = 0; sum = 0; - sns_preemph = sns_preemph_all[fs_idx]; - - bands_number = xLen; - assert(bands_number <= 64); - - /* 5 ms */ - if (bands_number < 64) { - d = 64 - bands_number; - - if (d < xLen) - { - j = 0; - for (i = 0; i < 2 * d; i = i + 2) { - x_tmp1[i] = x[j]; - x_tmp1[i + 1] = x[j]; - j++; - } - - move_float(&x_tmp1[2 * d], &x[d], 64 - 2 * d); - } - else if (bands_number < 32) - { - ratio = LC3_FABS((LC3_FLOAT) (1.0 - 32.0 / (LC3_FLOAT) xLen)); - n4 = round(ratio * xLen); - n2 = xLen - n4; - - j = 0; - for(i = 1; i <= n4; i++) - { - mapping[j] = i; - mapping[j + 1] = i; - mapping[j + 2] = i; - mapping[j + 3] = i; - j += 4; - } - - for (i = n4 + 1; i <= n4 + n2; i++) - { - mapping[j] = i; - mapping[j + 1] = i; - j += 2; - } - - - for (i = 0; i < 64; i++) - { - x_tmp1[i] = x[mapping[i] - 1]; - } - } else { - assert(0 && "Unsupported number of bands!"); - } - - move_float(x, x_tmp1, 64); - - bands_number = 64; - xLen = bands_number; - } - - - /* Smoothing */ - - x_tmp1[0] = x[0]; - move_float(&x_tmp1[1], &x[0], 63); - - for (i = 0; i < 63; i++) { - x[i] = 0.5 * x[i] + 0.25 * (x_tmp1[i] + x[i + 1]); - } - - x[63] = 0.5 * x[63] + 0.25 * (x_tmp1[63] + x[63]); - - /* Pre-emphasis */ - for (i = 0; i < 64; i++) { - x[i] = x[i] * sns_preemph[i]; - } - - /* Noise floor at -40dB */ - for (i = 0; i < 64; i++) { - sum += x[i]; - } - - mean = sum * 0.015625; /* 1/64 */ - - nf = mean * 1.00e-04; - nf = MAX(nf, 2.328306436538696e-10); - - for (i = 0; i < 64; i++) { - if (x[i] < nf) { - x[i] = nf; - } - } - - /* Log-domain */ - for (i = 0; i < 64; i++) { - x[i] = LC3_LOGTWO(x[i]) * 0.5; - } - - /* Downsampling */ - for (n = 0; n < 16; n++) { - if (n == 0) { - x_tmp1[0] = x[0]; - - move_float(&x_tmp1[1], &x[0], 5); - - } else if (n == 15) { - move_float(x_tmp1, &x[59], 5); - - x_tmp1[5] = x[63]; - - } else { - move_float(x_tmp1, &x[n * 4 - 1], ((n * 4 + 5 - 1) - (n * 4 - 1) + 1)); - } - - sum = 0; - for (i = 0; i < 6; i++) { - sum += x_tmp1[i] * sns_W[i]; - } - - gains_smooth[n] = sum; - sum_gains_smooth += sum; - } - - - /* Remove mean and scaling */ - mean = sum_gains_smooth / 16.0; - - for (i = 0; i < 16; i++) { - gains[i] = sns_damping * (gains_smooth[i] - mean); - } - - /* Smoothing */ - if (smooth) { - gains_smooth[0] = (gains[0] + gains[1] + gains[2]) / 3.0; - gains_smooth[1] = (gains[0] + gains[1] + gains[2] + gains[3]) / 4.0; - - for (i = 2; i < 14; i++) { - gains_smooth[i] = (gains[i - 2] + gains[i - 1] + gains[i] + gains[i + 1] + gains[i + 2]) / 5.0; - } - - gains_smooth[M - 2] = (gains[M - 4] + gains[M - 3] + gains[M - 2] + gains[M - 1]) / 4.0; - gains_smooth[M - 1] = (gains[M - 3] + gains[M - 2] + gains[M - 1]) / 3.0; - - sum = 0; - for (i = 0; i < M; i++) { - sum += gains_smooth[i]; - } - - mean = sum / (LC3_FLOAT)M; - - for (i = 0; i < M; i++) { - gains[i] = attdec_damping_factor * (gains_smooth[i] - mean); - } - } -} diff --git a/lib_lc3plus/sns_compute_scf_fx.c b/lib_lc3plus/sns_compute_scf_fx.c new file mode 100644 index 000000000..d56a1a7f8 --- /dev/null +++ b/lib_lc3plus/sns_compute_scf_fx.c @@ -0,0 +1,166 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void processSnsComputeScf_fx(Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 *scf, + Word16 scf_smoothing_enabled, Word16 attdec_damping_factor, Word8 *scratchBuffer, Word16 sns_damping + ) +{ + Dyn_Mem_Deluxe_In( + Word16 i, s, s2, nf, tmp; + Word32 L_mean, L_tmp; + Word32 *d3_fx; + Word16 *d3_fx_exp; + Word16 *d4_fx; + Word16 *scf_smooth; + ); + + UNUSED(attdec_damping_factor); + + d3_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */ + d3_fx_exp = scratchAlign(d3_fx, sizeof(*d3_fx) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + d4_fx = scratchAlign(d3_fx_exp, sizeof(*d3_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128bytes */ + scf_smooth = scratchAlign(d4_fx, sizeof(*d4_fx) * MAX_BANDS_NUMBER); /* Size = 2 * 16 */ + +/* Smoothing and Pre-emphasis */ + IF (sub(n_bands, 32) < 0) + { + L_tmp = sub(32, n_bands); + FOR (i = sub(n_bands, 1); i >= L_tmp; i--) + { + d2_fx[(i + L_tmp) * 2 + 1] = d2_fx[i]; move32(); + d2_fx[(i + L_tmp) * 2 + 0] = d2_fx[i]; move32(); + } + FOR (i = sub(L_tmp, 1); i >= 0; i--) + { + d2_fx[i * 4 + 3] = d2_fx[i]; move32(); + d2_fx[i * 4 + 2] = d2_fx[i]; move32(); + d2_fx[i * 4 + 1] = d2_fx[i]; move32(); + d2_fx[i * 4 + 0] = d2_fx[i]; move32(); + } + n_bands = 64; move16(); + } + ELSE + IF (sub(n_bands, 64) < 0) + { + L_tmp = sub(64, n_bands); + FOR (i = sub(n_bands, 1); i >= L_tmp; i--) + { + d2_fx[i + L_tmp] = d2_fx[i]; move32(); + } + FOR (i = sub(L_tmp, 1); i >= 0; i--) + { + d2_fx[i * 2 + 1] = d2_fx[i]; move32(); + d2_fx[i * 2 + 0] = d2_fx[i]; move32(); + } + n_bands = 64; move16(); + } + + L_tmp = L_add(Mpy_32_16_lc3plus(d2_fx[0], 24576), L_shr_pos(d2_fx[1], 2)); + d3_fx[0] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][0]); move32(); + d3_fx_exp[0] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][0]); move16(); + FOR (i = 1; i < n_bands - 1; i++) + { + L_tmp = L_add(L_shr_pos(d2_fx[i], 1), L_add(L_shr_pos(d2_fx[i - 1], 2), L_shr_pos(d2_fx[i + 1], 2))); + d3_fx[i] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][i]); move32(); + d3_fx_exp[i] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][i]); move16(); + } + L_tmp = L_add(Mpy_32_16_lc3plus(d2_fx[n_bands - 1], 24576), L_shr_pos(d2_fx[n_bands - 2], 2)); + d3_fx[n_bands - 1] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][n_bands - 1]); move32(); + d3_fx_exp[n_bands - 1] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][n_bands - 1]); move16(); + + /* Mean */ + s = d3_fx_exp[MAX_BANDS_NUMBER - 1]; + s2 = add(s, 6); + + L_mean = L_shr(d3_fx[0], sub(s2, d3_fx_exp[0])); + FOR (i = 1; i < MAX_BANDS_NUMBER; i++) + { + L_mean = L_add(L_mean, L_shr(d3_fx[i], sub(s2, d3_fx_exp[i]))); + } + + /* Noise floor at -40dB */ + nf = BASOP_Util_Log2_16(L_mean, s); + nf = sub(s_max(nf, -25965), 6803); + +/* Log-domain */ + FOR (i = 0; i < MAX_BANDS_NUMBER; i++) + { + d4_fx[i] = s_max(nf, BASOP_Util_Log2_16(d3_fx[i], d3_fx_exp[i])); move16(); + } + + /* Downsampling */ + L_tmp = L_mult(d4_fx[0], 8192); + L_tmp = L_mac(L_tmp, d4_fx[1], 8192); + L_tmp = L_mac(L_tmp, d4_fx[2], 8192); + L_tmp = L_mac(L_tmp, d4_fx[3], 5461); + d3_fx[0] = L_mac(L_tmp, d4_fx[4], 2731); move32(); + FOR (i = 1; i < M - 1; i++) + { + L_tmp = L_mult(d4_fx[i * 4 - 1], 2731); + L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 0], 5461); + L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 1], 8192); + L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 2], 8192); + L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 3], 5461); + d3_fx[i] = L_mac(L_tmp, d4_fx[i * 4 + 4], 2731); move32(); + } + L_tmp = L_mult(d4_fx[59], 2731); + L_tmp = L_mac(L_tmp, d4_fx[60], 5461); + L_tmp = L_mac(L_tmp, d4_fx[61], 8192); + L_tmp = L_mac(L_tmp, d4_fx[62], 8192); + d3_fx[M - 1] = L_mac(L_tmp, d4_fx[63], 8192); move32(); + +/* Remove mean and scaling */ + L_mean = L_shr_pos(d3_fx[0], 4); + FOR (i = 1; i < M; i++) + { + L_mean = L_add(L_mean, L_shr_pos(d3_fx[i], 4)); + } + + FOR (i = 0; i < M; i++) + { + scf[i] = mult_r(sns_damping, round_fx(L_shl_pos(L_sub(d3_fx[i], L_mean), 1))); + move16(); + } + + /* scale factor smoothing */ + IF (scf_smoothing_enabled) + { + scf_smooth[0] = L_shr(L_mult0(L_add(L_add(scf[0], scf[1]), scf[2]), 10923), 15); + L_mean = scf_smooth[0]; move16(); + scf_smooth[1] = L_shr(L_add(L_add(L_add(scf[0], scf[1]), scf[2]), scf[3]), 2); + L_mean = L_add(L_mean, scf_smooth[1]); + FOR (i = 2; i < M - 2; i++) + { + L_tmp = L_add(L_add(L_add(L_add(scf[i - 2], scf[i - 1]), scf[i]), scf[i + 1]), scf[i + 2]); + tmp = norm_s(L_shr(L_abs(L_tmp), 15)); + if (tmp > 0) { + tmp = sub(16, tmp); + L_tmp = L_shr(L_tmp, tmp); + } + scf_smooth[i] = L_shr(L_mult0(L_tmp, 13107), sub(16, tmp)); + L_mean = L_add(L_mean, scf_smooth[i]); + } + scf_smooth[M - 2] = L_shr(L_add(L_add(L_add(scf[M - 4], scf[M - 3]), scf[M - 2]), scf[M - 1]), 2); + L_mean = L_add(L_mean, scf_smooth[M - 2]); + scf_smooth[M - 1] = L_shr(L_mult0(L_add(L_add(scf[M - 3], scf[M - 2]), scf[M - 1]), 10923), 15); + L_mean = L_add(L_mean, scf_smooth[M - 1]); + + L_mean = L_shr(L_mean, 4); + + FOR (i = 0; i < M; i++) + { + scf[i] = mult_r(attdec_damping_factor, sub(scf_smooth[i], L_mean)); + } + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/sns_interpolate_scf.c b/lib_lc3plus/sns_interpolate_scf.c deleted file mode 100644 index 98b54909b..000000000 --- a/lib_lc3plus/sns_interpolate_scf.c +++ /dev/null @@ -1,92 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_int) -{ - LC3_INT i, n, d, n4; - LC3_FLOAT tmp[MAX_BANDS_NUMBER_PLC], ratio; - - /* Interpolation */ - - gains_int[0] = gains[0]; - gains_int[1] = gains[0]; - - for (n = 0; n <= 14; n++) { - gains_int[n * 4 + 2] = gains[n] + (gains[n + 1] - gains[n]) * 0.125; - gains_int[n * 4 + 3] = gains[n] + (gains[n + 1] - gains[n]) * 0.375; - gains_int[n * 4 + 4] = gains[n] + (gains[n + 1] - gains[n]) * 0.625; - gains_int[n * 4 + 5] = gains[n] + (gains[n + 1] - gains[n]) * 0.875; - } - - gains_int[62] = gains[15] + (gains[15] - gains[14]) * 0.125; - gains_int[63] = gains[15] + (gains[15] - gains[14]) * 0.375; - - /* For 5ms */ - - if (bands_number < 64) { - d = 64 - bands_number; - - if (d < 32) - { - i = 0; - for (n = 0; n < 2 * d; n = n + 2) { - tmp[i] = (gains_int[n] + gains_int[n + 1]) / (LC3_FLOAT)2.0; - i++; - } - - for (n = 1; n < d; n++) { - gains_int[n] = gains_int[2 * n]; - } - - for (n = 2 * d; n < 64; n++) { - gains_int[n - d] = gains_int[n]; - } - - move_float(gains_int, tmp, d); - } - else if (bands_number < 32) - { - ratio = LC3_FABS((LC3_FLOAT) ((LC3_FLOAT)1.0 - (LC3_FLOAT)32.0 / (LC3_FLOAT) bands_number)); - n4 = LC3_ROUND(ratio * (LC3_FLOAT)bands_number); - - for (i = 0; i < n4; i++) - { - tmp[i] = (gains_int[4 * i] + gains_int[4 * i + 1] + gains_int[4 * i + 2] + gains_int[4 * i + 3]) / 4.0; - } - - for (i = 0; i < bands_number - n4; i++) - { - tmp[n4 + i] = (gains_int[4 * n4 + 2 * i] + gains_int[4 * n4 + 2 * i + 1]) / 2.0; - } - - move_float(gains_int, tmp, bands_number); - } else { - assert(0 && "Unsupported number of bands!"); - } - } - - /* Inversion at encoder-side */ - - if (encoder_side == 1) { - for (n = 0; n < bands_number; n++) { - gains_int[n] = -gains_int[n]; - } - } - - /* Linear domain */ - - for (n = 0; n < bands_number; n++) { - gains_int[n] = LC3_POW(2, gains_int[n]); - } -} diff --git a/lib_lc3plus/sns_interpolate_scf_fx.c b/lib_lc3plus/sns_interpolate_scf_fx.c new file mode 100644 index 000000000..e71825d07 --- /dev/null +++ b/lib_lc3plus/sns_interpolate_scf_fx.c @@ -0,0 +1,154 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +void processSnsInterpolateScf_fx( +#ifdef ENABLE_HR_MODE + Word32 *scf_q, Word32 mdct_scf[], +#else + Word16 *scf_q, Word16 mdct_scf[], +#endif + Word16 mdct_scf_exp[], Word16 inv_scf, + Word16 n_bands, Word8 *scratchBuffer) +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In( + Word32 i, tmp2; + Word32 *scf_int; + Word32 tmp; + Word32 *scf_tmp; + ); +#else + Dyn_Mem_Deluxe_In( + Word16 i, tmp2; + Word16 *scf_int; + Word16 tmp; + Word16 *scf_tmp; + ); +#endif + +#ifdef ENABLE_HR_MODE + scf_int = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + scf_tmp = (Word32 *)scratchAlign(scf_int, 4 * MAX_BANDS_NUMBER); /* 2 * MAX_BANDS_NUMBER = 128 bytes */ +#else + scf_int = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + scf_tmp = (Word16 *)scratchAlign(scf_int, 2 * MAX_BANDS_NUMBER); /* 2 * MAX_BANDS_NUMBER = 128 bytes */ +#endif + + /* Interpolation */ + scf_int[0] = scf_q[0]; + scf_int[1] = scf_q[0]; + FOR (i = 1; i < M; i++) + { +#ifdef ENABLE_HR_MODE + tmp = L_sub(scf_q[i], scf_q[i - 1]); + tmp2 = L_shr(tmp, 2); + tmp = L_shr(tmp, 3); + scf_int[i * 4 - 2] = L_add(scf_q[i - 1], tmp); + scf_int[i * 4 - 1] = L_add(scf_int[i * 4 - 2], tmp2); + scf_int[i * 4] = L_add(scf_int[i * 4 - 1], tmp2); + scf_int[i * 4 + 1] = L_add(scf_int[i * 4], tmp2); +#else + tmp = sub(scf_q[i], scf_q[i - 1]); + tmp2 = mult_r(tmp, 8192); + tmp = mult_r(tmp, 4096); + scf_int[i * 4 - 2] = add(scf_q[i - 1], tmp); + scf_int[i * 4 - 1] = add(scf_int[i * 4 - 2], tmp2); + scf_int[i * 4] = add(scf_int[i * 4 - 1], tmp2); + scf_int[i * 4 + 1] = add(scf_int[i * 4], tmp2); +#endif + } +#ifdef ENABLE_HR_MODE + scf_int[62] = L_add(scf_int[61], tmp2); + scf_int[63] = L_add(scf_int[62], tmp2); +#else + scf_int[62] = add(scf_int[61], tmp2); + scf_int[63] = add(scf_int[62], tmp2); +#endif + + /* 8 kHz mode for 2.5 ms */ + IF (sub(n_bands, 32) < 0) + { +#ifdef ENABLE_HR_MODE + basop_memmove(scf_tmp, scf_int, 64 * sizeof(Word32)); +#else + basop_memmove(scf_tmp, scf_int, 64 * sizeof(Word16)); +#endif + tmp = sub(32, n_bands); + FOR (i = 0; i < tmp; i++) + { +#ifdef ENABLE_HR_MODE + scf_int[i] = L_add(L_shr(L_add(scf_tmp[4 * i], scf_tmp[4 * i + 1]), 2), + L_shr(L_add(scf_tmp[4 * i + 2], scf_tmp[4 * i + 3]), 2)); +#else + /* 8192 = 0.25 * 2^15 */ + scf_int[i] = add(mac_r(L_mult(scf_tmp[4 * i], 8192), scf_tmp[4 * i + 1], 8192), + mac_r(L_mult(scf_tmp[4 * i + 2], 8192), scf_tmp[4 * i + 3], 8192)); +#endif + } + + FOR (i = 0; i < n_bands - tmp; i++) + { +#ifdef ENABLE_HR_MODE + scf_int[tmp + i] = L_shr(L_add(scf_tmp[4 * tmp + 2 * i], scf_tmp[4 * tmp + 2 * i + 1]), 1); +#else + scf_int[tmp + i] = mac_r(L_mult(scf_tmp[4 * tmp + 2 * i], 16384), scf_tmp[4 * tmp + 2 * i + 1], 16384); +#endif + } + } + ELSE + /* For 5ms */ + IF (sub(n_bands, 64) < 0) + { + tmp = sub(64, n_bands); + FOR (i = 0; i < tmp; i++) + { +#ifdef ENABLE_HR_MODE + scf_int[i] = L_shr(L_add(scf_int[2 * i], scf_int[2 * i + 1]), 1); +#else + scf_int[i] = mac_r(L_mult(scf_int[2 * i], 16384), scf_int[2 * i + 1], 16384); +#endif + } + FOR (; i < n_bands; i++) + { + scf_int[i] = scf_int[tmp + i]; move16(); + } +#ifdef ENABLE_HR_MODE + move16(); // 32 bit operations have twice the complexity weight of 16 bit operations +#endif + } + + /* Inversion at encoder-side*/ + IF (inv_scf == 1) + { + FOR (i = 0; i < n_bands; i++) + { +#ifdef ENABLE_HR_MODE + scf_int[i] = L_negate(scf_int[i]); +#else + scf_int[i] = negate(scf_int[i]); +#endif + } + } + +/* Linear Domain */ + FOR (i = 0; i < n_bands; i++) + { +#ifdef ENABLE_HR_MODE + /* scf_int is in Q26, BASOP_Util_InvLog2_pos requires Q25 data */ + mdct_scf[i] = BASOP_Util_InvLog2_pos(L_shr(scf_int[i], 1), &mdct_scf_exp[i]); +#else + mdct_scf[i] = BASOP_Util_InvLog2_16(scf_int[i], &mdct_scf_exp[i]); +#endif + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/sns_quantize_scf.c b/lib_lc3plus/sns_quantize_scf.c deleted file mode 100644 index e3fa34d83..000000000 --- a/lib_lc3plus/sns_quantize_scf.c +++ /dev/null @@ -1,523 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -static void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses); -static LC3_INT find_last_indice_le(LC3_INT compare, const LC3_INT* array, LC3_INT len); -static void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len); - -void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len) -{ - LC3_INT i; - LC3_FLOAT norm1, sum; - - norm1 = 0.353553390593274; /* sqrt(2 / 16) */ - - for (i = 0; i < len; i++) { - sum = mac_loop(in, idct_lookup[i], len); - out[i] = norm1 * sum; - } -} - -static LC3_INT pvq_pulse_search(LC3_FLOAT *xabs, LC3_FLOAT *ener, LC3_FLOAT *corr, LC3_INT *y, LC3_INT start, LC3_INT end) -{ - LC3_INT i; - LC3_INT nBest; - LC3_FLOAT bestCorrSq, bestEn; - LC3_FLOAT corrSq, currCorr, currEn; - - nBest = 0; - bestCorrSq = 0.0; - bestEn = 0.0; - - *ener += 1; // Added once for the entire loop - - i = start; - - currCorr = *corr + xabs[i]; - currEn = *ener + (2 * y[i]); - - corrSq = currCorr * currCorr; - - bestEn = currEn; - bestCorrSq = corrSq; - nBest = i; - - /* Iterative max search as recommended in the spec */ - for (; i < end; i++) - { - currCorr = *corr + xabs[i]; - currEn = *ener + (2 * y[i]); - - corrSq = currCorr * currCorr; - - if ((corrSq * bestEn) > (bestCorrSq * currEn)) - { - bestEn = currEn; - bestCorrSq = corrSq; - nBest = i; - } - } - - *corr += xabs[nBest]; - *ener += (2 * y[nBest]); - - y[nBest] += 1; /* Add the selected unit pulse */ - - return nBest; -} - -static void pvq_enc_vec_normalize(LC3_FLOAT *vec, LC3_INT N) -{ - LC3_FLOAT mag = 0.0, norm_fac; - LC3_INT i; - - for (i = 0; i < N; i++) - { - mag += (vec[i] * vec[i]); - } - - norm_fac = 1.0 / LC3_SQRT(mag); - - for (i = 0; i < N; i++) - { - vec[i] = vec[i] * norm_fac; - } - - return; -} - -static void pvq_enc_search(LC3_FLOAT* x_in, LC3_INT y[4][M]) -{ - LC3_INT i, N, K, pulse_total, N_setA; - LC3_FLOAT abs_sum, projfac; - LC3_FLOAT xabs[16]; - LC3_FLOAT yy, xy; - - abs_sum = 0.0; - - /* Step 1 : Projection to pyramid N=16, K=6 */ - N = 16; - K = 6; - pulse_total = 0; - N_setA = 10; - - yy = xy = 0.0f; - - for (i = 0; i < N; i++) - { - xabs[i] = LC3_FABS(x_in[i]); - abs_sum += xabs[i]; - } - - projfac = (K - 1) / abs_sum; - - for (i = 0; i < N; i++) - { - y[3][i] = floor(xabs[i] * projfac); - - pulse_total += y[3][i]; - - yy += (y[3][i] * y[3][i]); - xy += (xabs[i] * y[3][i]); - } - - /* Step 2: Adding unit pulses up to K = 6 */ - for (; pulse_total < K; pulse_total++) - { - pvq_pulse_search(xabs, &yy, &xy, y[3], 0, N); - } - - /* Step 3: Adding unit pulses up to K = 8 */ - memcpy(y[2], y[3], sizeof(LC3_INT)*N); - K = 8; - - for (; pulse_total < K; pulse_total++) - { - pvq_pulse_search(xabs, &yy, &xy, y[2], 0, N); - } - - memcpy(y[1], y[2], sizeof(LC3_INT)*N_setA); - - /* Step 4: Remove unit pulses not belonging to set A */ - for (i = N_setA; i < N; i++) - { - y[1][i] = 0; - } - - /* Step 5: Update yy and xy terms to reflect y1 */ - yy = 0; - xy = 0; - pulse_total = 0; - - for (i = 0; i < N_setA; i++) - { - yy += (y[1][i] * y[1][i]); - xy += (xabs[i] * y[1][i]); - - pulse_total += y[1][i]; - } - - /* Step 6: Add unit pulses until K = 10 over N = 10 */ - K = 10; - for (; pulse_total < K; pulse_total++) - { - pvq_pulse_search(xabs, &yy, &xy, y[1], 0, N_setA); - } - - memcpy(y[0], y[1], sizeof(LC3_INT)*N); - - /* Step 7: Add unit pulses until K = 1 over N = 6 in set B*/ - pvq_pulse_search(xabs, &yy, &xy, y[0], N_setA, N); - - /* Step 8: Add signs to each of the 4 vectors from x */ - for (i = 0; i < N; i++) - { - if (x_in[i] < 0) - { - y[0][i] = -y[0][i]; - y[1][i] = -y[1][i]; - y[2][i] = -y[2][i]; - y[3][i] = -y[3][i]; - } - } - - return; -} - -static inline LC3_FLOAT calc_mse(LC3_FLOAT *t2rot, LC3_FLOAT *y, LC3_FLOAT gain, LC3_INT N) -{ - LC3_FLOAT mse; - LC3_INT i; - - mse = 0.0; - - for (i = 0; i < N; i++) - { - LC3_FLOAT err = (t2rot[i] - gain * y[i]); - mse += (err * err); - } - - return mse; -} - -static void sns_quant_adj_gain_shape_search(LC3_FLOAT *t2rot, LC3_INT y[4][M] , - LC3_INT *gain_idx, LC3_INT *shape_idx, LC3_FLOAT *y_norm, LC3_FLOAT *scq_gain) -{ - LC3_INT gidx, sidx; - LC3_FLOAT min_mse, mse; - LC3_INT N; - LC3_FLOAT yCur[4][16]; - LC3_INT i; - - const LC3_INT gain_levels[4] = { 2, 4, 4, 8 }; - const LC3_FLOAT *sns_vq_gains[4] = { sns_vq_reg_adj_gains_fl , sns_vq_reg_lf_adj_gains_fl , - sns_vq_near_adj_gains_fl , sns_vq_far_adj_gains_fl }; - - min_mse = -1.0; - N = 16; - - - *gain_idx = *shape_idx = 0; - - for (sidx = 0; sidx < 4; sidx++) - { - for (i = 0; i < N; i++) - { - yCur[sidx][i] = (LC3_FLOAT)y[sidx][i]; - } - - /* Step 9: Normalize the vectors */ - pvq_enc_vec_normalize(yCur[sidx], N); - - for (gidx = 0; gidx < gain_levels[sidx]; gidx++) - { - mse = calc_mse(t2rot, yCur[sidx], sns_vq_gains[sidx][gidx], N); - - if ((mse < min_mse) || (min_mse < 0)) - { - *gain_idx = gidx; - *shape_idx = sidx; - min_mse = mse; - } - } - } - - for (i = 0; i < N; i++) - { - y_norm[i] = yCur[*shape_idx][i]; - } - - *scq_gain = sns_vq_gains[*shape_idx][*gain_idx]; - - return; -} - -static void enc_push_sign(LC3_FLOAT val, LC3_UINT32 *next_sign_ind, LC3_INT *index) -{ - if (((*next_sign_ind & 0x80000000U) == 0) && (val != 0)) { - *index = 2 * (*index) + *next_sign_ind; - } - if (val < 0) { - *next_sign_ind = 1; - } - if (val > 0) { - *next_sign_ind = 0; - } - - return; -} - -static void MPVQ_enum(LC3_INT dim, LC3_INT *sns_vec, LC3_INT *index_val, LC3_INT *lead_sign_ind) -{ - LC3_UINT32 next_sign_ind; - LC3_INT k_val_acc; - LC3_INT pos; - LC3_INT index, n; - LC3_INT const *row_ptr; - - /* MPVQ-index composition loop */ - LC3_INT tmp_h_row; - LC3_INT tmp_val; - - next_sign_ind = 0x80000000U; - k_val_acc = 0; - pos = dim; - index = 0; - n = 0; - - row_ptr = (LC3_INT const *)&(pvq_enc_A[n]); - tmp_h_row = row_ptr[0]; - - for (pos--; pos >= 0; pos--) - { - tmp_val = sns_vec[pos]; - enc_push_sign(tmp_val, &next_sign_ind, &index); - - index += tmp_h_row; - k_val_acc += abs(tmp_val); - if (pos != 0) { - n += 1; /* switch row in offset table MPVQ_offsets(n, k) */ - } - row_ptr = (LC3_INT const *)&(pvq_enc_A[n]); - - tmp_h_row = row_ptr[k_val_acc]; - } - - *index_val = index; - *lead_sign_ind = next_sign_ind; - - return; -} - -static LC3_INT MSEsearch (LC3_FLOAT *scf, const LC3_FLOAT sns_CB[8][32]) -{ - LC3_FLOAT distance, mse; - LC3_INT i, n, ind; - - ind = 0; - - distance = (LC3_FLOAT) LC3_CONST_POW_2_100; - for (i = 0; i < 32; i++) { - mse = 0; - for (n = 0; n < 8; n++) { - mse += (scf[n] - sns_CB[n][i]) * (scf[n] - sns_CB[n][i]); - } - - if (mse < distance) { - distance = mse; - ind = i; - } - } - return ind; -} - -void process_snsQuantizesScf_Enc(LC3_FLOAT* env, LC3_INT* index, LC3_FLOAT* envq, Dct2 dct2structSNS) -{ - LC3_FLOAT stage2_en1_norm_sub[M]; - LC3_INT i, j; - LC3_FLOAT st1_vector[M]; - LC3_FLOAT pvq_target_pre[M]; - LC3_FLOAT pvq_target[M]; - LC3_FLOAT stage2_en1_norm_pre_sub[M]; - LC3_INT gain, shape; - LC3_FLOAT scfq_gain; - LC3_INT y[4][M]; - - /* Stage 1 split VQ */ - index[0] = MSEsearch(&env[0], sns_LFCB); /* ind_LF */ - index[1] = MSEsearch(&env[8], sns_HFCB); /* ind_HF */ - - j = 8; - for (i = 0; i < 8; i++, j++) { - st1_vector[i] = sns_LFCB[i][index[0]]; - st1_vector[j] = sns_HFCB[i][index[1]]; - } - - /* STAGE 2 */ - for (i = 0; i < 16; i++) { - pvq_target_pre[i] = env[i] - st1_vector[i]; - } - - dct2_apply(&dct2structSNS, pvq_target_pre, pvq_target); - pvq_enc_search(pvq_target, y); - sns_quant_adj_gain_shape_search(pvq_target, y, &gain, &shape, stage2_en1_norm_pre_sub, &scfq_gain); - - /* Inverse transform */ - idct_II(stage2_en1_norm_pre_sub, stage2_en1_norm_sub, M); - - index[2] = shape; - index[3] = gain; - - if (shape < 2) { - MPVQ_enum(10, y[shape], &index[5], &index[4]); - } - else { - MPVQ_enum(M, y[shape], &index[5], &index[4]); - } - - if (shape == 0) { - LC3_INT ls_ind, ind; - MPVQ_enum(6, &y[shape][10], &ind, &ls_ind); - index[6] = ind * 2 + ls_ind; - } - else if (shape == 2) { - index[6] = -1; - } - else { - index[6] = -2; - } - - for (i = 0; i < M; i++) { - envq[i] = st1_vector[i] + (stage2_en1_norm_sub[i] * scfq_gain); - } -} - -LC3_INT find_last_indice_le(LC3_INT compare, const LC3_INT* array, LC3_INT len) -{ - LC3_INT idx = 0, i = 0; - - for (i = 0; i < len; i++) { - if (compare >= array[i]) { - idx++; - } - } - - if (idx > 0) { - idx--; - } - - return idx; -} - -void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses) -{ - LC3_INT leading_sign, idx, k_delta = 0, pos; - - leading_sign = 1 - 2 * LS_ind; - - /* Decoding loop */ - - for (pos = 0; pos < m; pos++) { - if (MPVQ_ind != 0) { - /* Find last indice */ - idx = find_last_indice_le(MPVQ_ind, &pvq_enc_A[m - pos - 1][0], k + 1); - MPVQ_ind = MPVQ_ind - pvq_enc_A[m - pos - 1][idx]; - k_delta = k - idx; - } else { - pulses[pos] = leading_sign * k; - break; - } - - if (k_delta != 0) { - pulses[pos] = leading_sign * k_delta; - if ((MPVQ_ind % 2) != 0) { - leading_sign = -1; - } else { - leading_sign = 1; - } - - MPVQ_ind = floor(MPVQ_ind / 2); - k = k - k_delta; - } - } -} - -void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q) -{ - LC3_INT i, submode; - LC3_INT pulses2[6] = {0}, pulses[M] = {0}; - LC3_FLOAT st2_vector[M], st2_vector_idct[M], sum = 0; - - /* Decode first stage */ - - for (i = 0; i < 8; i++) { - scf_q[i] = sns_LFCB[i][scf_idx[0]]; - scf_q[i + 8] = sns_HFCB[i][scf_idx[1]]; - } - - /* STAGE 2 */ - /* Decode submode */ - - submode = scf_idx[2]; - - /* Decode pulses */ - - if (submode < 2) { - pvq_dec(10, 10, scf_idx[4], scf_idx[5], pulses); - - if (submode == 0) { - pvq_dec(1, 6, (scf_idx[6] % 2), floor(scf_idx[6] / 2), pulses2); - - move_int(&pulses[10], pulses2, 6); - - } else { - pulses[15] = 0; - } - } else if (submode == 2) { - pvq_dec(8, 16, scf_idx[4], scf_idx[5], pulses); - } else { - pvq_dec(6, 16, scf_idx[4], scf_idx[5], pulses); - } - - /* Normalization */ - - for (i = 0; i < M; i++) { - sum += pulses[i] * pulses[i]; - } - - sum = 1.0 / LC3_SQRT(sum); - - for (i = 0; i < M; i++) { - st2_vector[i] = pulses[i] * sum; - } - - /* Inverse transform */ - idct_II(st2_vector, st2_vector_idct, M); - - /* Gain */ - /* Add stage 1 and stage 2 */ -#ifdef CR9_SIMPLIFY_LOOP - for (i = 0; i < M; i++) { - scf_q[i] += st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]]; - } -#else - for (i = 0; i < M; i++) { - st2_vector_idct[i] = st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]]; - } - - for (i = 0; i < M; i++) { - scf_q[i] = scf_q[i] + st2_vector_idct[i]; - } -#endif -} diff --git a/lib_lc3plus/sns_quantize_scf_fx.c b/lib_lc3plus/sns_quantize_scf_fx.c new file mode 100644 index 000000000..991381285 --- /dev/null +++ b/lib_lc3plus/sns_quantize_scf_fx.c @@ -0,0 +1,834 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +static Word16 stage1_base( /* o : idx */ + const Word16 *t, /* i : target SCFs */ +#ifdef ENABLE_HR_MODE + const Word32 *cdbk, /* i : SCFs cdbk */ +#else + const Word16 *cdbk, /* i : SCFs cdbk */ +#endif + const Word16 R /* i : number of rows in codebook */ +) +{ + Counter row; + Word16 k_ptr, idx; + Word32 L_min_mse, L_mse; + Counter col; +#ifdef ENABLE_HR_MODE + Word32 err; +#else + Word16 err; +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("stage1_base", sizeof(struct { + Counter row, col; + Word16 k_ptr, idx, err; + Word32 L_min_mse, L_mse; + })); +#endif +#ifdef WMOPS + BASOP_sub_sub_start("stage1_base"); +#endif + +/* find first vector error energy for */ +/* loop probably works with saturation , but it should not occur anyway */ + L_min_mse = L_add(0, 0); /* init acc with absolute min mse sofar */ + FOR (col = 0; col < M / 2; col++) /* fixed to 8 elements */ + { +#ifdef ENABLE_HR_MODE + err = L_sub(cdbk[col], L_deposit_h(t[col])); /* cdbk max abs value is 2048 = 2.^11 , max nb col is 2^3 max + target is approx similar (2.^14/M)*2 = +/- 2048 , errmax is 4096 */ + L_min_mse = L_add(L_min_mse, Mpy_32_32_lc3plus(err, err)); +#else + err = sub(cdbk[col], t[col]); /* cdbk max abs value is 2048 = 2.^11 , max nb col is 2^3 max target is approx + similar (2.^14/M)*2 = +/- 2048 , errmax is 4096 */ + L_min_mse = L_mac0(L_min_mse, err, err); /* max L_min_mse is 8*4096*4096 =2.^(3+12+12) = 2.^27 */ +#endif + } + + idx = 0; move16(); + + k_ptr = M / 2; move16(); /* ptr init to second row */ + FOR (row = 1; row < R; row++) + { + /* loop probably works with saturation , but it should not occur anyway */ + + L_mse = L_add(L_min_mse, 0); /* init acc with min mse sofar , */ + FOR (col = 0; col < M / 2; col++) /* fixed to 8 elements */ + { +#ifdef ENABLE_HR_MODE + err = L_sub(cdbk[k_ptr++], L_deposit_h(t[col])); + L_mse = L_sub(L_mse, Mpy_32_32_lc3plus(err, err)); +#else + err = sub(cdbk[k_ptr++], t[col]); + L_mse = L_msu0(L_mse, err, + err); /* NB subtraction from best MSE error sofar in acc , saturation may not occur */ +#endif + } + + L_min_mse = L_sub(L_min_mse, L_max(L_mse, 0L)); /* ALWAYS update best MSE error sofar */ + + if (L_mse > 0L) /* if acc value still is positive a new lower error energy vector was found in this row */ + { + idx = row; move16(); /* update 1-8 bits idx */ + } + + /* this inner loop(always updating L_min_mse), (L_msu, if ) consumes AV 19, WC ~20 STL cycles , + compared to a conventional(L_mac, IF( ) ) AV 21 WC ~23 STL cycles per + loop */ + } + ASSERT(idx >= 0 && idx < R); + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + return idx; +} + +static void first_stage_split_search( +#ifdef ENABLE_HR_MODE + const Word32 *cbk_LF, const Word32 *cbk_HF, +#else + const Word16 *cbk_LF, const Word16 *cbk_HF, +#endif + const Word16 *target, + const Word16 nbCbkEntries, Word16 *idxLF, Word16 *idxHF) +{ + /* find base index for each SCF split */ + *idxLF = stage1_base(target, cbk_LF, nbCbkEntries); + *idxHF = stage1_base((&target[M / 2]), cbk_HF, nbCbkEntries); +} + +static void processDeQuantize_stage1ScfDecStage1_fx( +#ifdef ENABLE_HR_MODE + const Word32 *cbk_LF, const Word32 *cbk_HF, +#else + const Word16 *cbk_LF, const Word16 *cbk_HF, +#endif + Word16 st1_idx0, Word16 st1_idx1, +#ifdef ENABLE_HR_MODE + Word32 *st1_vector +#else + Word16 *st1_vector +#endif + ) +{ + Counter col; + Word16 offset0, offset1; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processDeQuantize_stage1ScfDecStage1_fx", sizeof(struct { + Word16 offset0, offset1; + Counter col; + })); +#endif + + offset0 = shl_pos(st1_idx0, 3); /* mult by M/2 */ + offset1 = shl_pos(st1_idx1, 3); + FOR (col = 0; col < M / 2; col++) + { + st1_vector[col] = cbk_LF[offset0++]; move16(); + st1_vector[col + 8] = cbk_HF[offset1++]; move16(); +#ifdef ENABLE_HR_MODE + move16(); + move16(); +#endif + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +void downshift_w32_arr(Word32 *w32_arr, Word16 *w16_arr, Word16 shft_val, Word32 len) +{ + Word32 i; + FOR (i = 0; i < len; i++) + { + w16_arr[i] = extract_l(L_shr_pos(w32_arr[i], shft_val)); + move16(); + } + return; +} + +void round_w32tow16_arr(Word32 *w32_arr, Word16 *w16_arr,Word32 len) +{ + Word32 i; + FOR (i = 0; i < len; i++) + { + w16_arr[i] = round_fx(w32_arr[i]); + move16(); + } + return; +} + +static void processQuantize_stage1ScfEncStage1_fx(const Word16 *target_st1, +#ifdef ENABLE_HR_MODE + Word32 *st1_vector, +#else + Word16 *st1_vector, +#endif + Word16 *st1_idx0Ptr, Word16 *st1_idx1Ptr) + +{ +#ifdef WMOPS + BASOP_sub_sub_start("processQuantize_stage1ScfEncStage1_fx"); +#endif + +#ifdef ENABLE_HR_MODE + first_stage_split_search(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27, target_st1, SCF_STAGE1_NBCDKENTRIES, + st1_idx0Ptr, st1_idx1Ptr); + + processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27, *st1_idx0Ptr, + *st1_idx1Ptr, st1_vector); +#else + first_stage_split_search(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, target_st1, SCF_STAGE1_NBCDKENTRIES, + st1_idx0Ptr, st1_idx1Ptr); + + processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, *st1_idx0Ptr, + *st1_idx1Ptr, st1_vector); +#endif + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + + return; +} + +/* gain-shape MSE search in warped SCF-residual domain, synthesis in SCF resiudal domain allows for easy weighting */ + +static void pvq_enc_find_best_submode_pre_post_fx( +#ifdef ENABLE_HR_MODE + const Word32 *target_st2, /* this target is in the linearized warped domain , same as input to PVQ search */ +#else + const Word16 *target_st2, /* this target is in the linearized warped domain , same as input to PVQ search */ +#endif + const Word16 *enc_pulses_far, Word16 *enc_pulses_near, const Word16 *enc_pulsesA, const Word16 *enc_pulsesB, + Word16 *sub_mode_ptr, Word16 *i_gain_ptr, +#ifdef ENABLE_HR_MODE + Word32 *enc_adj_glob_warped_vec, +#else + Word16 *enc_adj_glob_warped_vec, +#endif + Word8 *scratchBuffer) /* Size = 18 * M */ +{ + + Counter L_section, idx; +#ifdef ENABLE_HR_MODE + const Word32 *search_en1shape[N_SCF_SHAPES_ST2]; +#else + const Word16 *search_en1shape[N_SCF_SHAPES_ST2]; +#endif + const Word16 *search_gainTab[N_SCF_SHAPES_ST2]; + Word16 search_n_gains[N_SCF_SHAPES_ST2]; + Word32 L_mse, L_mse_min, L_idx; + Word16 * pulses_far, *pulses_near, *pulsesAB, *pulsesA; +#ifdef ENABLE_HR_MODE + Word32 * target_w, *shape_far, *shape_near, *shapeAB, *shapeA; +#else + Word16 * target_w, *shape_far, *shape_near, *shapeAB, *shapeA; +#endif +#ifdef ENABLE_HR_MODE + Word32 tmp, err; +#else + Word16 tmp, err; +#endif + Counter i; + +#ifdef DYNMEM_COUNT +#ifdef ENABLE_HR_MODE + Dyn_Mem_In("pvq_enc_find_best_submode_pre_post_fx", sizeof(struct { + Counter i, L_section, idx; + Word32 *search_en1shape[N_SCF_SHAPES_ST2]; + Word16 *search_gainTab[N_SCF_SHAPES_ST2]; + Word16 search_n_gains[N_SCF_SHAPES_ST2]; + Word32 L_mse, L_mse_min, L_idx; + Word16 *pulses_far, *pulses_near, *pulsesAB, *pulsesA; + Word32 *target_w, *shape_far, *shape_near, *shapeAB, *shapeA; + Word32 tmp, err; + })); +#else + Dyn_Mem_In("pvq_enc_find_best_submode_pre_post_fx", sizeof(struct { + Counter i, L_section, idx; + Word16 *search_en1shape[N_SCF_SHAPES_ST2]; + Word16 *search_gainTab[N_SCF_SHAPES_ST2]; + Word16 search_n_gains[N_SCF_SHAPES_ST2]; + Word32 L_mse, L_mse_min, L_idx; + Word16 *pulses_far, *pulses_near, *pulsesAB, *pulsesA; + Word16 *target_w, *shape_far, *shape_near, *shapeAB, *shapeA; + Word16 tmp, err; + })); +#endif /* ENABLE_HR_MODE */ +#endif /* DYNMEM_COUNT */ + + pulses_near = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */ + + pulsesAB = (Word16 *)scratchAlign(pulses_near, sizeof(*pulses_near) * M); /* Size = 2 * M */ + + pulsesA = (Word16 *)scratchAlign(pulsesAB, sizeof(*pulsesAB) * M); /* Size = 2 * M */ + +#ifdef ENABLE_HR_MODE + target_w = (Word32 *)scratchAlign(pulsesA, sizeof(*pulsesA) * M); /* Size = 2 * M */ + + shape_near = (Word32 *)scratchAlign(target_w, sizeof(*target_w) * M); /* Size = 4 * M */ + + shapeAB = (Word32 *)scratchAlign(shape_near, sizeof(*shape_near) * M); /* Size = 4 * M */ + + shapeA = (Word32 *)scratchAlign(shapeAB, sizeof(*shapeAB) * M); /* Size = 4 * M */ +#else + target_w = (Word16 *)scratchAlign(pulsesA, sizeof(*pulsesA) * M); /* Size = 2 * M */ + + shape_near = (Word16 *)scratchAlign(target_w, sizeof(*target_w) * M); /* Size = 2 * M */ + + shapeAB = (Word16 *)scratchAlign(shape_near, sizeof(*shape_near) * M); /* Size = 2 * M */ + + shapeA = (Word16 *)scratchAlign(shapeAB, sizeof(*shapeAB) * M); /* Size = 2 * M */ +#endif + + pulses_far = (Word16 *)scratchAlign(shapeA, sizeof(*shapeA) * M); /* Size = 2 * M */ + +#ifdef ENABLE_HR_MODE + shape_far = (Word32 *)scratchAlign(pulses_far, sizeof(*pulses_far) * M); /* Size = 2 * M */ +#else + shape_far = (Word16 *)scratchAlign(pulses_far, sizeof(*pulses_far) * M); /* Size = 2 * M */ +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("pvq_enc_find_best_submode_pre_post_fx"); +#endif + + /* construct pulse vectors and en1 normalized shape vectors */ /* use shape Q in Q14 */ + basop_memmove(pulses_far, enc_pulses_far, M * sizeof(*pulses_far)); + basop_memmove(pulses_near, enc_pulses_near, M * sizeof(*pulses_near)); + basop_memmove(target_w, target_st2, M * sizeof(*target_w)); + + pvq_dec_en1_normQ14_fx(shape_near, pulses_near, sns_Kval[2][0], M); /* near outlier mode */ + pvq_dec_en1_normQ14_fx(shape_far, pulses_far, sns_Kval[3][0], M); /* far outlier mode */ + + /* regular mode(with a split), prepare vectors of full length M */ + basop_memmove(pulsesAB, enc_pulsesA, N_SETA * sizeof(*pulsesAB)); + basop_memmove(pulsesA, enc_pulsesA, N_SETA * sizeof(*pulsesA)); + + FOR (i = N_SETA; i < M; i++) + { + pulsesAB[i] = enc_pulsesB[sub(i, N_SETA)]; move16(); + } + + IF (M > N_SETA) + { + basop_memset(&pulsesA[N_SETA], 0, (M - N_SETA) * sizeof(*pulsesA)); + } + + pvq_dec_en1_normQ14_fx(shapeAB, pulsesAB, sns_Kval[0][0], M); + /* regular AB , b_pulses = 1 ;*/ /* OPT: combine with shapeA */ + + pvq_dec_en1_normQ14_fx(shapeA, pulsesA, sns_Kval[1][0], M); + /* regular A , b_pulses = 0 */ /* OPT: M-> N_SETA */ + + /* setup search structure */ + + /* now aligned with order of j {regular=0, regular_lf=1, outlier_near=2, outlier far=3} */ + + search_en1shape[0] = shapeAB; + search_gainTab[0] = sns_gaintabPtr[0]; + search_n_gains[0] = sns_gainSz[0]; /* assumes whole bits */ + + search_en1shape[1] = shapeA; + search_gainTab[1] = sns_gaintabPtr[1]; + search_n_gains[1] = sns_gainSz[1]; /* assumes whole bits */ + + search_en1shape[2] = shape_near; + search_gainTab[2] = sns_gaintabPtr[2]; + search_n_gains[2] = sns_gainSz[2]; /*assume whole bits */ + + search_en1shape[3] = shape_far; + search_gainTab[3] = sns_gaintabPtr[3]; + search_n_gains[3] = sns_gainSz[3]; /*assume whole bits */ + + /* start actual search loop */ + + /* basic raw MSE loop, */ + L_mse_min = INT32_MAX; move32(); + L_idx = L_deposit_l(-1); /* section in low 2 bits* gain idx above */ + + FOR (L_section = 0; L_section < N_SCF_SHAPES_ST2; L_section++) + { + /* raw MSE over gain and shape */ + FOR (idx = 0; idx < search_n_gains[L_section]; idx++) + { + /* MSE ( proc_target_local[i]-adjGain[i]*en1Shape[i] ) */ + + L_mse = L_deposit_l(0); + FOR (i = 0; i < M; i++) + { +#ifdef ENABLE_HR_MODE + tmp = Mpy_32_16_lc3plus(search_en1shape[L_section][i], search_gainTab[L_section][idx]); /* Q30 + 14 - 15 = Q29 */ + err = L_sub(target_w[i], tmp); /* both in Q29 */ + L_mse = L_add(L_mse, L_shr_pos(Mpy_32_32_lc3plus(err, err), 1)); /* Q29+29-31 = Q27 */ +#else + tmp = mult_r(search_gainTab[L_section][idx], search_en1shape[L_section][i]); /* Q15+14+1-16= Q14 */ + err = sub(target_w[i], tmp); /* both in Q14 */ + L_mse = L_mac0(L_mse, err, err); /* Q14+14 = Q28 */ +#endif /* Q14+14 = Q28 */ + } + + IF (L_sub(L_mse, L_mse_min) < 0) /* OPT: always update L_mse_min) */ + { + L_mse_min = L_mse; move32(); + L_idx = L_mac0(L_section, idx, 1 << 2); /* save both section and gain idx */ + } + } /* gains */ + } /*submodes*/ + + L_section = L_and(0x3L, L_idx); /* section was stored in two lowest bits */ + ASSERT(L_section >= 0 && L_section <= 3); + *i_gain_ptr = extract_l(L_shr_pos(L_idx, 2)); /*1,2,3 bit gain */ + ASSERT(*i_gain_ptr >= 0 && *i_gain_ptr <= 7); + + /* returns a scaled and transformed vector, ___EXACTLY__ as a decoder would scale it */ + ASSERT(enc_adj_glob_warped_vec != NULL); + { + /* warp/rotate search result to SCF residual domain */ +#ifdef ENABLE_HR_MODE + idct32_32_fx(search_en1shape[L_section], target_w); +#else + idct16_fx(search_en1shape[L_section], target_w); /* fwd synthesis warping */ +#endif + /* actual synthesis gain scaling in SCF-residual domain, for easy weighting analysis */ + pvq_dec_scale_vec_fx(target_w, search_gainTab[L_section][*i_gain_ptr], enc_adj_glob_warped_vec); + } + + *sub_mode_ptr = extract_l(L_section); + move16(); /* 0,1,2,3 */ + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return; +} + +static void processQuantize_stage2ScfEncStage2_fx( +#ifdef ENABLE_HR_MODE + const Word32 *target_st2, Word32 *st2_vector, +#else + const Word16 *target_st2, Word16 *st2_vector, +#endif + Word32 *L_prm_idx, + Word16 submodes, Word8 *scratchBuffer) /* Size = 26 * M + 48 */ +{ /*func */ +#ifdef ENABLE_HR_MODE + Word32 *proc_target; +#else + Word16 *proc_target; +#endif + + Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB; + + Word16 *pulses_fin, *pulses_proj; + Word32 L_tmp; + + Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx; + + PvqEntry_fx enc_PVQ_OA, enc_PVQ_B; + Word16 submode, i_gain, submodeMSB, submodeLSB; + Word32 * L_search_corr, *L_search_en; +#ifdef ENABLE_HR_MODE + Word16 * proc_target_lp; +#endif + +#ifdef DYNMEM_COUNT +#ifdef ENABLE_HR_MODE + Dyn_Mem_In("processQuantize_stage2ScfEncStage2_fx", sizeof(struct { + Word32 *proc_target; + Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB; + Word16 *pulses_fin, *pulses_proj; + Word32 L_tmp; + Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx; + PvqEntry_fx enc_PVQ_OA, enc_PVQ_B; + Word16 submode, i_gain, submodeMSB, submodeLSB; + Word32 * L_search_corr, *L_search_en; + Word16 * proc_target_lp; + })); +#else + Dyn_Mem_In("processQuantize_stage2ScfEncStage2_fx", sizeof(struct { + Word16 *proc_target; + Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB; + Word16 *pulses_fin, *pulses_proj; + Word32 L_tmp; + Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx; + PvqEntry_fx enc_PVQ_OA, enc_PVQ_B; + Word16 submode, i_gain, submodeMSB, submodeLSB; + Word32 * L_search_corr, *L_search_en; + })); +#endif /* ENABLE_HR_MODE */ +#endif /* DYNMEM_COUNT */ + +#ifdef ENABLE_HR_MODE + buffer_pvq_enc_find_best_submode_pre_post_fx = (Word8 *) scratchAlign(scratchBuffer, 0); + proc_target = (Word32 *) scratchAlign(buffer_pvq_enc_find_best_submode_pre_post_fx, sizeof(*buffer_pvq_enc_find_best_submode_pre_post_fx) * 28 * M); +#else + buffer_pvq_enc_find_best_submode_pre_post_fx = scratchAlign(scratchBuffer, 0); /* Size = 18 * M */ + proc_target = + (Word16 *)scratchAlign(buffer_pvq_enc_find_best_submode_pre_post_fx, + sizeof(*buffer_pvq_enc_find_best_submode_pre_post_fx) * 18 * M); /* Size = 2 * M */ +#endif + + enc_pulses_near = (Word16 *)scratchAlign(proc_target, sizeof(*proc_target) * M); /* Size = 2 * M */ + enc_pulsesA = (Word16 *)scratchAlign(enc_pulses_near, sizeof(*enc_pulses_near) * M); /* Size = 2 * N_SETA */ + enc_pulsesB = (Word16 *)scratchAlign(enc_pulsesA, sizeof(*enc_pulsesA) * N_SETA); /* Size = 2 * N_SETB */ + pulses_fin = (Word16 *)scratchAlign(enc_pulsesB, sizeof(*enc_pulsesB) * N_SETB); /* Size = 2 * N_SCF_SHAPES_ST2 */ + pulses_proj = + (Word16 *)scratchAlign(pulses_fin, sizeof(*pulses_fin) * N_SCF_SHAPES_ST2); /* Size = 2 * N_SCF_SHAPES_ST2 */ + L_search_corr = + (Word32 *)scratchAlign(pulses_proj, sizeof(*pulses_proj) * N_SCF_SHAPES_ST2); /* Size = 4 * N_SCF_SHAPES_ST2 */ + L_search_en = (Word32 *)scratchAlign(L_search_corr, + sizeof(*L_search_corr) * N_SCF_SHAPES_ST2); /* Size = 4 * N_SCF_SHAPES_ST2 */ + enc_pulses_far = (Word16 *)scratchAlign(L_search_en, sizeof(*L_search_en) * N_SCF_SHAPES_ST2); /* Size = 2 * M */ + +#ifdef ENABLE_HR_MODE + proc_target_lp = (Word16 *)buffer_pvq_enc_find_best_submode_pre_post_fx; /* size = 2*M */ +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("processQuantize_stage2ScfEncStage2_fx"); +#endif + + /* fixed setup for a given bitrate of 38 , no moves needed */ + /* k_far = sns_Kval[3][0]; */ + /* k_near = sns_Kval[2][0]; */ + /* kA = sns_Kval[1][0]; */ /* regular, regular_lf */ + /* kB is always 1 */ + + /* NB these search indecese do not correspond exactly to specification shape_index j */ + + pulses_fin[0] = sns_Kval[3][0]; /* far 6 */ + pulses_fin[1] = sns_Kval[2][0]; /* near 8 */ + pulses_fin[2] = sns_Kval[1][0]; /* section A 10 */ + pulses_fin[3] = sns_Kval[0][1]; /* section B 1 */ + + pulses_proj[0] = sns_Kval[3][0]; + pulses_proj[1] = 0; + pulses_proj[2] = 0; + pulses_proj[3] = 0; + + /* pre_process */ +#ifdef ENABLE_HR_MODE + dct32_fx(target_st2, proc_target); /* enc analysis */ + downshift_w32_arr(proc_target, proc_target_lp, 16, M); + + /* get the initial four integer shape candidate vectors, no normalization at this stage */ + pvq_enc_search_fx(proc_target_lp, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB, L_search_corr, + L_search_en, pulses_fin, pulses_proj, M, N_SETA); +#else + Word32 target_st2_32[M]; Word32 proc_target_32[M]; int i; + + FOR (i = 0; i < M; i++) + { + target_st2_32[i] = L_shl_pos(target_st2[i], 16); + } + + dct32_fx(target_st2_32, proc_target_32); /* enc analysis */ + + downshift_w32_arr(proc_target_32, proc_target, 16, M); + + /* get the initial four integer shape candidate vectors, no normalization at this stage */ + pvq_enc_search_fx(proc_target, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB, L_search_corr, + L_search_en, pulses_fin, pulses_proj, M, N_SETA); +#endif + + /* scale with gains a after a unit energy fwd transform */ + /* apply transform to each candidate shape vector priot to gain-shape search loop */ + submode = submodes; /* used as input solely to debug/unit test a specific shape mode */ + + /*target should be in a linearized residual domain target */ + /* search pre, synthesis post*/ + pvq_enc_find_best_submode_pre_post_fx(proc_target, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB, + &submode, &i_gain, st2_vector, + buffer_pvq_enc_find_best_submode_pre_post_fx); /* Q14 tr out */ + + /* send parameters to multiplexor as a series/vector of Long Words */ + /* 0 : 0..3 submode */ + /* 1 : 0..7 gain_ind */ + /* 2 : 0..1 LeadSign ind */ + /* 3 : 25 bit MPVQ index outl_near or A part */ + /* 4 : 3.7 to 21 bits MPVQ index B part OR -2 */ + + L_prm_idx[0] = L_deposit_l(submode); /* complete submode fwd'ed to ari_codec as 0,1,2,3 */ + + submodeMSB = shr_pos(submode, 1); /* LSB of submode , sent as main submode bit */ + submodeLSB = s_and(submode, 0x1); /* LSB of submode */ /* sent via shape param */ + + /* gain, shape indicese , incl. calls to MPVQ indexing */ + IF (submodeMSB == 0) + { /* regular modes:: j=0(reg=AB) or 1(reg_lf A) */ /* regular mode, with two or one shape indices */ + + /* assume regular_lf part , shape_j == 1 */ + enc_PVQ_OA = + mpvq_index_fx(enc_pulsesA, N_SETA, sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */ + L_prm_idx[2] = L_deposit_l(enc_PVQ_OA.lead_sign_ind); /*LS set A */ + + ASSERT(enc_PVQ_OA.size == (UWord32)sns_MPVQ_Sz[submode][0]); + L_prm_idx[3] = L_add(0L, (Word32)enc_PVQ_OA.index); /* MPVQ shape index set A fractional */ + + /* section B always have low indexing dynamics and is combined into one joint single index */ + IF (submodeLSB == 0) + { /* regular AB , shape_j == 0*/ + L_prm_idx[1] = L_deposit_l(i_gain); /* full established gain idx fwd'ed */ /* 2 possible values */ + enc_PVQ_B = mpvq_index_fx(enc_pulsesB, N_SETB, 1); + ASSERT(((enc_PVQ_B.size << 1)) == + (sns_MPVQ_Sz[submode][1])); /* two lowest indeces indicate all_zero B section */ + + L_tmp = L_shl_pos((Word32)enc_PVQ_B.index, 1); /* 2*section B MPVQ index */ + L_prm_idx[4] = L_add(L_tmp, enc_PVQ_B.lead_sign_ind); move32(); /* add joint section B and LS index */ + + ASSERT(L_prm_idx[4] >= 0 && L_prm_idx[4] < (Word32)sns_MPVQ_Sz[submode][0]); + } + ELSE + { + L_prm_idx[1] = L_deposit_l(i_gain); + /* MSBs of established gain idx */ /* 2 or 4 total possible values */ + L_prm_idx[4] = L_deposit_l(-2); + } + } + ELSE + { + /* outlier modes shape_j= 2(near, LSB=0) or 3(far, LSB=1) */ + + IF (submodeLSB == 0) + { + L_prm_idx[1] = L_deposit_l(i_gain); /* established gain idx */ /* 4 possible values */ + enc_PVQ_OA = mpvq_index_fx(enc_pulses_near, M, + sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */ + ASSERT(enc_PVQ_OA.size == sns_MPVQ_Sz[submode][0]); + L_prm_idx[3] = L_add(0L, enc_PVQ_OA.index); /* MPVQ index fractional bits */ + L_prm_idx[4] = L_deposit_l(-1); /* no gain LSBs */ + } + ELSE + { + L_prm_idx[1] = L_deposit_l(i_gain); /* established gain idx MSBs */ /* all 4 or 8 possible values */ + enc_PVQ_OA = mpvq_index_fx(enc_pulses_far, M, + sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */ + ASSERT(enc_PVQ_OA.size == sns_MPVQ_Sz[submode][0]); + L_prm_idx[3] = L_add(0L, enc_PVQ_OA.index); /* MPVQ index fractional bits */ + L_prm_idx[4] = L_deposit_l(-2); /* */ + } + L_prm_idx[2] = L_deposit_l(enc_PVQ_OA.lead_sign_ind); /* LS shape single bit */ + } + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return; +} + +static Word16 scfdec_stage2_fx( /* o: ber flag */ + const Word32 *L_prm_idx, /* set to -1 if not used */ +#ifdef ENABLE_HR_MODE + Word32 * st2_vector, /*o: Q14 */ +#else + Word16 * st2_vector, /*o: Q14 */ +#endif + Word8 * scratchBuffer) +{ + /* MPVQ deindexing, gainscaling transform and transform */ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In( + Word16 submode; + Word16 submodeLSB, submodeMSB; + Word16 gValQ13; + Word16 idxB; + Word16 maxK; + Word16 BER_dec; + Word16 *dec_pulses; + Word32 *dec_en1_vec; + Word32 *dec_adj_glob_vec; + ); +#else + Dyn_Mem_Deluxe_In( + Word16 submode; + Word16 submodeLSB, submodeMSB; + Word16 gValQ13; + Word16 idxB; + Word16 maxK; + Word16 BER_dec; + Word16 *dec_pulses; + Word16 *dec_en1_vec; + Word16 *dec_adj_glob_vec; + ); +#endif + +#ifdef WMOPS + BASOP_sub_sub_start("scfdec_stage2_fx"); +#endif + + dec_pulses = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M = 32 bytes */ +#ifdef ENABLE_HR_MODE + dec_en1_vec = (Word32 *)scratchAlign(dec_pulses, sizeof(*dec_pulses) * M); /* Size = 2 * M = 32 bytes */ + dec_adj_glob_vec = (Word32 *)scratchAlign(dec_en1_vec, sizeof(*dec_en1_vec) * M); /* Size = 2 * M = 32 bytes */ +#else + dec_en1_vec = (Word16 *)scratchAlign(dec_pulses, sizeof(*dec_pulses) * M); /* Size = 2 * M = 32 bytes */ + dec_adj_glob_vec = (Word16 *)scratchAlign(dec_en1_vec, sizeof(*dec_en1_vec) * M); /* Size = 2 * M = 32 bytes */ +#endif + + /* get submode */ + submode = extract_l(L_prm_idx[0]); /* 0..3 */ + + submodeLSB = s_and(submode, 0x1); + submodeMSB = shr_pos(submode, 1); + + /* get initial adjustment gain vector for regular, outl_near */ + ASSERT(L_prm_idx[1] >= 0 && L_prm_idx[1] < sns_gainSz[submode]); + gValQ13 = sns_gaintabPtr[submode][L_prm_idx[1]]; + ASSERT(gValQ13 >= 0); + + /* gain, shape indices, incl.calls to MPVQ deindexing */ + IF (submodeMSB != 0) + { + /* outlier_near or outlier_far mode decoding */ + maxK = sns_Kval[submode][0]; move16(); + BER_dec = pvq_dec_deidx_fx(dec_pulses, maxK, M, extract_l(L_prm_idx[2]), (UWord32)L_prm_idx[3]); + } + ELSE + { /* regular mode, with potentially two shape indices */ + + maxK = sns_Kval[submode][0]; move16(); + BER_dec = pvq_dec_deidx_fx(dec_pulses, maxK, N_SETA, extract_l(L_prm_idx[2]), (UWord32)L_prm_idx[3]); + + IF (submodeLSB == 0) + { + idxB = extract_l(L_prm_idx[4]); /* 0..11 */ + ASSERT(idxB >= 0 && idxB < (Word16)sns_MPVQ_Sz[0][1]); + BER_dec |= pvq_dec_deidx_fx(&(dec_pulses[N_SETA]), sns_Kval[submode][1], N_SETB, s_and(idxB, 0x1), + (UWord32)L_deposit_l(shr_pos(idxB, 1))); + /* maxK does not need to be increased as set B is not stacked */ + } + ELSE + { /* LSB gain bit already parsed */ + ASSERT(L_prm_idx[4] < 0); + basop_memset(&dec_pulses[N_SETA], 0, (N_SETB) * sizeof(*dec_pulses)); + } + } + + /* normalize decoded integer vector , exactly as on encoder side !! */ + pvq_dec_en1_normQ14_fx(dec_en1_vec, dec_pulses, maxK, M); + +#ifdef ENABLE_HR_MODE + idct32_32_fx(dec_en1_vec, dec_adj_glob_vec); +#else + idct16_fx(dec_en1_vec, dec_adj_glob_vec); /* fwd warping in unscaled domain */ +#endif + + /* scaling aligend with encoder search */ + pvq_dec_scale_vec_fx(dec_adj_glob_vec, gValQ13, st2_vector); + +#ifdef WMOPS + BASOP_sub_sub_end(); +#endif + Dyn_Mem_Deluxe_Out(); + return BER_dec; +} + +void processSnsQuantizeScfEncoder_fx(Word16 scf[], /* i: input scf M */ + Word32 *L_prm_idx, /* o: indeces . negative == unused */ +#ifdef ENABLE_HR_MODE + Word32 *scf_q, /* o: quantized scf M */ +#else + Word16 *scf_q, /* o: quantized scf M */ +#endif + Word8 * scratchBuffer) /* Size = 28 * M + 52 */ +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In( + Word32 *target_st2; + Word16 *st1_idx; /* stage 1 indices */ + Word8 * buffer_processQuantize_stage2ScfEncStage2_fx; + Counter col; + ); +#else + Dyn_Mem_Deluxe_In( + Word16 *target_st2; + Word16 *st1_idx; /* stage 1 indices */ + Word8 * buffer_processQuantize_stage2ScfEncStage2_fx; + Counter col; + ); +#endif + +#ifdef ENABLE_HR_MODE + target_st2 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */ +#else + target_st2 = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */ +#endif + st1_idx = (Word16 *)scratchAlign(target_st2, sizeof(*target_st2) * M); /* Size = 2 * 2 */ + buffer_processQuantize_stage2ScfEncStage2_fx = (Word8 *)scratchAlign(st1_idx, sizeof(*st1_idx) * M); + /* Size = 26 * M + 48 */ + + /* TBD needs update */ + + /* 1st stage trained VQ */ + processQuantize_stage1ScfEncStage1_fx(scf, scf_q, &st1_idx[0], &st1_idx[1]); + L_prm_idx[0] = L_deposit_l(st1_idx[0]); + L_prm_idx[1] = L_deposit_l(st1_idx[1]); + +/* 2nd stage PVQ-based SCF quantizer */ + FOR (col = 0; col < M; col++) + { +#ifdef ENABLE_HR_MODE + target_st2[col] = L_sub(L_deposit_h(scf[col]), scf_q[col]); +#else + target_st2[col] = sub(scf[col], scf_q[col]); +#endif + } + + processQuantize_stage2ScfEncStage2_fx(target_st2, scf_q, &L_prm_idx[2], VQMODES26, /* 0xF means all submodes */ + buffer_processQuantize_stage2ScfEncStage2_fx); /* PVQ in stage 2 */ + Dyn_Mem_Deluxe_Out(); +} + +Word16 processSnsQuantizeScfDecoder_fx( /* o: BER flag */ + Word32 *L_prm_idx, /* i: indeces */ +#ifdef ENABLE_HR_MODE + Word32 scf_q[], +#else + Word16 scf_q[], +#endif + Word8 *scratchBuffer) /* o: M */ +{ + Dyn_Mem_Deluxe_In( + Word16 BER_flag; + ); + + /* Decode First Stage */ +#ifdef ENABLE_HR_MODE + processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27, + extract_l(L_prm_idx[0]), extract_l(L_prm_idx[1]), scf_q); +#else + processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, + extract_l(L_prm_idx[0]), extract_l(L_prm_idx[1]), scf_q); +#endif + + /* Decode Second Stage */ + BER_flag = scfdec_stage2_fx(&(L_prm_idx[2]), scf_q, scratchBuffer); + + Dyn_Mem_Deluxe_Out(); + return BER_flag; +} + diff --git a/lib_lc3plus/structs.h b/lib_lc3plus/structs.h deleted file mode 100644 index 59425744e..000000000 --- a/lib_lc3plus/structs.h +++ /dev/null @@ -1,208 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#ifndef STRUCTS_H -#define STRUCTS_H - -#include "options.h" -#include "wmc_auto.h" -#include "defines.h" -#include "fft/iisfft.h" - -typedef struct { - LC3_FLOAT r; /* real part */ - LC3_FLOAT i; /* imaginary part */ -} Complex; - -typedef struct { - LC3_INT length; - void *handle; -} Fft; - -typedef struct { - LC3_INT length; - Fft fft; -} Dct2; - -typedef struct { - LC3_INT length; - Fft fft; -} Dct3; - -typedef struct { - LC3_INT length; - Complex *twid1; - Complex *twid2; - Fft fft; -} Dct4; - -typedef struct { - LC3_INT length; - LC3_INT leading_zeros; - LC3_INT mem_length; - const LC3_FLOAT *window; - LC3_FLOAT *mem; - Dct4 dct; -} Mdct; - -typedef struct { - uint32_t ac_low_fl; - uint32_t ac_range_fl; - int BER_detect; - - LC3_INT32 pc_c_bp; - LC3_INT32 pc_c_bp_side; - LC3_INT32 pc_bytes; - LC3_INT32 pc_b_left; - LC3_INT32 pc_b_right; - LC3_INT32 pc_enc; - LC3_INT32 pc_bfi; - LC3_INT32 pc_bbi; - LC3_INT32 pc_be_bp_left; - LC3_INT32 pc_be_bp_right; - LC3_INT32 pc_return; - LC3_INT16 pc_inv_bin; -} Decoder_State_fl; - -typedef struct { - LC3_INT bp; - LC3_INT low; - LC3_INT range; - LC3_INT cache; - LC3_INT carry; - LC3_INT carry_count; - uint8_t *ptr; - LC3_INT *bp_side; - LC3_INT *mask_side; -} Encoder_State_fl; - -typedef struct { - LC3_INT nbLostCmpt; - LC3_INT prevBfi; - LC3_INT prevprevBfi; - LC3_FLOAT q_d[MAX_LEN]; - LC3_FLOAT q_d_prev[MAX_LEN]; -} PlcSetup; - - -typedef struct { - LC3_FLOAT cum_alpha; - LC3_INT seed; -} PlcNsSetup; - -typedef struct { - LC3_INT32 seed; - LC3_INT32 ns_nbLostCmpt_pc; - LC3_FLOAT *q_old_res; - LC3_FLOAT prev_gg; -} pcState; - -typedef struct { - LC3_INT len; - LC3_INT sign; - LC3_FLOAT* table; -} Cfft; - -typedef struct T_IIS_FFT { - IIS_FFT_DIR sign; - LC3_INT32 len; - LC3_FLOAT* buffer; - LC3_FLOAT* sine_table; - Iisfft iisfft; - Cfft cfft; -} IIS_FFT; - -typedef struct T_IIS_FFT* HANDLE_IIS_FFT; - -typedef struct { - Fft PhEcu_Fft; /*no counterpart in BASOP */ - Fft PhEcu_Ifft; /*no counterpart in BASOP */ - - - LC3_FLOAT PhECU_f0hzLtpBin; /* BASOP Word16 PhECU_f0hzLtpBinQ7 */ - LC3_FLOAT PhECU_norm_corr; /* BASOP Word16 norm_corrQ15 */ - - LC3_FLOAT *PhECU_oold_grp_shape; /* BASOP Word16 PhECU_oold_grp_shape_fx[MAX_LGW]; */ - LC3_FLOAT *PhECU_old_grp_shape; /* BASOP Word16 PhECU_old_grp_shape_fx[MAX_LGW] ; */ - - LC3_FLOAT PhECU_L_oold_xfp_w_E; /* BASOP Word32 PhECU_L_oold_xfp_w_E_fx;*/ - LC3_FLOAT PhECU_L_old_xfp_w_E; /* BASOP Word32 PhECU_L_old_xfp_w_E_fx; */ - - LC3_INT32 PhECU_Lprot ; /* BASOP Word16 PhECU_Lprot_fx;*/ - - LC3_FLOAT *PhECU_xfp; - Complex *PhECU_X_sav_m; - LC3_INT32 *PhECU_plocs; /* BASOP Word16 *PhECU_plocs; */ /* MAX_PLOCS */ - LC3_FLOAT *PhECU_f0est; /*BASOP Word32 *PhECU_f0est;*/ - - LC3_FLOAT *PhECU_mag_chg_1st; /* BASOP Word16 PhECU_mag_chg_1st[MAX_LGW];*/ - LC3_FLOAT *PhECU_Xavg; /* BASOP Word16 PhECU_Xavg[MAX_LGW] ; */ - - LC3_FLOAT PhECU_beta_mute; /* BASOP Word16 PhECU_beta_mute*/ - - LC3_INT16 PhECU_seed; /* BASOP Word16 PhECU_seed_fx;*/ - - LC3_INT32 PhECU_LDWIN_OLAP; /* BASOP Word16 PhECU_LDWIN_OLAP; */ - LC3_INT32 PhECU_t_adv; /* BASOP Word16 t_adv; */ - - LC3_INT32 PhECU_short_flag_prev; - LC3_INT32 PhECU_time_offs; - LC3_INT32 PhECU_num_plocs; - HANDLE_IIS_FFT handle_fft_phaseecu; - HANDLE_IIS_FFT handle_ifft_phaseecu; -#ifdef CR8_A_PLC_FADEOUT_TUNING - LC3_INT16 PhECU_nonpure_tone_flag; /* BASOP Word16 PhECU_nonpure_tone_flag*/ -#endif - -} PlcPhEcuSetup; - -typedef struct { - LC3_INT16 seed; - LC3_FLOAT gain_c; - LC3_INT32 lpcorder; - LC3_FLOAT A[M+1]; - LC3_INT32 fract; - LC3_INT32 lagw_bw; - LC3_FLOAT preemphFac; - LC3_FLOAT *harmonicBuf; - LC3_FLOAT synthHist[M]; -} PlcTdcSetup; - -typedef struct { - LC3_FLOAT *pcmbufHist; - LC3_INT32 max_len_pcm_plc; - PlcTdcSetup PlcTdcSetup; - LC3_FLOAT stabFac; - LC3_FLOAT cum_fading_slow; - LC3_FLOAT cum_fading_fast; - LC3_FLOAT cum_fflcAtten; - LC3_FLOAT scf_q_old[M]; - LC3_FLOAT scf_q_old_old[M]; - PlcPhEcuSetup PlcPhEcuSetup; - -#ifdef CR8_A_PLC_FADEOUT_TUNING - LC3_INT16 longterm_counter_plcTdc; -#ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - LC3_INT16 longterm_counter_plcPhaseEcu; -#endif - LC3_INT16 longterm_counter_plcNsAdv; - LC3_INT16 longterm_analysis_counter_max; /* Maximum longterm frames number */ - LC3_INT16 longterm_analysis_counter_max_bytebuffer; /* Same as above but reduced for circular bit-buffer */ - LC3_INT32 *plc_longterm_advc_tdc; - LC3_INT32 *plc_longterm_advc_ns; - LC3_UINT8 plc_fadeout_type; - LC3_UINT8 plc_fadeout_type_first; - LC3_INT16 overall_counter; - LC3_INT8 longterm_counter_byte_position; - LC3_INT8 longterm_counter_bit_position; -#endif -} PlcAdvSetup; - -#endif diff --git a/lib_lc3plus/tinywavein_c.h b/lib_lc3plus/tinywavein_c.h new file mode 100644 index 000000000..32789e314 --- /dev/null +++ b/lib_lc3plus/tinywavein_c.h @@ -0,0 +1,603 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef __TINYWAVEIN_C_H__ +#define __TINYWAVEIN_C_H__ + +/*#define SUPPORT_BWF*/ + +#include +#include +#include + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || defined(__arm__) || \ + defined(__aarch64__) +#define __TWI_LE /* _T_iny _W_ave _I_n _L_ittle _E_ndian */ +#endif + +#if defined(__POWERPC__) +#define __TWI_BE /* _T_iny _W_ave _I_n _B_ig _E_ndian */ +#endif + +#if !defined(__TWI_LE) && !defined(__TWI_BE) +#error unknown processor +#endif + +#define __TWI_SUCCESS (0) +#define __TWI_ERROR (-1) + +#ifdef SUPPORT_BWF +typedef struct +{ + float loudnessVal; + float loudnessRange; + float maxTruePeakLevel; + float maxMomentaryLoudnes; + float maxShortTermLoudness; +} WAVEIN_LOUDNESSINFO; +#endif + +typedef struct __tinyWaveInHandle +{ + FILE * theFile; + fpos_t dataChunkPos; + unsigned int position; + unsigned int length; + unsigned int bps; +#ifdef SUPPORT_BWF + WAVEIN_LOUDNESSINFO *loudnessInfo; +#endif +} __tinyWaveInHandle, WAVEFILEIN; + +typedef struct +{ + short compressionCode; + short numberOfChannels; + unsigned int sampleRate; + unsigned int averageBytesPerSecond; + short blockAlign; + short bitsPerSample; + /* short extraFormatBytes ; */ +} SWavInfo; + +#ifdef SUPPORT_BWF +typedef struct +{ + unsigned char description[256]; + unsigned char originator[32]; + unsigned char originatorReference[32]; + unsigned char originatorDate[10]; /* ASCII: <> */ + unsigned char originationTime[8]; /* ASCII: <> */ + unsigned int timeReferenceLow; + unsigned int timeReferenceHigh; + unsigned short version; + unsigned char UMID[64]; /* Binary Bytes of SMPTE UMID */ + + signed short loudnessVal; + signed short loudnessRange; + signed short maxTruePeakLevel; + signed short maxMomentaryLoudnes; + signed short maxShortTermLoudness; + + unsigned char Reserved[180]; + + unsigned char codingHistory; /* ASCII: <> */ +} SBwfWav; +#endif + +typedef struct +{ + char chunkID[4]; + unsigned int chunkSize; + /* long dataOffset ; */ /* never used */ +} SChunk; + +/* local wrapper, always returns correct endian */ +static size_t fread_LE(void *ptr, size_t size, size_t nmemb, FILE *stream); + +#ifdef __TWI_BE +static short BigEndian16(short v); +static int BigEndian32(int v); +#endif + +/*! + * \brief Read header from a WAVEfile. Host endianess is handled accordingly. + * \fp filepointer of type FILE*. + * \wavinfo SWavInfo struct where the decoded header info is stored into. + * \return 0 on success and non-zero on failure. + * + */ +static WAVEFILEIN *OpenWav(const char *filename, unsigned int *samplerate, short *channels, unsigned int *samplesInFile, + short *bps) +{ + WAVEFILEIN *self; + + SChunk fmt_chunk, data_chunk; + int offset; + unsigned int tmpSize; + char tmpFormat[4]; + SWavInfo wavinfo = {0, 0, 0, 0, 0, 0}; + + self = (WAVEFILEIN *)calloc(1, sizeof(WAVEFILEIN)); + if (!self) + goto bail; /* return NULL; */ + + if (!filename) + goto bail; + if (!samplerate) + goto bail; + if (!channels) + goto bail; + if (!samplesInFile) + goto bail; + if (!bps) + goto bail; + + self->theFile = fopen(filename, "rb"); + if (!self->theFile) + goto bail; + + /* read RIFF-chunk */ + if (fread(tmpFormat, 1, 4, self->theFile) != 4) + { + goto bail; + } + + if (strncmp("RIFF", tmpFormat, 4)) + { + goto bail; + } + + /* Read RIFF size. Ignored. */ + fread_LE(&tmpSize, 4, 1, self->theFile); + + /* read WAVE-chunk */ + if (fread(tmpFormat, 1, 4, self->theFile) != 4) + { + goto bail; + } + + if (strncmp("WAVE", tmpFormat, 4)) + { + goto bail; + } + + /* read format/bext-chunk */ + if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4) + { + goto bail; + } + +#ifdef SUPPORT_BWF + /* test for bext-chunk */ + if (!strncmp("bext", fmt_chunk.chunkID, 4)) + { + /*unsigned int i;*/ + unsigned int bextSize = 0; + + if (fread_LE(&bextSize, 1, 4, self->theFile) != 4) + { + goto bail; + } + + self->loudnessInfo = (WAVEIN_LOUDNESSINFO *)calloc(1, sizeof(WAVEIN_LOUDNESSINFO)); + + if (bextSize >= 602) + { /* minimum size bext-data, w/o 'CodingHistory' */ + int i; + signed short readBuf = 0; + signed int nulbuf = 0; + + /* first skip all descriptive data */ + for (i = 0; i < 412; i++) + { + if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1) + { + goto bail; + } + bextSize -= 1; + } + /* second, read loudness data */ + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->loudnessVal = (float)readBuf * 0.01f; + + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->loudnessRange = (float)readBuf * 0.01f; + + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->maxTruePeakLevel = (float)readBuf * 0.01f; + + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->maxMomentaryLoudnes = (float)readBuf * 0.01f; + + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->maxShortTermLoudness = (float)readBuf * 0.01f; + + /* skip reserved data */ + for (i = 0; i < 180; i++) + { + if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1) + { + goto bail; + } + bextSize -= 1; + } + } + + /* skip remaining data */ + while (bextSize) + { + int nulbuf; + if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1) + { + goto bail; + } + bextSize -= 1; + } + + /* read next chunk header */ + if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4) + { + goto bail; + } + } +#endif + + /* skip some potential chunks up to fmt chunk */ + + while (strncmp("fmt ", fmt_chunk.chunkID, 4) != 0) + { + unsigned int chunkSize = 0; + + if (fread_LE(&chunkSize, 1, 4, self->theFile) != 4) + { + goto bail; + } + + /* skip chunk data */ + while (chunkSize) + { + int nulbuf; + if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1) + { + goto bail; + } + chunkSize -= 1; + } + + /* read next chunk header */ + if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4) + { + goto bail; + } + } + + /* go on with fmt-chunk */ + if (strncmp("fmt ", fmt_chunk.chunkID, 4)) + { + goto bail; + } + + if (fread_LE(&fmt_chunk.chunkSize, 4, 1, self->theFile) != 1) + { /* should be 16 for PCM-format (uncompressed) */ + goto bail; + } + + + /* read info */ + fread_LE(&(wavinfo.compressionCode), 2, 1, self->theFile); + fread_LE(&(wavinfo.numberOfChannels), 2, 1, self->theFile); + fread_LE(&(wavinfo.sampleRate), 4, 1, self->theFile); + fread_LE(&(wavinfo.averageBytesPerSecond), 4, 1, self->theFile); + fread_LE(&(wavinfo.blockAlign), 2, 1, self->theFile); + fread_LE(&(wavinfo.bitsPerSample), 2, 1, self->theFile); + + if (wavinfo.compressionCode == -2) + { + fseek(self->theFile, 8, SEEK_CUR); // skip channel mask + fread_LE(&(wavinfo.compressionCode), 2, 1, self->theFile); // part of GUID + fseek(self->theFile, 14, SEEK_CUR); // skip rest of GUID + offset = fmt_chunk.chunkSize - 40; + } + else + offset = fmt_chunk.chunkSize - 16; + + if (wavinfo.compressionCode == 0x01) + { + if ((wavinfo.bitsPerSample != 16) && (wavinfo.bitsPerSample != 24) && (wavinfo.bitsPerSample != 32)) + /* we do only support 16,24 and 32 bit PCM audio */ + goto bail; + } + else + { + /* if(wavinfo.bitsPerSample != 32) */ + printf("compressioncode: %02x\n", wavinfo.compressionCode); + puts("Error! We only support 16,24 and 32 bit PCM audio"); + exit(1); + goto bail; + } + + /* Skip rest of fmt header if any. */ + for (; offset > 0; offset--) + { + fread(&tmpSize, 1, 1, self->theFile); + } + + do + { + + /* Read data chunk ID */ + if (fread(data_chunk.chunkID, 1, 4, self->theFile) != 4) + { + goto bail; + } + + /* Read chunk length. */ + + if (fread_LE(&offset, 4, 1, self->theFile) != 1) + { + goto bail; + } + + /* Check for data chunk signature. */ + if (strncmp("data", data_chunk.chunkID, 4) == 0) + { + data_chunk.chunkSize = offset; + break; + } + + /* unused 1 byte present, if size is odd */ + /* see https://www.daubnet.com/en/file-format-riff */ + if (offset % 2) + { + offset++; + } + + /* Jump over non data chunk. */ + for (; offset > 0; offset--) + { + fread(&tmpSize, 1, 1, self->theFile); + } + + } while (!feof(self->theFile)); + + /* success so far */ + *samplerate = wavinfo.sampleRate; + *channels = wavinfo.numberOfChannels; + *samplesInFile = data_chunk.chunkSize / wavinfo.numberOfChannels; + *samplesInFile /= ((wavinfo.bitsPerSample + 7) / 8); + *bps = wavinfo.bitsPerSample; + + self->position = 0; + self->bps = wavinfo.bitsPerSample; + self->length = *samplesInFile * wavinfo.numberOfChannels; + + fgetpos(self->theFile, &self->dataChunkPos); + + return self; + +bail: + free(self); + return NULL; +} + +#ifdef SUPPORT_BWF +static void ReadBWF(WAVEFILEIN *self, WAVEIN_LOUDNESSINFO **wavInLoudness) +{ + *wavInLoudness = self->loudnessInfo; +} +#endif + +static int __ReadSample16(WAVEFILEIN *self, int *sample) +{ + size_t cnt; + short v = 0; + + cnt = fread(&v, 2, 1, self->theFile); + + if (cnt != 1) + { + return __TWI_ERROR; + } + + self->position += 1; + +#ifdef __TWI_BE + v = BigEndian16(v); +#endif + *sample = v; + return __TWI_SUCCESS; +} + +static int __ReadSample24(WAVEFILEIN *self, int *sample) +{ + size_t cnt; + int v = 0; + + cnt = fread(&v, 3, 1, self->theFile); + + if (cnt != 1) + { + return __TWI_ERROR; + } + + self->position += 1; + +#ifdef __TWI_BE + v = BigEndian32(v); +#endif + + if (v >= 0x800000) + { + v |= 0xff000000; + } + + *sample = v; + + return __TWI_SUCCESS; +} + +static int __ReadSample32(WAVEFILEIN *self, int *sample) +{ + size_t cnt; + int v = 0; + + cnt = fread(&v, 4, 1, self->theFile); + + if (cnt != 1) + { + return __TWI_ERROR; + } + + self->position += 1; + +#ifdef __TWI_BE + v = BigEndian32(v); +#endif + + *sample = v >> 8; + + return __TWI_SUCCESS; +} + +static int __ReadSampleInternal(WAVEFILEIN *self, int *sample, int scale) +{ + int err; + + if (!self) + { + return __TWI_ERROR; + } + + switch (scale) + { + + case 16: err = __ReadSample16(self, sample); break; + + case 24: err = __ReadSample24(self, sample); break; + + case 32: err = __ReadSample32(self, sample); break; + + default: err = __TWI_ERROR; break; + } + + return err; +} + +/* this function returns normalized values in the range +8388607..-8388608 */ +static int ReadWavInt(WAVEFILEIN *self, int sampleBuffer[], unsigned int nSamplesToRead, unsigned int *nSamplesRead) +{ + unsigned int i; + int err = __TWI_SUCCESS; + *nSamplesRead = 0; + + if (!sampleBuffer) + { + return __TWI_ERROR; + } + + /* check if we have enough samples left, if not, + set nSamplesToRead to number of samples left. */ + if (self->position + nSamplesToRead > self->length) + { + nSamplesToRead = self->length - self->position; + } + + for (i = 0; i < nSamplesToRead; i++) + { + + int tmp; + err = __ReadSampleInternal(self, &tmp, self->bps); + if (err != __TWI_SUCCESS) + { + return err; + } + sampleBuffer[i] = tmp; + *nSamplesRead += 1; + } + + return __TWI_SUCCESS; +} + +static int CloseWavIn(WAVEFILEIN *self) +{ + if (self) + { + if (self->theFile) + { + fclose(self->theFile); + } + } + free(self); + + return __TWI_SUCCESS; +} +/* +static int ResetWavIn(WAVEFILEIN* self) +{ + if (self) { + if (self->theFile) { + fsetpos(self->theFile, &self->dataChunkPos); + self->position = 0; + } + } + return __TWI_SUCCESS; +} +*/ +/*------------- local subs ----------------*/ + +static size_t fread_LE(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ +#ifdef __TWI_LE + return fread(ptr, size, nmemb, stream); +#endif +#ifdef __TWI_BE + + unsigned char x[sizeof(int)]; + unsigned char *y = (unsigned char *)ptr; + int i; + int len; + + len = fread(x, size, nmemb, stream); + + for (i = 0; i < size * nmemb; i++) + { + *y++ = x[size * nmemb - i - 1]; + } + + return len; +#endif +} + +#ifdef __TWI_BE +static short BigEndian16(short v) +{ + short a = (v & 0x0ff); + short b = (v & 0x0ff00) >> 8; + + return a << 8 | b; +} + +static int BigEndian32(int v) +{ + int a = (v & 0x0ff); + int b = (v & 0x0ff00) >> 8; + int c = (v & 0x0ff0000) >> 16; + int d = (v & 0xff000000) >> 24; + + return a << 24 | b << 16 | c << 8 | d; +} +#endif + +#endif /* __TINYWAVEIN_C_H__ */ diff --git a/lib_lc3plus/tinywaveout_c.h b/lib_lc3plus/tinywaveout_c.h new file mode 100644 index 000000000..672254270 --- /dev/null +++ b/lib_lc3plus/tinywaveout_c.h @@ -0,0 +1,889 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef __TINYWAVEOUT_C_H__ +#define __TINYWAVEOUT_C_H__ + +/*#define TWO_SUPPORT_BWF*/ + +#include +#include +#include +#include +#ifdef TWO_SUPPORT_BWF +#include +#endif + +/***** Interface *********************************************************/ + +#ifndef TWO_UINT64 + #if !(defined(WIN32)) + #include + #define TWO_UINT64 uint64_t + #else + #define TWO_UINT64 unsigned __int64 + #endif +#endif + +typedef struct WAVEFILEOUT WAVEFILEOUT; +#ifdef TWO_SUPPORT_BWF +typedef struct WAVEOUT_LOUDNESSINFO WAVEOUT_LOUDNESSINFO; +#endif + +#define __TWO_SUCCESS (0) +#define __TWO_ERROR (-1) + +static WAVEFILEOUT* CreateWav( + const char *fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps + ); + +#ifdef TWO_SUPPORT_BWF +static WAVEFILEOUT* CreateWavBWF( + const char *fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps, + const WAVEOUT_LOUDNESSINFO *hBwfData + ); +#endif + +/* this function expects values in the 16 bit range +32767..-32768 */ +static int WriteWavShort( + WAVEFILEOUT* self, + short sampleBuffer[], + unsigned int nSamples + ); + +/* this function expects values in the 24 bit range +8388607..-8388608 */ +static int WriteWavLong( + WAVEFILEOUT* self, + int sampleBuffer[], + unsigned int nSamples + ); + +/* this function expects normalized values in the range +-1.0f */ +static int WriteWavFloat( + WAVEFILEOUT* self, + float sampleBuffer[], + unsigned int nSamples + ); + +static int CloseWav(WAVEFILEOUT* self); +#ifdef TWO_SUPPORT_BWF +static int CloseWavBWF(WAVEFILEOUT* self, WAVEOUT_LOUDNESSINFO bextData); +#endif + +/***** Implementation *********************************************************/ + +#if defined (__i386__) || defined (_M_IX86) || defined (_M_X64) || defined (__x86_64__) || defined (__arm__) || defined (__xtensa__) || defined (__aarch64__) || defined (__EMSCRIPTEN__) +#define __TWO_LE /* _T_iny _W_ave _O_ut _L_ittle _E_ndian */ +#endif + +#if defined (__POWERPC__) +#define __TWO_BE /* _T_iny _W_ave _O_ut _B_ig _E_ndian */ +#endif + +#if defined (__sparc__) +#define __TWO_BE /* _T_iny _W_ave _O_ut _B_ig _E_ndian */ +#endif + +#if ! defined (__TWO_LE) && ! defined (__TWO_BE) +#error unknown processor +#endif + +/*--- local types/structs ----------------------------------*/ + +#if defined(_MSC_VER) + #pragma pack(push, 1) +#else + #pragma pack(1) +#endif + + +#ifdef TWO_SUPPORT_BWF +struct WAVEOUT_LOUDNESSINFO { + float loudnessVal; + float loudnessRange; + float maxTruePeakLevel; + float maxMomentaryLoudnes; + float maxShortTermLoudness; +}; +#endif + + +typedef struct __tinyWaveOutHeader +{ + unsigned int riffType; /* 'RIFF/RF64' */ + unsigned int riffSize; /* file size/-1 */ + unsigned int waveType; /* 'WAVE' */ +} __tinyWaveOutHeader; + +typedef struct __tinyWaveOutDs64Chunk +{ + unsigned int formatType; /* = 'JUNK/ds64' */ + unsigned int formatSize; /* size info */ + TWO_UINT64 riffSize64; + TWO_UINT64 dataSize64; + TWO_UINT64 sampleCount64; + unsigned int tableLength; /* optional tables, always 0 for tinywaveout */ + /* here: optional tables */ +} __tinyWaveOutDs64Chunk; + +#ifdef TWO_SUPPORT_BWF +typedef struct __tinyWaveOutBextChunk +{ + unsigned int formatType; /* = 'bext' */ + unsigned int formatSize; /* size info */ + + unsigned char description[256]; + unsigned char originator[32]; + unsigned char originatorReference[32]; + unsigned char originatorDate[10]; /* ASCII: <> */ + unsigned char originationTime[8]; /* ASCII: <> */ + unsigned int timeReferenceLow; + unsigned int timeReferenceHigh; + unsigned short version; + unsigned char UMID[64]; /* Binary Bytes of SMPTE UMID */ + + signed short loudnessVal; + signed short loudnessRange; + signed short maxTruePeakLevel; + signed short maxMomentaryLoudnes; + signed short maxShortTermLoudness; + + unsigned char Reserved[180]; + + unsigned char codingHistory; /* ASCII: <> - undefined length! */ + /* for variable length, mve this out of this struct */ +} __tinyWaveOutBextChunk; +#endif + +typedef struct __tinyWaveOutFmtChunk +{ + unsigned int formatType; + unsigned int formatSize; + + unsigned short formatTag; + unsigned short numChannels; + unsigned int sampleRate; + unsigned int bytesPerSecond; + unsigned short blockAlignment; + unsigned short bitsPerSample; + + /* wav fmt ext hdr here */ +} __tinyWaveOutFmtChunk; + +typedef struct __tinyWaveOutDataChunk +{ + unsigned int dataType; + unsigned int dataSize; + +} __tinyWaveOutDataChunk; + + +struct WAVEFILEOUT { + /* for reasons of memory alignment, have 64 bit data types first */ + TWO_UINT64 dataSize; + TWO_UINT64 dataSizeLimit; /* maximum size for data chunk for 4 GB files */ + TWO_UINT64 dataSizeLimit64; /* maximum size for data chunk for 2^64 B addressable files */ + TWO_UINT64 clipCount; + FILE* theFile; + unsigned int junkChunkOffset; + unsigned int fmtChunkOffset; +#ifdef TWO_SUPPORT_BWF + unsigned int bextChunkOffset; +#endif + unsigned int dataChunkOffset; + unsigned int bps; + + /* only needed for RF64: */ + unsigned int blockAlign; /* only needed for close() of ds64 chunk */ +}; + + +/*--- local protos --------------------------------------------------*/ +static __inline unsigned int BigEndian32(char, char, char, char); +static __inline unsigned int LittleEndian32(unsigned int); +static __inline unsigned int LittleEndian32s(int); +static __inline short LittleEndian16(short); +static __inline TWO_UINT64 LittleEndian64(TWO_UINT64); +#ifdef TWO_SUPPORT_BWF +static unsigned int EncodeLoudness(float); +#endif +static __inline int __dataSizeChk( WAVEFILEOUT* self, int newbytes ); + +#if defined(_MSC_VER) + #pragma pack(pop) +#else + #pragma pack() +#endif + + +#ifdef TWO_SUPPORT_BWF +static void setDefaultLoudness(WAVEOUT_LOUDNESSINFO *x) +{ + x->loudnessVal = 1.0f; + x->loudnessRange = 2.0f; + x->maxTruePeakLevel = 3.0f; + x->maxMomentaryLoudnes = 4.0f; + x->maxShortTermLoudness = 5.0f; +} +#endif + +static WAVEFILEOUT* __CreateWavInternal( + const char *fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps +#ifdef TWO_SUPPORT_BWF + , + const WAVEOUT_LOUDNESSINFO *hBwfData +#endif + ) +{ + WAVEFILEOUT* self = NULL; + __tinyWaveOutHeader whdr; + __tinyWaveOutDs64Chunk ds64ch; +#ifdef TWO_SUPPORT_BWF + __tinyWaveOutBextChunk wbextch; +#endif + __tinyWaveOutFmtChunk wfch; + __tinyWaveOutDataChunk wdch; + unsigned int blockAlignment = 0; + unsigned int ByteCnt = 0; /* Byte counter for fwrite */ + + /* pseudo use to avoid unused symbols */ + (void)WriteWavShort; + (void)WriteWavLong; + (void)WriteWavFloat; +#ifdef TWI_SUPPORT_BWF + (void)CreateWavBWF; + (void)CloseWavBWF; + (void)setDefaultLoudness; +#endif + + /* param check */ + if (!fileName) goto bail; + if (sampleRate == 0) goto bail; + if (sampleRate > 768000) goto bail; + if (numChannels == 0) goto bail; + if (numChannels > 64) goto bail; + if (bps != 16 && bps != 24 && bps != 32) goto bail; + + self = (WAVEFILEOUT*)calloc(1, sizeof(WAVEFILEOUT)); + if (!self) goto bail; /* return NULL; */ + + self->theFile = fopen(fileName, "wb+"); + if (!self->theFile) goto bail; + + /* WAV-Header */ + whdr.riffType = BigEndian32('R','I','F','F'); + whdr.riffSize = LittleEndian32(0xffffffff); /* set to maximum, if fseek() doesn't work later */ + whdr.waveType = BigEndian32('W','A','V','E'); + /* write to file */ + ByteCnt = 0; + ByteCnt += fwrite(&whdr, 1, sizeof(whdr), self->theFile); + + /* ds64/JUNK-Chunk */ + ds64ch.formatType = BigEndian32('J','U','N','K'); + ds64ch.formatSize = LittleEndian32(sizeof(__tinyWaveOutDs64Chunk) - 8); + ds64ch.riffSize64 = (TWO_UINT64) -1; + ds64ch.dataSize64 = (TWO_UINT64) -1; + ds64ch.sampleCount64 = (TWO_UINT64) -1; + ds64ch.tableLength = 0; + self->junkChunkOffset = ByteCnt; + ByteCnt += fwrite(&ds64ch, 1, sizeof(ds64ch), self->theFile); + +#ifdef TWO_SUPPORT_BWF + /* BEXT-Chunk */ + if (hBwfData) { + memset(&wbextch, 0, sizeof(__tinyWaveOutBextChunk)); + wbextch.formatType = BigEndian32('b','e','x','t'); + wbextch.formatSize = LittleEndian32(sizeof(__tinyWaveOutBextChunk) - 8); + wbextch.version = 0x0002; + wbextch.loudnessVal = EncodeLoudness(hBwfData->loudnessVal); + wbextch.loudnessRange = EncodeLoudness(hBwfData->loudnessRange); + wbextch.maxTruePeakLevel = EncodeLoudness(hBwfData->maxTruePeakLevel); + wbextch.maxMomentaryLoudnes = EncodeLoudness(hBwfData->maxMomentaryLoudnes); + wbextch.maxShortTermLoudness = EncodeLoudness(hBwfData->maxShortTermLoudness); + /* t.b.d.: more values */ + + /* write to file */ + self->bextChunkOffset = ByteCnt; + ByteCnt += fwrite(&wbextch, 1, sizeof(wbextch), self->theFile); + } +#endif + + /* FMT-Chunk */ + wfch.formatType = BigEndian32('f','m','t',' '); + wfch.formatSize = LittleEndian32(16); + switch (bps) { + case 16: + case 24: + wfch.formatTag = LittleEndian16(0x0001); /* WAVE_FORMAT_PCM */ + break; + case 32: + wfch.formatTag = LittleEndian16(0x0003); /* WAVE_FORMAT_IEEE_FLOAT */ + break; + default: + goto bail; + } + self->bps = bps; + wfch.bitsPerSample = LittleEndian16(bps); + wfch.numChannels = LittleEndian16(numChannels); + blockAlignment = numChannels * (bps >> 3); + wfch.blockAlignment = LittleEndian16(blockAlignment); + wfch.sampleRate = LittleEndian32(sampleRate); + wfch.bytesPerSecond = LittleEndian32(sampleRate * blockAlignment); + /* tbd: wavfmt ext hdr here */ + /* write to file */ + self->fmtChunkOffset = ByteCnt; + ByteCnt += fwrite(&wfch, 1, sizeof(wfch), self->theFile); + + /* DATA-Chunk */ + self->dataChunkOffset = ByteCnt; + wdch.dataType = BigEndian32('d','a','t','a'); + wdch.dataSize = LittleEndian32(0xffffffff - ByteCnt); /* yet unknown. set to maximum of 4 GB file */ + /* write to file */ + ByteCnt += fwrite(&wdch, 1, sizeof(wdch), self->theFile); + + self->dataSize = 0; + + /* self->dataSizeLimit = 0x7fffffff - ByteCnt; */ /* maximum size for data chunk for 2 GB files */ + self->dataSizeLimit = 0xffffffff - ByteCnt; /* maximum size for data chunk for 4 GB files */ + self->dataSizeLimit64 = 0xffffffffffffffff - ByteCnt; /* maximum size for data chunk for 64 bit addressable files */ + + self->clipCount = 0; + self->blockAlign = blockAlignment; + + return self; + + bail: + if ( NULL != self) { + free(self); + } + + return NULL; +} + +static WAVEFILEOUT* CreateWav( + const char* fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps + ) +{ +#ifdef TWO_SUPPORT_BWF + return __CreateWavInternal(fileName, sampleRate, numChannels, bps, NULL); +#else + return __CreateWavInternal(fileName, sampleRate, numChannels, bps); +#endif +} + +#ifdef TWO_SUPPORT_BWF +static WAVEFILEOUT* CreateWavBWF( + const char *fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps, + const WAVEOUT_LOUDNESSINFO *hBwfData + ) +{ + return __CreateWavInternal(fileName, sampleRate, numChannels, bps, hBwfData); +} +#endif + +#define MAX_PCM16 (+32767) +#define MIN_PCM16 (-32768) +static __inline int CLIP_PCM16(int sample, TWO_UINT64* clipcount) +{ + int tmp = sample; + + if (sample >= MAX_PCM16) { + tmp = MAX_PCM16; + (*clipcount)++; + } else { + if (sample <= MIN_PCM16) { + tmp = MIN_PCM16; + (*clipcount)++; + } + } + + return tmp; +} + +#define MAX_PCM24 (+8388607) +#define MIN_PCM24 (-8388608) +static __inline int CLIP_PCM24(int sample, TWO_UINT64* clipcount) +{ + int tmp = sample; + + if (sample >= MAX_PCM24) { + tmp = MAX_PCM24; + (*clipcount)++; + } else { + if (sample <= MIN_PCM24) { + tmp = MIN_PCM24; + (*clipcount)++; + } + } + + return tmp; +} + +#define MAX_FLOAT32 (+1.0f) +#define MIN_FLOAT32 (-1.0f) +static __inline float CLIP_FLOAT32(float sample, TWO_UINT64* clipcount) +{ + float tmp = sample; + + if (sample >= MAX_FLOAT32) { + tmp = MAX_FLOAT32; + (*clipcount)++; + } else { + if (sample <= MIN_FLOAT32) { + tmp = MIN_FLOAT32; + (*clipcount)++; + } + } + + return tmp; +} + + + +static int __WriteSample16( + WAVEFILEOUT* self, + int sample, + int scale + ) +{ + size_t cnt; + short v; + + if ((scale - 16) > 0) + sample = sample >> (scale - 16); + else + sample = (int) ((uint32_t) sample << (16 - scale)); + + v = (short)CLIP_PCM16(sample, &(self->clipCount)); +#ifdef __TWO_BE + v = LittleEndian16(v); +#endif + + cnt = fwrite(&v, sizeof(short), 1, self->theFile); + + if (cnt == 1) { + self->dataSize += 2; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + + +static int __WriteSample24( + WAVEFILEOUT* self, + int sample, + int scale + ) +{ + size_t cnt; + int v; + + if ((scale - 24) > 0) + sample = sample >> (scale - 24); + else + sample = (int) (((unsigned int)sample) << (24 - scale)); + + v = (int)CLIP_PCM24(sample, &(self->clipCount)); +#ifdef __TWO_BE + v = LittleEndian32s(v); +#endif + cnt = fwrite(&v, 3, 1, self->theFile); + + if (cnt == 1) { + self->dataSize += 3; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + + +static int __WriteSample32( + WAVEFILEOUT* self, + float sample + ) +{ + size_t cnt; + union fl_int { + float v_float; + int v_int; + }; + union fl_int v; + +#if CLIP_FLOAT + v.v_float = CLIP_FLOAT32(sample, &(self->clipCount)); +#else + v.v_float = sample; + if((sample > 1.0f) || (sample <-1.0f)) + self->clipCount++; +#endif + +#ifdef __TWO_BE + v.v_int = LittleEndian32s(v.v_int); +#endif + cnt = fwrite(&v, 4, 1, self->theFile); + + if (cnt == 1) { + self->dataSize += 4; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + + +static int __WriteSampleInt( + WAVEFILEOUT* self, + int sample, + int scale + ) +{ + int err; + + if (!self) return __TWO_ERROR; + + + switch (self->bps) { + + case 16: + err = __WriteSample16(self, sample, scale); + break; + + case 24: + err = __WriteSample24(self, sample, scale); + break; + + default: + err = __TWO_ERROR; + break; + } + + return err; +} + + +/* this function expects values in the 16 bit range +-32767/8 */ +static int WriteWavShort( + WAVEFILEOUT* self, + short sampleBuffer[], + unsigned int nSamples + ) +{ + unsigned long i; + int err = __TWO_SUCCESS; + + if (!self) return __TWO_ERROR; + if (!sampleBuffer) return __TWO_ERROR; + if (__dataSizeChk(self, nSamples * sizeof(short))) return __TWO_ERROR; + + for (i=0; i< nSamples; i++) { + if (self->bps == 32) + { + err = __WriteSample32(self, sampleBuffer[i] / 32768.0f); + } + else + { + err = __WriteSampleInt(self, (int)sampleBuffer[i], 16); + } + if (err != __TWO_SUCCESS) return err; + } + + return __TWO_SUCCESS; +} + + +/* this function expects values in the 24 bit range +-8388607/8 */ +static int WriteWavLong( + WAVEFILEOUT* self, + int sampleBuffer[], + unsigned int nSamples + ) +{ + unsigned long i; + int err = __TWO_SUCCESS; + + if (!self) return __TWO_ERROR; + if (!sampleBuffer) return __TWO_ERROR; + if (__dataSizeChk(self, nSamples * sizeof(int))) return __TWO_ERROR; + + for (i = 0; i < nSamples; i++) { + if (self->bps == 32) + { + err = __WriteSample32(self, sampleBuffer[i] / 8388608.0f); + } + else + { + err = __WriteSampleInt(self, sampleBuffer[i], 24); + } + if (err != __TWO_SUCCESS) return err; + } + + return __TWO_SUCCESS; +} + + +/* this function expects normalized values in the range +-1.0 */ +#define MAX_FL (+2.0f * 8388608.0f ) +#define MIN_FL (-2.0f * 8388608.0f ) +#define CLIP_FL(x) ( ((x) >= MAX_FL) ? MAX_FL : (((x) <= MIN_FL) ? MIN_FL : (x)) ) +static int WriteWavFloat( + WAVEFILEOUT* self, + float sampleBuffer[], + unsigned int nSamples + ) +{ + unsigned int i; + int err = __TWO_SUCCESS; + + if (!self) return __TWO_ERROR; + if (!sampleBuffer) return __TWO_ERROR; + if (__dataSizeChk(self, nSamples * sizeof(float))) return __TWO_ERROR; + + for (i=0; ibps == 32) + { + err = __WriteSample32(self, sampleBuffer[i]); + } + else + { + float tmp = CLIP_FL(sampleBuffer[i] * 8388608.0f); /* CLIP_FL is just to avoid an INT overrun before the actual cast to int, real clipping and counting is done below */ + err = __WriteSampleInt(self, (int) tmp, 24); + } + if (err != __TWO_SUCCESS) return err; + } + + return __TWO_SUCCESS; +} + + +static int CloseWav(WAVEFILEOUT* self) +{ + unsigned int riffSize_le = 0; + unsigned int dataSize_le = 0; + TWO_UINT64 riffSize64 = 0; + TWO_UINT64 dataSize64 = 0; + TWO_UINT64 sampleCount64 = 0; /* nr of samples in the WAVE sense: 1 sample are all pcm samples of all channels of one time slice */ + int mustWriteRF64 = 0; + + if (!self) return __TWO_ERROR; + + /* check for 4 GB (switch to RF64) */ + if ( self->dataSize > self->dataSizeLimit ) { + /* when we exceed 4 GB: switch from std wave header to RF64 header */ + mustWriteRF64 = 1; + } + + /* calc header values */ + if (mustWriteRF64 == 0) { + /* write padding byte if dataSize is uneven */ + int pad = 0; + if (self->dataSize % 2 > 0) { + char tmp= 0x00; + fwrite(&tmp, sizeof(char), 1, self->theFile); + pad = 1; + } + riffSize_le = LittleEndian32(self->dataChunkOffset - 8 + 8 + (unsigned int)self->dataSize + pad); /* sizeof(hdr) - (8 bytes of riff chunk header) + (8 bytes data chunk header) + sizeof(raw-pcm-data) + padding Byte */ + dataSize_le = LittleEndian32((unsigned int)self->dataSize); + } else { + riffSize_le = 0xffffffff; + dataSize_le = 0xffffffff; + riffSize64 = LittleEndian64( self->dataSize + (TWO_UINT64)self->dataChunkOffset ); + dataSize64 = LittleEndian64( self->dataSize ); + sampleCount64 = LittleEndian64( self->dataSize / (TWO_UINT64)self->blockAlign ); + } + + /* now overwrite length/size values in header with the actual/real ones */ + if (mustWriteRF64 == 0) { + /* riffsize32 */ + fseek(self->theFile, 4, SEEK_SET); + fwrite(&riffSize_le, sizeof(riffSize_le), 1, self->theFile); + /* datasize32 */ + fseek(self->theFile, self->dataChunkOffset + 4, SEEK_SET); + fwrite(&dataSize_le, sizeof(dataSize_le), 1, self->theFile); + } else { + unsigned int rf64sig = BigEndian32('R','F','6','4'); + unsigned int ds64sig = BigEndian32('d','s','6','4'); + + /* replace RIFF->RF64 */ + fseek(self->theFile, 0, SEEK_SET); + fwrite(&rf64sig, sizeof(rf64sig), 1, self->theFile); + + /* riffsize32 */ + fseek(self->theFile, 4, SEEK_SET); + fwrite(&riffSize_le, sizeof(riffSize_le), 1, self->theFile); + + /* replace JUNK->ds64 */ + fseek(self->theFile, self->junkChunkOffset, SEEK_SET); + fwrite(&ds64sig, sizeof(ds64sig), 1, self->theFile); + + /* riffSize64, dataSize64, sampleCount64 */ + fseek(self->theFile, self->junkChunkOffset + 8, SEEK_SET); + fwrite(&riffSize64, sizeof(riffSize64), 1, self->theFile); + fwrite(&dataSize64, sizeof(dataSize64), 1, self->theFile); + fwrite(&sampleCount64, sizeof(sampleCount64), 1, self->theFile); + + /* datasize32 */ + fseek(self->theFile, self->dataChunkOffset + 4, SEEK_SET); + fwrite(&dataSize_le, sizeof(dataSize_le), 1, self->theFile); + } + + fclose(self->theFile); + free(self); + + return __TWO_SUCCESS; +} + +#ifdef TWO_SUPPORT_BWF +static int CloseWavBWF( + WAVEFILEOUT* self, + WAVEOUT_LOUDNESSINFO bextData + ) +{ + int wordData; + + if (!self) return __TWO_ERROR; + + if (self->bextChunkOffset) { + /* Offset for Loudness Data in bext-chunk: 8: Chunk-Header, 412:prev.Data */ + fseek(self->theFile, self->bextChunkOffset+8+412, SEEK_SET); + + wordData = LittleEndian32(EncodeLoudness(bextData.loudnessVal)); + fwrite(&wordData, 2, 1, self->theFile); + + wordData = LittleEndian32(EncodeLoudness(bextData.loudnessRange)); + fwrite(&wordData, 2, 1, self->theFile); + + wordData = LittleEndian32(EncodeLoudness(bextData.maxTruePeakLevel)); + fwrite(&wordData, 2, 1, self->theFile); + + wordData = LittleEndian32(EncodeLoudness(bextData.maxMomentaryLoudnes)); + fwrite(&wordData, 2, 1, self->theFile); + + wordData = LittleEndian32(EncodeLoudness(bextData.maxShortTermLoudness)); + fwrite(&wordData, 2, 1, self->theFile); + } + + return CloseWav(self); +} +#endif + +/*------------- local subs ----------------*/ + +static __inline unsigned int BigEndian32(char a, char b, char c, char d) +{ +#ifdef __TWO_LE + return + (unsigned int) d << 24 | + (unsigned int) c << 16 | + (unsigned int) b << 8 | + (unsigned int) a ; +#else + return + (unsigned int) a << 24 | + (unsigned int) b << 16 | + (unsigned int) c << 8 | + (unsigned int) d ; +#endif +} + + +static __inline unsigned int LittleEndian32(unsigned int v) +{ +#ifdef __TWO_LE + return v; +#else + return + (v & 0x000000FF) << 24 | + (v & 0x0000FF00) << 8 | + (v & 0x00FF0000) >> 8 | + (v & 0xFF000000) >> 24 ; +#endif +} + + +/* signed version of the above */ +static __inline unsigned int LittleEndian32s(int v) +{ +#ifdef __TWO_LE + return v; +#else + return + (v & 0x000000FF) << 24 | + (v & 0x0000FF00) << 8 | + (v & 0x00FF0000) >> 8 | + (v & 0xFF000000) >> 24 ; +#endif +} + + +static __inline short LittleEndian16(short v) +{ +#ifdef __TWO_LE + return v; +#else + return ((v << 8) & 0xFF00) | ((v >> 8) & 0x00FF); +#endif +} + +static __inline TWO_UINT64 LittleEndian64(TWO_UINT64 v) +{ +#ifdef __TWO_LE + return v; +#else + return + (v & 0x00000000000000FF) << 56 | + (v & 0x000000000000FF00) << 40 | + (v & 0x0000000000FF0000) << 24 | + (v & 0x00000000FF000000) << 8 | + (v & 0x000000FF00000000) >> 8 | + (v & 0x0000FF0000000000) >> 24 | + (v & 0x00FF000000000000) >> 40 | + (v & 0xFF00000000000000) >> 56 ; +#endif +} + +#ifdef TWO_SUPPORT_BWF +static unsigned int EncodeLoudness(float x) +{ + int s = (x>0)-(x<0); + return (int)( x*100.0f + s*0.5f ); +} +#endif + +static __inline int __dataSizeChk( WAVEFILEOUT* self, int newbytes ) +{ + if (!self) return __TWO_ERROR; + + if ( (self->dataSize + ((TWO_UINT64)newbytes) ) > self->dataSizeLimit64 ) { + return __TWO_ERROR; + } + + return __TWO_SUCCESS; +} + +#endif /* __TINYWAVEOUT_C_H__ */ + + + diff --git a/lib_lc3plus/tns_coder.c b/lib_lc3plus/tns_coder.c deleted file mode 100644 index 6870ba1e1..000000000 --- a/lib_lc3plus/tns_coder.c +++ /dev/null @@ -1,393 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -static void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen); -static void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len); -static void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len); - -void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen) -{ - LC3_INT32 m; - - - for (m = 0; m <= lag; m++) { - /* Calculate correlation */ - out[m] = mac_loop(in, &in[m], (inLen - m)); - } -} - -void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLOAT* error, LC3_INT len) -{ - LC3_INT t, i, j; - LC3_FLOAT g, v, sum, buf_tmp[10]; - - g = r[1] / r[0]; - out_lev[0] = g; - - v = (1.0 - g * g) * r[0]; - rc_unq[0] = -g; - - for (t = 1; t < len; t++) { - - sum = 0; - for (i = 1; i <= t; i++) { - sum += out_lev[i - 1] * r[i]; - } - - g = (r[t + 1] - sum) / v; - - j = 1; - for (i = t - 1; i >= 0; i--) { - buf_tmp[j] = out_lev[j - 1] - g * out_lev[i]; - j++; - } - - move_float(&out_lev[1], &buf_tmp[1], len); - - out_lev[0] = g; - - v = v * (1 - g * g); - rc_unq[t] = -g; - } - - /* Reorder out_lev */ - out_lev[0] = 1; - j = 1; - for (i = len - 1; i >= 0; i--) { - buf_tmp[j] = -out_lev[i]; - j++; - } - - move_float(&out_lev[1], &buf_tmp[1], (len - 1)); - - out_lev[len] = rc_unq[len - 1]; - - *error = v; -} - -void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len) -{ - LC3_INT32 i, j; - LC3_FLOAT tmp_buf[8], knxt; - LC3_FLOAT norm; - - memset(tmp_buf, 0, 8 * sizeof(LC3_FLOAT)); - /* Initial length = 9 */ - - /* Drop the leading 1 */ - - *len = *len - 1; /* Lenght = 8 */ - - /* Last coefficient */ - knxt = anxt[*len]; /* At [7] */ - - *len = *len - 1; /* Lenght = 7 */ - - j = 0; - for (i = *len - 1; i >= 0; i--) { - tmp_buf[j] = knxt * anxt[i + 1]; - j++; - } - - norm = 1.0 / (1.0 - (LC3_FABS(knxt)) * (LC3_FABS(knxt))); - - out_a[0] = 1; - for (i = 0; i < *len; i++) { - out_a[i + 1] = (anxt[i + 1] - tmp_buf[i]) * norm; - } - - *len = *len + 1; /* Length = 8 */ -} - -void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len) -{ - LC3_INT k, i, len_old; - LC3_FLOAT buf[9]; - - len_old = len; - - zero_float(out, len - 1); - - /* Length = 9 */ - - /* Normalize */ - for (i = 0; i < len; i++) { - a[i] = a[i] / a[0]; - } - - out[len - 1] = a[len - 1]; - - /* Process */ - for (k = len - 2; k >= 0; k--) { - levdown(a, buf, &len); - out[k] = buf[len - 1]; /* Store last value */ - - move_float(a, buf, len); - } - - /* Shift output array by one to the left to lose leading 1 */ - for (i = 0; i < len_old - 1; i++) { - out[i] = out[i + 1]; - } -} - - -void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits, - LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out - , LC3_INT16 near_nyquist_flag -) -{ - LC3_INT i, stopfreq[2], startfreq[2], f, numfilters, maxOrder, bits, sub, - subdiv_startfreq, subdiv_stopfreq, j, rc_idx_tmp[MAXLAG], order_tmp, tmp, tns; - LC3_FLOAT minPGfac, minPredictionGain, maxPG, xcorr_out[MAXLAG + 1], sum, - subdiv_len, nSubdivisions, r[MAXLAG + 1], rc_unq[MAXLAG + 1], error_lev, predGain, - alpha, rc[MAXLAG], st[MAXLAG + 1] = {0}, s, tmpSave, tmp_fl; - const LC3_INT* order; - LC3_FLOAT inv_sum, x_val; - LC3_FLOAT alpha_loc; - LC3_INT32 iIndex; - - /* Init */ - - if (fs >= 32000 && frame_dms >= 50) { - numfilters = 2; - } else { - numfilters = 1; - } - - /* 40 * frame_dms / 10 = 4 * frame_dms */ - if (N > 4 * frame_dms) - { - N = 4 * frame_dms; - fs = 40000; - } - - if (numfilters == 1) { - startfreq[0] = floor(600 * N * 2 / fs) + 1; - stopfreq[0] = N; - } else { - startfreq[0] = floor(600 * N * 2 / fs) + 1; - startfreq[1] = N / 2 + 1; - stopfreq[0] = N / 2; - stopfreq[1] = N; - } - - switch (frame_dms) - { - case 25: - maxOrder = 4; - nSubdivisions = 2.0; - break; - case 50: - maxOrder = 4; - nSubdivisions = 2.0; - break; -#ifdef CR8_G_ADD_75MS - case 75: - maxOrder = 8; - nSubdivisions = 3; - break; -#endif - case 100: - maxOrder = 8; - nSubdivisions = 3.0; - break; - } - - minPredictionGain = 1.5; - - if (nBits >= 4.8 * frame_dms) { - order = order1_tns; - } else { - order = order2_tns; - } - - /* Processing */ - if (bw_cutoff_idx >= 3 && numfilters == 2) { - numfilters = 2; - startfreq[1] = bw_fcbin / 2 + 1; - stopfreq[0] = bw_fcbin / 2; - stopfreq[1] = bw_fcbin; - } else { - numfilters = 1; - stopfreq[0] = bw_fcbin; - } - - bits = 0; - - for (f = 0; f < numfilters; f++) { - subdiv_len = ((LC3_FLOAT)stopfreq[f] + 1.0 - (LC3_FLOAT)startfreq[f]) / nSubdivisions; - - zero_float(r, MAXLAG+1); - - for (sub = 1; sub <= nSubdivisions; sub++) { - subdiv_startfreq = floor(subdiv_len * (sub - 1)) + startfreq[f] - 1; - subdiv_stopfreq = floor(subdiv_len * sub) + startfreq[f] - 1; - -#ifdef CR8_G_ADD_75MS - if (fs == 32000 && frame_dms == 75) - { - if (subdiv_startfreq == 83) - { - subdiv_startfreq = 82; - } - - if (subdiv_stopfreq == 83) - { - subdiv_stopfreq = 82; - } - - if (subdiv_startfreq == 160) - { - subdiv_startfreq = 159; - } - - if (subdiv_stopfreq == 160) - { - subdiv_stopfreq = 159; - } - } -#endif - - sum = 0; - for (i = subdiv_startfreq; i < subdiv_stopfreq; i++) { - sum += x[i] * x[i]; - } - - if (sum < LC3_EPS) { - zero_float(r, MAXLAG+1); - r[0] = 1; - break; - } - - xcorr(&x[subdiv_startfreq], xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq); - - inv_sum = 1.0 / sum; - for (i = 0; i <= maxOrder; i++) { - r[i] = r[i] + xcorr_out[i] * inv_sum; - } - } - - for (i = 0; i <= maxOrder; i++) { - r[i] = r[i] * lagw_tns[i]; - } - - levinsonDurbin(r, xcorr_out, rc_unq, &error_lev, maxOrder); - - predGain = r[0] / error_lev; - - if (predGain > minPredictionGain && near_nyquist_flag == 0) { - tns = 1; - } else { - tns = 0; - } - - bits++; - - if (tns == 1) { - minPGfac = 0.85; - maxPG = 2; - if (nBits >= 4.8 * frame_dms) { - maxPG = minPredictionGain; - } - - /* LPC weighting */ - if (predGain < maxPG) { - alpha = (maxPG - predGain) * (minPGfac - 1.0) / (maxPG - minPredictionGain) + 1.0; - - alpha_loc = 1; - for (i = 0; i <= maxOrder; i++) { - xcorr_out[i] = xcorr_out[i] * alpha_loc; - alpha_loc *= alpha; - } - - poly2rc(xcorr_out, rc_unq, maxOrder + 1); - } - - /* PARCOR Quantization */ - for (i = 0; i < maxOrder; i++) - { - iIndex = 1; - x_val = rc_unq[i]; - - while ((iIndex < 17) && (x_val > quants_thr_tns[iIndex - 1])) - { - iIndex = (iIndex + 1); - } - rc_idx_tmp[i] = (iIndex - 2); - } - - /* Filter Order */ - order_tmp = 0; - for (i = 0; i < maxOrder; i++) { - rc[i] = quants_pts_tns[rc_idx_tmp[i]]; - - if (rc[i] != 0) { - order_tmp = i + 1; - } - } - - order_out[f] = order_tmp; - - // Disable TNS if order is 0: - if (order_out[f] == 0) { - tns = 0; - - // Jump to else statement - goto tns_disabled; - } - tmp = order[order_out[f] - 1]; - - /* Huffman Coding of PARCOR coefficients */ - for (i = 0; i <= order_out[f] - 1; i++) { - tmp += huff_bits_tns[i][rc_idx_tmp[i]]; - } - - bits = bits + ceil((LC3_FLOAT)tmp / 2048.0); - - j = 0; - for (i = f * 8; i <= f * 8 + order_out[f] - 1; i++) { - rc_idx[i] = rc_idx_tmp[j]; - j++; - } - } else { -tns_disabled: - order_out[f] = 0; - } - - /* Filtering */ - if (tns == 1) { - for (i = startfreq[f]; i <= stopfreq[f]; i++) { - s = x[i - 1]; - tmpSave = s; - - for (j = 0; j < order_out[f] - 1; j++) { - tmp_fl = rc[j] * s + st[j]; - s += rc[j] * st[j]; - - st[j] = tmpSave; - tmpSave = tmp_fl; - } - - s += rc[order_out[f] - 1] * st[order_out[f] - 1]; - - st[order_out[f] - 1] = tmpSave; - x[i - 1] = s; - } - } - } - - *tns_numfilters = numfilters; - *bits_out = bits; -} diff --git a/lib_lc3plus/tns_coder_fx.c b/lib_lc3plus/tns_coder_fx.c new file mode 100644 index 000000000..640e246cc --- /dev/null +++ b/lib_lc3plus/tns_coder_fx.c @@ -0,0 +1,378 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +static void Parcor2Index(const Word16 parCoeff[] /*Q15*/, Word16 index[], Word16 order); +static void Index2Parcor(const Word16 index[], Word16 parCoeff[], Word16 order); +static Word32 FIRLattice(Word16 order, const Word16 *parCoeff /*Q15*/, Word32 *state, Word32 x /* Q0 */); + +/*************************************************************************/ + +void processTnsCoder_fx(Word16 *bits, Word16 indexes[], Word32 x[], Word16 BW_cutoff_idx, Word16 order[], + Word16 *numfilters, Word16 enable_lpc_weighting, Word16 nSubdivisions, Word16 frame_dms, + Word16 maxLen, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + , Word16 near_nyquist_flag +) +{ + Dyn_Mem_Deluxe_In(Word16 * tmpbuf; Word32 * rxx, epsP, *state, L_tmp, *A, predictionGain, alpha; Word16 * RC, inv; + Word16 n, n2, headroom, shift, tmp, shifts, facs, facs_e, stopfreq, xLen, maxOrder; + Word16 startfreq[TNS_NUMFILTERS_MAX]; const Word16 *subdiv_startfreq, *subdiv_stopfreq; + Counter i, j, iSubdivisions, lag; Word8 * LevinsonBuffer;); + + /* Buffer alignment */ + tmpbuf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */ + + rxx = (Word32 *)scratchAlign(tmpbuf, sizeof(*tmpbuf) * maxLen); /* Size = 4 * (MAXLAG + 1) = 36 bytes */ + + state = (Word32 *)scratchAlign(rxx, sizeof(*rxx) * (MAXLAG + 1)); /* Size = 4 * MAXLAG = 32 bytes */ + + A = (Word32 *)scratchAlign(state, sizeof(*state) * MAXLAG); /* Size = 4 * (MAXLAG + 1) = 36 bytes */ + + RC = (Word16 *)scratchAlign(A, sizeof(*A) * (MAXLAG + 1)); /* Size = 2 * MAXLAG = 16 bytes */ + + LevinsonBuffer = (Word8 *)scratchAlign(RC, sizeof(*RC) * (MAXLAG)); /* Size = 4 * (M_LTPF + 1) = 100 bytes */ + + /* Init */ + *bits = 0; + move16(); + maxOrder = MAXLAG; + move16(); + *numfilters = 1; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + xLen = BW_cutoff_bin_all_HR[BW_cutoff_idx]; + } + else +#endif + { + xLen = BW_cutoff_bin_all[BW_cutoff_idx]; + } + move16(); + + SWITCH (frame_dms) + { + case 25: + startfreq[0] = 3; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + subdiv_startfreq = tns_subdiv_startfreq_2_5ms_HR[BW_cutoff_idx - 4]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_2_5ms_HR[BW_cutoff_idx - 4]; + move16(); + } + else +#endif + { + subdiv_startfreq = tns_subdiv_startfreq_2_5ms[BW_cutoff_idx]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_2_5ms[BW_cutoff_idx]; + move16(); + } + xLen = shr_pos(xLen, 2); + maxOrder = 4; + move16(); + BREAK; + case 50: + startfreq[0] = 6; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + subdiv_startfreq = tns_subdiv_startfreq_5ms_HR[BW_cutoff_idx - 4]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_5ms_HR[BW_cutoff_idx - 4]; + move16(); + } + else +#endif + { + subdiv_startfreq = tns_subdiv_startfreq_5ms[BW_cutoff_idx]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_5ms[BW_cutoff_idx]; + move16(); + } + xLen = shr_pos(xLen, 1); + maxOrder = 4; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + startfreq[0] = 9; + move16(); + subdiv_startfreq = tns_subdiv_startfreq_7_5ms[BW_cutoff_idx]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_7_5ms[BW_cutoff_idx]; + move16(); + tmp = shr_pos(xLen, 2); + xLen = add(tmp, add(tmp, tmp)); + maxOrder = 8; + BREAK; +#endif + default: /* 100 */ + startfreq[0] = 12; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + subdiv_startfreq = tns_subdiv_startfreq_HR[BW_cutoff_idx - 4]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_HR[BW_cutoff_idx - 4]; + move16(); + } + else +#endif + { + subdiv_startfreq = tns_subdiv_startfreq[BW_cutoff_idx]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq[BW_cutoff_idx]; + move16(); + } + BREAK; + } + + IF (sub(BW_cutoff_idx, 3) >= 0 && frame_dms >= 50) + { + *numfilters = 2; + startfreq[1] = shr_pos(xLen, 1); + } + + basop_memset(state, 0, MAXLAG * sizeof(*state)); + + FOR (j = 0; j < *numfilters; j++) + { + basop_memset(rxx, 0, (maxOrder + 1) * sizeof(*rxx)); + + FOR (iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++) + { + n = sub(subdiv_stopfreq[nSubdivisions * j + iSubdivisions], + subdiv_startfreq[nSubdivisions * j + iSubdivisions]); + + /*norms[iFilter][iSubdivisions] = norm2FLOAT(pSpectrum+iStartLine, iEndLine-iStartLine);*/ + headroom = getScaleFactor32_lc3plus(x + subdiv_startfreq[nSubdivisions * j + iSubdivisions], n); + + /* Calculate norm of spectrum band */ + L_tmp = Norm32Norm(x + subdiv_startfreq[nSubdivisions * j + iSubdivisions], headroom, n, &shift); + + /* Rounding to avoid overflow when computing the autocorrelation below */ + tmp = sub(norm_l(L_tmp), 1); + L_tmp = L_shl(L_tmp, tmp); + shift = sub(shift, tmp); + L_tmp = L_add(L_tmp, 0x8000); + L_tmp = L_and(L_tmp, 0x7FFF0000); + + IF (L_tmp == 0) + { + rxx[0] = 0x7FFFFFFF; + move32(); + basop_memset(&rxx[1], 0, (maxOrder) * sizeof(*rxx)); + BREAK; + } + + /* get pre-shift for autocorrelation */ + tmp = sub(shift, norm_l(L_tmp)); /* exponent for normalized L_tmp */ + tmp = shr_pos(sub(1, tmp), 1); /* pre-shift to apply before autocorrelation */ + shifts = s_min(tmp, headroom); + + /* calc normalization factor */ + facs_e = shl_pos(sub(tmp, shifts), 1); + + SWITCH (frame_dms) + { + case 25: facs_e = add(facs_e, 1); BREAK; + case 50: facs_e = add(facs_e, 1); BREAK; +#ifdef CR8_G_ADD_75MS + case 75: BREAK; +#endif + case 100: BREAK; + } + + tmp = sub(1, shl_pos(tmp, 1)); /* exponent of autocorrelation */ + L_tmp = L_shl(L_tmp, sub(shift, tmp)); /* shift L_tmp to that exponent */ + /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ + facs = div_s(0x2000, round_fx(L_tmp)); /* L_tmp is >= 0x2000000 */ + + FOR (i = 0; i < n; i++) + { + tmpbuf[i] = round_fx_sat(L_shl_sat(x[subdiv_startfreq[nSubdivisions * j + iSubdivisions] + i], shifts)); + move16(); + } + + FOR (lag = 0; lag <= maxOrder; lag++) + { + n2 = sub(n, lag); + L_tmp = L_deposit_l(0); + FOR (i = 0; i < n2; i++) + { + L_tmp = L_mac0(L_tmp, tmpbuf[i], tmpbuf[i + lag]); + } + if (lag != 0) + L_tmp = Mpy_32_32_lc3plus(L_tmp, tnsAcfWindow_lc3plus[lag - 1]); + + L_tmp = Mpy_32_16_lc3plus(L_tmp, facs); + L_tmp = L_shl(L_tmp, facs_e); + + rxx[lag] = L_add(rxx[lag], L_tmp); + move32(); + } + } + + /* Levinson-Durbin */ + processLevinson_fx(A, rxx, maxOrder, RC, &epsP, LevinsonBuffer); + + /* Prediction Gain */ + shift = norm_l(epsP); + inv = div_s(16383, extract_h(L_shl_pos(epsP, shift))); + predictionGain = Mpy_32_32_lc3plus(rxx[0], Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(L_shl(epsP, shift), inv)), inv)); + + IF (L_sub(predictionGain, L_shr_pos_pos(0x30000000, shift)) > 0 && near_nyquist_flag == 0) + { + /* If Prediction Gain is low */ + test(); + IF (enable_lpc_weighting != 0 && L_sub(predictionGain, L_shr_pos_pos(0x40000000, shift)) < 0) + { + /* LPC weighting */ + alpha = L_add(0x6CCCCCCD, + Mpy_32_32_lc3plus(0x13333333, L_shl_pos(L_sub(L_shl_pos(predictionGain, shift), 0x30000000), 3))); + L_tmp = alpha; + FOR (i = 1; i < maxOrder; i++) + { + A[i] = Mpy_32_32_lc3plus(A[i], L_tmp); + move32(); + L_tmp = Mpy_32_32_lc3plus(L_tmp, alpha); + } + A[maxOrder] = Mpy_32_32_lc3plus(A[maxOrder], L_tmp); + move32(); + + /* LPC -> RC */ + lpc2rc(A, RC, maxOrder); + } + + /* Reflection Coefficients Quantization */ + Parcor2Index(RC, &indexes[MAXLAG * j], maxOrder); + + /* reduce filter order by truncating trailing zeros */ + i = sub(maxOrder, 1); + WHILE ((i >= 0) && (indexes[MAXLAG * j + i] == INDEX_SHIFT)) + { + i = sub(i, 1); + } + order[j] = add(i, 1); + + // Disable TNS if order is 0: + IF (order[j] == 0) { + // Jump to else statement + goto tns_disabled; + } + /* Count bits */ + L_tmp = L_deposit_l(ac_tns_order_bits[enable_lpc_weighting][order[j] - 1]); + FOR (i = 0; i < order[j]; i++) + { + L_tmp = L_add(L_tmp, L_deposit_l(ac_tns_coef_bits[i][indexes[MAXLAG * j + i]])); + } + *bits = add(*bits, add(2, extract_l(L_shr_pos(L_sub(L_tmp, 1), 11)))); + move16(); + + /* Unquantize Reflection Coefficients */ + Index2Parcor(&indexes[MAXLAG * j], RC, order[j]); + + /* Stop frequency */ + stopfreq = xLen; + move16(); + IF (sub(*numfilters, 2) == 0 && j == 0) + { + stopfreq = startfreq[1]; + } + + /* Filter */ + FOR (i = startfreq[j]; i < stopfreq; i++) + { + x[i] = FIRLattice(order[j], RC, state, x[i]); + move32(); + } + } + ELSE + { +tns_disabled: + /* TNS disabled */ + *bits = add(*bits, 1); + order[j] = 0; + } + } + + Dyn_Mem_Deluxe_Out(); +} + +/*************************************************************************/ + +static void Parcor2Index(const Word16 parCoeff[] /*Q15*/, Word16 index[], Word16 order) +{ + Dyn_Mem_Deluxe_In(Counter i; Word16 iIndex; Word16 x;); + + FOR (i = 0; i < order; i++) + { + move16(); + move16(); + iIndex = 1; + x = parCoeff[i]; + + WHILE ((iIndex < TNS_COEF_RES) && (x > tnsQuantThr[iIndex - 1])) + { + iIndex = add(iIndex, 1); + } + index[i] = sub(iIndex, 1); + move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +static void Index2Parcor(const Word16 index[], Word16 parCoeff[], Word16 order) +{ + Counter i; + FOR (i = 0; i < order; i++) + { + parCoeff[i] = tnsQuantPts[index[i]]; + move16(); + } +} + +static Word32 FIRLattice(Word16 order, const Word16 *parCoeff /*Q15*/, Word32 *state, Word32 x /* Q0 */) +{ + Dyn_Mem_Deluxe_In(Counter i; Word32 tmpSave, tmp;); + + tmpSave = L_add(x, 0); + + FOR (i = 0; i < order - 1; i++) + { + tmp = L_add(state[i], Mpy_32_16_lc3plus(x, parCoeff[i])); + x = L_add(x, Mpy_32_16_lc3plus(state[i], parCoeff[i])); /* exponent: 31+0 */ + state[i] = tmpSave; + move32(); + tmpSave = L_add(tmp, 0); + } + + /* last stage: only need half operations */ + x = L_add(x, Mpy_32_16_lc3plus(state[order - 1], parCoeff[order - 1])); + state[order - 1] = tmpSave; + move32(); + Dyn_Mem_Deluxe_Out(); + return x; +} + diff --git a/lib_lc3plus/tns_decoder.c b/lib_lc3plus/tns_decoder.c deleted file mode 100644 index dbdadaeaf..000000000 --- a/lib_lc3plus/tns_decoder.c +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#include "options.h" -#include "wmc_auto.h" -#include "functions.h" - -void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs) -{ - LC3_INT startfreq[2], stopfreq[2], f, i, j, m, l; - LC3_FLOAT rc[9], s, st[9] = {0}; - LC3_INT order_tmp; - - if (numfilters == 2) { - startfreq[0] = floor(600 * N * 2 / fs) + 1; - stopfreq[0] = bw_fcbin / 2; - startfreq[1] = bw_fcbin / 2 + 1; - stopfreq[1] = bw_fcbin; - } else { - startfreq[0] = floor(600 * N * 2 / fs) + 1; - stopfreq[0] = bw_fcbin; - } - - for (f = 0; f < numfilters; f++) { - order_tmp = order[f]; - - if (order_tmp > 0) { - j = 0; - - for (i = f * 8; i < f * 8 + order_tmp; i++) { - rc[j] = quants_pts_tns[rc_idx[i]]; - j++; - } - - for (m = startfreq[f]; m <= stopfreq[f]; m++) { - s = x[m - 1] - rc[order_tmp - 1] * st[order_tmp - 1]; - - for (l = order_tmp - 2; l >= 0; l--) { - s = s - rc[l] * st[l]; - st[l + 1] = rc[l] * s + st[l]; - } - - st[0] = s; - x[m - 1] = s; - } - } - } -} diff --git a/lib_lc3plus/tns_decoder_fx.c b/lib_lc3plus/tns_decoder_fx.c new file mode 100644 index 000000000..b138c4510 --- /dev/null +++ b/lib_lc3plus/tns_decoder_fx.c @@ -0,0 +1,150 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" + +static Word32 IIRLattice(Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x); + +/*************************************************************************/ + +void processTnsDecoder_fx(Word16 rc_idx[], Word32 x[], Word16 xLen, Word16 order[], Word16 *x_e, Word16 BW_stopband_idx, + Word16 frame_dms, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + Dyn_Mem_Deluxe_In( + Word32 *state; + Counter i, j; + Word16 s1, s2, s, *rc, f, stopfreq, BW_stopband; + Word16 numfilters, startfreq[TNS_NUMFILTERS_MAX]; + ); + + state = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = MAXLAG */ + rc = (Word16 *)scratchAlign(state, sizeof(*state) * MAXLAG); /* Size = MAXLAG */ + + numfilters = 1; + +#ifdef ENABLE_HR_MODE + if (hrmode == 1) + { + BW_stopband = BW_cutoff_bin_all_HR[BW_stopband_idx]; move16(); + } + else +#endif + { + BW_stopband = BW_cutoff_bin_all[BW_stopband_idx]; move16(); + } + + SWITCH (frame_dms) + { + case 25: + startfreq[0] = 3; move16(); + BW_stopband = shr_pos(BW_stopband, 2); + BREAK; + case 50: + startfreq[0] = 6; move16(); + BW_stopband = shr_pos(BW_stopband, 1); + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + startfreq[0] = 9; move16(); + BW_stopband = add(shr_pos(BW_stopband, 2), add(shr_pos(BW_stopband, 2), shr_pos(BW_stopband, 2))); + BREAK; +#endif + case 100: startfreq[0] = 12; BREAK; + } + + IF (sub(BW_stopband_idx, 3) >= 0 && frame_dms >= 50) + { + numfilters = 2; + startfreq[1] = shr_pos(BW_stopband, 1); + } + stopfreq = 0; + + test(); test(); + IF (order[0] > 0 || (sub(numfilters, 2) == 0 && order[1] > 0)) + { + /* Scaling */ + f = startfreq[0]; move16(); + test(); + IF (sub(numfilters, 2) == 0 && order[0] == 0) + { + f = startfreq[1]; move16(); + } + s1 = getScaleFactor32_lc3plus(x, f); + s2 = getScaleFactor32_lc3plus(x + f, sub(xLen, f)); + s = s_min(s1, sub(s2, 7)); /* 7 bits of headroom for IIR filtering */ + *x_e = sub(*x_e, s); + +/* Init Filter */ + basop_memset(state, 0, MAXLAG * sizeof(Word32)); + FOR (i = 0; i < f; i++) + { + x[i] = L_shl(x[i], s); move32(); + } + + FOR (j = 0; j < numfilters; j++) + { + IF (order[j] > 0) + { + /* Unquantize coefficients */ + FOR (i = 0; i < order[j]; i++) + { + rc[i] = tnsQuantPts[rc_idx[j * MAXLAG + i]]; move16(); + } + + /* Stop frequency */ + stopfreq = BW_stopband; move16(); + IF (sub(numfilters, 2) == 0 && j == 0) + { + stopfreq = startfreq[1]; + } + + /* Filter */ + FOR (i = startfreq[j]; i < stopfreq; i++) + { + x[i] = IIRLattice(order[j], rc, state, L_shl(x[i], s)); move32(); + } + } + } + FOR (i = stopfreq; i < xLen; i++) + { + x[i] = L_shl(x[i], s); move32(); + } + } + Dyn_Mem_Deluxe_Out(); +} + +/*************************************************************************/ +/*************************************************************************/ +/*************************************************************************/ + +static Word32 IIRLattice(Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + /* first stage: no need to calculate state[order-1] */ + x = L_sub_sat(x, Mpy_32_16_lc3plus(state[order - 1], parCoeff[order - 1])); + + FOR (i = order - 2; i >= 0; i--) + { + x = L_sub(x, Mpy_32_16_lc3plus(state[i], parCoeff[i])); + state[i + 1] = L_add(state[i], Mpy_32_16_lc3plus(x, parCoeff[i])); move32(); + } + + state[0] = x; move32(); + + Dyn_Mem_Deluxe_Out(); + return x; +} + diff --git a/lib_lc3plus/util.h b/lib_lc3plus/util.h deleted file mode 100644 index 069e89371..000000000 --- a/lib_lc3plus/util.h +++ /dev/null @@ -1,256 +0,0 @@ -/****************************************************************************** -* ETSI TS 103 634 V1.4.3 * -* Low Complexity Communication Codec Plus (LC3plus) * -* * -* Copyright licence is solely granted through ETSI Intellectual Property * -* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -* estoppel or otherwise. * -******************************************************************************/ - - -#ifndef UTIL_H -#define UTIL_H - -#include "options.h" -#include "wmc_auto.h" -#include "clib.h" -#include "math.h" - -#ifdef _MSC_VER -/* strcasecmp is not available on visual studio */ -static LC3_INT strcasecmp(const char* a, const char* b) { - return _stricmp(a,b); -} -#endif - -/* restrict is not available on visual studio */ -#ifdef _MSC_VER -#define restrict __restrict -/* inline is not recognized in visual studio 13 required by matlab r2015a in win10 */ -#define inline __inline -#endif - -/* number of elements in array */ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -/* min max with no side effects */ -static inline LC3_INT imin(LC3_INT a, LC3_INT b) { return a < b ? a : b; } -static inline LC3_INT imax(LC3_INT a, LC3_INT b) { return a > b ? a : b; } - -/* restrict x to range [min, max] */ -static inline LC3_INT iclamp(LC3_INT min, LC3_INT x, LC3_INT max) { - return x < min ? min : x > max ? max : x; -} -static inline double fcmamp(double min, double x, double max) { - return x < min ? min : x > max ? max : x; -} -static inline LC3_FLOAT fclampf(LC3_FLOAT min, LC3_FLOAT x, LC3_FLOAT max) { - return x < min ? min : x > max ? max : x; -} - -/* x² */ -static inline LC3_FLOAT sqrf(LC3_FLOAT x) { return x * x; } - -/* convenience wrappers around memmove */ -static inline void move_float(LC3_FLOAT *dst, const LC3_FLOAT *src, LC3_INT len) { -#ifdef WMOPS - LC3_INT i; - for (i = 0; i < len; i++) - { - dst[i] = src[i]; - } -#else - memmove(dst, src, len * sizeof(LC3_FLOAT)); -#endif -} -static inline void move_int(LC3_INT *dst, const LC3_INT *src, LC3_INT len) { -#ifdef WMOPS - LC3_INT i; - for (i = 0; i < len; i++) - { - dst[i] = src[i]; - } -#else - memmove(dst, src, len * sizeof(LC3_INT)); -#endif -} - -/* convenience wrappers around memset */ -static inline void zero_float(LC3_FLOAT *x, LC3_INT len) { -#ifdef WMOPS - LC3_INT i; - for (i = 0; i < len; i++) - { - x[i] = 0; - } -#else - memset(x, 0, len * sizeof(LC3_FLOAT)); -#endif -} -static inline void zero_int(LC3_INT *x, LC3_INT len) { -#ifdef WMOPS - LC3_INT i; - for (i = 0; i < len; i++) - { - x[i] = 0; - } -#else - memset(x, 0, len * sizeof(LC3_INT)); -#endif -} - -/* multiply float vectors element by element, in-place */ -static inline void mult_vec(LC3_FLOAT *a, const LC3_FLOAT *b, - LC3_INT len) { - LC3_INT i = 0; - for (i = 0; i < len; i++) { - a[i] *= b[i]; - } -} - -/* multiply float vector with constant, in-place */ -static inline void mult_const(LC3_FLOAT *a, LC3_FLOAT b, LC3_INT len) { - LC3_INT i = 0; - for (i = 0; i < len; i++) { - a[i] *= b; - } -} - -/* sum of vector */ -static inline LC3_FLOAT sum_vec(const LC3_FLOAT *x, LC3_INT len) { - LC3_FLOAT sum = 0; - LC3_INT i = 0; - for (i = 0; i < len; i++) { - sum += x[i]; - } - return sum; -} - -/* complex constructor */ -static inline Complex cmplx(LC3_FLOAT r, LC3_FLOAT i) { return (Complex){r, i}; } - -/* complex a + b */ -static inline Complex cadd(Complex a, Complex b) { - return cmplx(a.r + b.r, a.i + b.i); -} - -/* complex a * b */ -static inline Complex cmul(Complex a, Complex b) { - return cmplx(a.r * b.r - a.i * b.i, a.i * b.r + a.r * b.i); -} - -/* mac operator */ -static inline LC3_FLOAT mac_loop(const LC3_FLOAT *array1, const LC3_FLOAT *array2, LC3_INT len) -{ - LC3_INT i; - LC3_FLOAT sum = 0.0; - - for (i = 0; i < len; i++) - { - sum += (*array1++) * (*array2++); - } - - return sum; -} - -/* complex eᶦˣ */ -static inline Complex cexpi(LC3_FLOAT x) { return cmplx(LC3_COS(x), LC3_SIN(x)); } - -/* complex -x */ -static inline Complex cneg(Complex x) { return cmplx(-x.r, -x.i); } - -/* convert string to number. return true on success */ -static inline bool str_to_int(const char *str, LC3_INT *value) { - char *end = NULL; - long v = str ? strtol(str, &end, 0) : 0; - *value = (LC3_INT)v; - return str && *end == 0 && v >= INT_MIN && v <= INT_MAX; -} - -/* returns true if str ends with str ends with suffix. ignoring case. str may be - * NULL */ -static inline bool str_ends_with(const char *str, const char *suffix) { - char *tmp = str ? strrchr(str, suffix[0]) : NULL; - return tmp && !strcasecmp(tmp, suffix); -} - -/* complex a - b */ -static inline Complex csub(Complex a, Complex b) { - return cmplx(a.r - b.r, a.i - b.i); -} - -static inline void move_cmplx(Complex *dst, const Complex *src, LC3_INT32 len) { - if (len > 0) { - memmove(dst, src, len * sizeof(Complex)); - assert(src[len - 1].r == dst[len - 1].r && src[len - 1].i == dst[len - 1].i); /*check that Cmplx is stored contiguously*/ - assert(src[0].r == dst[0].r && src[0].i == dst[0].i); /*check that Cmplx is stored contiguously*/ - } -} - -static inline void zero_cmplx(Complex *x, LC3_INT32 len) { - if(len > 0) { - memset(x, 0, len * sizeof(Complex)); - assert(x[0].r == 0 && x[0].i == 0 && x[len-1].r == 0 && x[len-1].i == 0); - } -} - -static inline Complex realtoc(LC3_FLOAT r) { return cmplx(r, 0); } - -/* set float vector to constant */ -static inline void set_vec(const LC3_FLOAT c, LC3_FLOAT *x, LC3_INT32 len) { - LC3_INT32 i = 0; - for (i = 0; i < len; i++) { - x[i] = c; - } -} - -/* set float vector to constant */ -static inline void set_vec_int(const LC3_INT32 c, LC3_INT32 *x, LC3_INT32 len) { - LC3_INT32 i = 0; - for (i = 0; i < len; i++) { - x[i] = c; - } -} - -static inline LC3_INT32 clz_func(LC3_INT32 inp) -{ -#if defined(__clang__) || defined(__GNUC__) - if (inp == 0) - { - return 0; - } - return __builtin_clz(inp); - -#elif defined(_WIN32) || defined(_WIN64) - LC3_INT32 leading_zero = 0; - - if (_BitScanReverse(&leading_zero, inp)) - { - return 31 - leading_zero; - } - else - return 0; - -#else - LC3_INT32 i = 0; - int64_t x = inp; - - if (inp == 0) - { - return 0; - } - - inp = (inp < 0) ? ~inp : inp; - - while (x < (int64_t)0x80000000L) - { - inp <<= 1; - i += 1; - } - - return i; -#endif -} - - -#endif diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index a8dd46e57..f7667cc69 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -713,6 +713,7 @@ typedef struct ivas_combined_orientation_struct IVAS_QUATERNION Quaternions_ext_interpolation_start; IVAS_QUATERNION Quaternions_ext_interpolation_target; float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; + Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; #ifdef SPLIT_REND_WITH_HEAD_ROT float Rmat_prev[MAX_HEAD_ROT_POSES][3][3]; #else @@ -1433,6 +1434,12 @@ typedef struct float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; + + Word32 Cldfb_Prev_BinReal_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_Prev_BinImag_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + Word16 Q_Prev_Bin_fx; + Word32 xf_bet_fx[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; + } CLDFB_PLC, *CLDFB_PLC_HANDLE; typedef struct @@ -1473,10 +1480,14 @@ typedef struct int16_t max_num_channels; int16_t num_channels; float **channel_ptrs; + Word32 **channel_ptrs_fx; int32_t sampling_rate; float gain; + Word32 gain_fx; float release_heuristic; + Word32 release_heuristic_fx; float attack_constant; + Word32 attack_constant_fx; int16_t strong_saturation_count; #ifdef DEBUGGING int32_t cnt_frames_limited; /* counter of frames in which the limiter is applied */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 663e3c602..2dbc5e8aa 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -45,6 +45,7 @@ #include #include #include "wmc_auto.h" +#include "prot_fx2.h" /*-------------------------------------------------------------------* @@ -4472,6 +4473,10 @@ ivas_error IVAS_REND_SetHeadRotation( { return error; } + hIvasRend->headRotData.headPositions[sf_idx].w_fx = floatToFixed( hIvasRend->headRotData.headPositions[sf_idx].w, Q22 ); + hIvasRend->headRotData.headPositions[sf_idx].x_fx = floatToFixed( hIvasRend->headRotData.headPositions[sf_idx].x, Q22 ); + hIvasRend->headRotData.headPositions[sf_idx].y_fx = floatToFixed( hIvasRend->headRotData.headPositions[sf_idx].y, Q22 ); + hIvasRend->headRotData.headPositions[sf_idx].z_fx = floatToFixed( hIvasRend->headRotData.headPositions[sf_idx].z, Q22 ); hIvasRend->headRotData.Pos[sf_idx] = Pos; @@ -7557,7 +7562,16 @@ static ivas_error getSamplesInternal( int16_t num_poses_orig; num_poses_orig = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; outAudio = hIvasRend->splitRendEncBuffer; + Word16 i, q_factor = Q22; + ISAR_PRE_REND_GetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); + + FOR( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + hIvasRend->splitRendWrapper.multiBinPoseData.relative_head_poses[i][0] = fixedToFloat( hIvasRend->splitRendWrapper.multiBinPoseData.relative_head_poses_fx[i][0], q_factor ); + hIvasRend->splitRendWrapper.multiBinPoseData.relative_head_poses[i][1] = fixedToFloat( hIvasRend->splitRendWrapper.multiBinPoseData.relative_head_poses_fx[i][1], q_factor ); + hIvasRend->splitRendWrapper.multiBinPoseData.relative_head_poses[i][2] = fixedToFloat( hIvasRend->splitRendWrapper.multiBinPoseData.relative_head_poses_fx[i][2], q_factor ); + } assert( num_poses_orig == hIvasRend->splitRendWrapper.multiBinPoseData.num_poses && "number of poses should not change dynamically" ); /* Clear output buffer for split rendering bitstream */ @@ -7600,6 +7614,17 @@ static ivas_error getSamplesInternal( int16_t cldfb_in_flag; float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + for ( int i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + for ( int j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + for ( int k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + Cldfb_RealBuffer_Binaural[i][j][k] = 0; + Cldfb_ImagBuffer_Binaural[i][j][k] = 0; + } + } + } int16_t ch; int16_t i, ro_md_flag; float *tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS], tmpBinaural_buff[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; @@ -7632,27 +7657,117 @@ static ivas_error getSamplesInternal( break; } } + Word16 j; + Word16 q, q1 = 31, q2 = 31, Q_buff; + Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 *pOutput_fx[CLDFB_NO_COL_MAX]; + Word32 output_fx[CLDFB_NO_COL_MAX][L_FRAME48k]; + Word16 Q_out[CLDFB_NO_COL_MAX]; + Q_out[0] = 31; + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + pOutput_fx[i] = &( output_fx[i][0] ); + } + Word16 num_poses = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; + for ( i = 0; i < 16; i++ ) + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + q = Q_factor_arrL( Cldfb_RealBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX ); + q1 = s_min( q1, q ); + q = Q_factor_arrL( Cldfb_ImagBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX ); + q2 = s_min( q2, q ); + } + } + Q_buff = s_min( q1, q2 ); + for ( i = 0; i < 16; i++ ) + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + floatToFixed_arrL( Cldfb_RealBuffer_Binaural[i][j], Cldfb_RealBuffer_Binaural_fx[i][j], Q_buff, CLDFB_NO_CHANNELS_MAX ); + floatToFixed_arrL( Cldfb_ImagBuffer_Binaural[i][j], Cldfb_ImagBuffer_Binaural_fx[i][j], Q_buff, CLDFB_NO_CHANNELS_MAX ); + } + } + IF( EQ_16( cldfb_in_flag, 0 ) ) + { + /*TD input*/ + /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ + /* local float2fix, to be removed */ + num_poses = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; + if ( hIvasRend->splitRendWrapper.hLc3plusEnc != NULL ) + { + Word16 frame_size_lc3 = (Word16) ( ( hIvasRend->splitRendWrapper.hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND ) + hIvasRend->splitRendWrapper.lc3plusDelaySamples ); + + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + Q_out[0] = s_min( Q_out[0], Q_factor_arrL( hIvasRend->splitRendWrapper.lc3plusDelayBuffers[i], frame_size_lc3 ) ); + } + } + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + Q_out[0] = s_min( Q_out[0], Q_factor_arrL( tmpBinaural[i], L_FRAME48k ) ); + } + // printf("%d\n", Q_sig); + if ( hIvasRend->splitRendWrapper.hLc3plusEnc != NULL ) + { + Word16 frame_size_lc3 = (Word16) ( ( hIvasRend->splitRendWrapper.hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND ) + hIvasRend->splitRendWrapper.lc3plusDelaySamples ); - if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, - hIvasRend->headRotData.headPositions[0], - hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, - hIvasRend->hRendererConfig->split_rend_config.codec, + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + floatToFixed_arrL( hIvasRend->splitRendWrapper.lc3plusDelayBuffers[i], hIvasRend->splitRendWrapper.lc3plusDelayBuffers_fx[i], Q_out[0], frame_size_lc3 ); + } + } + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + floatToFixed_arrL( tmpBinaural[i], pOutput_fx[i], Q_out[0], L_FRAME48k ); + } + } + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, #ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms, #endif hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, - &bits, - Cldfb_RealBuffer_Binaural, - Cldfb_ImagBuffer_Binaural, - ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), - tmpBinaural, - 1, - cldfb_in_flag, - ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, - ro_md_flag ) ) != IVAS_ERR_OK ) + &bits, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), tmpBinaural, pOutput_fx, 1, cldfb_in_flag, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, ro_md_flag, Q_buff, &Q_out[0] ) ) != IVAS_ERR_OK ) { return error; } + IF( EQ_16( cldfb_in_flag, 0 ) ) + { + if ( hIvasRend->splitRendWrapper.hLc3plusEnc != NULL ) + { + Word16 frame_size_lc3 = (Word16) ( ( hIvasRend->splitRendWrapper.hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND ) + hIvasRend->splitRendWrapper.lc3plusDelaySamples ); + +#ifdef DUMP_LC3_DELAY_OUT + FILE *fp = fopen( "ref_lc3delay.txt", "ab" ); +#endif + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + fixedToFloat_arrL( hIvasRend->splitRendWrapper.lc3plusDelayBuffers_fx[i], hIvasRend->splitRendWrapper.lc3plusDelayBuffers[i], Q_out[0], frame_size_lc3 ); +#ifdef DUMP_LC3_DELAY_OUT + for ( Word16 j = 0; j < frame_size_lc3; j++ ) + { + fprintf( fp, "%f\n", hSplitBin->lc3plusDelayBuffers[i][j] ); + } +#endif + } +#ifdef DUMP_LC3_DELAY_OUT + fclose( fp ); +#endif + } + } + + Word16 pcm_out_flag = ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + IF( NE_16( pcm_out_flag, 0 ) && ( NE_16( cldfb_in_flag, 0 ) ) ) + { + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + fixedToFloat_arrL( pOutput_fx[ch], tmpBinaural[ch], Q_out[ch], hIvasRend->splitRendWrapper.hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX ); + + fixedToFloat_arrL( hIvasRend->splitRendWrapper.hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hIvasRend->splitRendWrapper.hCldfbHandles->cldfbSyn[ch]->cldfb_state, hIvasRend->splitRendWrapper.hCldfbHandles->cldfbSyn[ch]->Q_split, hIvasRend->splitRendWrapper.hCldfbHandles->cldfbSyn[ch]->p_filter_length ); + } + } + convertInternalBitsBuffToBitsBuffer( hBits, bits ); diff --git a/lib_util/rotation_file_reader.c b/lib_util/rotation_file_reader.c index 19721f49b..748063fad 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -91,7 +91,47 @@ ivas_error RotationFileReader_open( * * Read values from the trajectory file *-----------------------------------------------------------------------*/ +ivas_error HeadRotationFileReading_fx( + RotFileReader *headRotReader, /* i/o: HeadRotFileReader handle */ + IVAS_QUATERNION *pQuaternion, /* o : head-tracking data */ + IVAS_VECTOR3 *pPos /* o : listener position */ +) +{ + float w, x, y, z; + float posx, posy, posz; + int32_t read_values; + + posx = 0; + posy = 0; + posz = 0; + read_values = fscanf( headRotReader->trajFile, "%f,%f,%f,%f,%f,%f,%f", &w, &x, &y, &z, &posx, &posy, &posz ); + IF( ( read_values != 4 ) && ( read_values != 7 ) ) /* Allow either orientation (4) or orientation+position (4+3) */ + { + IF( feof( headRotReader->trajFile ) ) + { + rewind( headRotReader->trajFile ); + headRotReader->fileRewind = true; + return HeadRotationFileReading_fx( headRotReader, pQuaternion, pPos ); + } + return IVAS_ERR_FAILED_FILE_PARSE; + } + + ( headRotReader->frameCounter )++; + + pQuaternion->w_fx = (Word32) ( w * ONE_IN_Q22 ); + pQuaternion->x_fx = (Word32) ( x * ONE_IN_Q22 ); + pQuaternion->y_fx = (Word32) ( y * ONE_IN_Q22 ); + pQuaternion->z_fx = (Word32) ( z * ONE_IN_Q22 ); + IF( pPos != NULL ) + { + pPos->x_fx = (Word32) ( posx * ONE_IN_Q22 ); + pPos->y_fx = (Word32) ( posy * ONE_IN_Q22 ); + pPos->z_fx = (Word32) ( posz * ONE_IN_Q22 ); + } + + return IVAS_ERR_OK; +} ivas_error HeadRotationFileReading( RotFileReader *headRotReader, /* i/o: HeadRotFileReader handle */ IVAS_QUATERNION *pQuaternion, /* o : head-tracking data */ diff --git a/lib_util/rotation_file_reader.h b/lib_util/rotation_file_reader.h index 1ae772fce..a11f72099 100644 --- a/lib_util/rotation_file_reader.h +++ b/lib_util/rotation_file_reader.h @@ -55,6 +55,11 @@ ivas_error RotationFileReader_open( * Read values from the trajectory file *-----------------------------------------------------------------------*/ +ivas_error HeadRotationFileReading_fx( + RotFileReader *headRotReader, /* i/o: HeadRotFileReader handle */ + IVAS_QUATERNION *pQuaternion, /* o : head-tracking data */ + IVAS_VECTOR3 *pPos /* o : listener position */ +); ivas_error HeadRotationFileReading( RotFileReader *headRotReader, /* i/o: RotFileReader handle */ IVAS_QUATERNION *pQuaternion, /* o : head-tracking data */ -- GitLab